Lembar tindakan overlay keyboard di iOS 13.1 di CNContactViewController
12
Ini tampaknya khusus untuk iOS 13.1, karena berfungsi seperti yang diharapkan pada iOS 13.0 dan versi sebelumnya untuk menambahkan kontak di CNContactViewController, jika saya 'Batal', lembar tindakan tumpang tindih dengan keyboard. Tidak ada tindakan yang dilakukan dan keyboard tidak menolak.
Kudos to @GxocT untuk solusi hebatnya! Sangat membantu pengguna saya.
Tapi saya ingin membagikan kode saya berdasarkan solusi @GxocT dengan harapan itu akan membantu orang lain dalam skenario ini.
Saya perlu saya CNContactViewControllerDelegatecontactViewController(_:didCompleteWith:)dipanggil batal (dan juga dilakukan).
Juga kode saya tidak dalam UIViewControllersehingga tidak adaself.navigationController
Saya juga tidak suka menggunakan kekuatan membuka ketika saya bisa membantu. Saya telah digigit di masa lalu jadi saya dirantai if letdi setup
Inilah yang saya lakukan:
Perpanjang CNContactViewControllerdan letakkan fungsi swizzle di
sana.
Dalam kasus saya dalam fungsi swizzle panggil saja CNContactViewControllerDelegatedelegasi contactViewController(_:didCompleteWith:)dengan selfdan self.contactobjek dari pengontrol kontak
Dalam kode pengaturan, pastikan panggilan swizzleMethod untuk
class_getInstanceMethodmenentukan CNContactViewController
kelas, bukanself
Dan kode Swift:
classMyClass:CNContactViewControllerDelegate{overridefunc viewDidLoad(){super.viewDidLoad()self.changeImplementation()}func changeCancelImplementation(){let originalSelector =Selector(("editCancel:"))let swizzledSelector =#selector(CNContactViewController.cancelHack)iflet originalMethod = class_getInstanceMethod(object_getClass(CNContactViewController()), originalSelector),let swizzledMethod = class_getInstanceMethod(object_getClass(CNContactViewController()), swizzledSelector){
method_exchangeImplementations(originalMethod, swizzledMethod)}}func contactViewController(_ viewController:CNContactViewController, didCompleteWith contact:CNContact?){// dismiss the contacts controller as usual viewController.dismiss(animated:true, completion:nil)// do other stuff when your contact is canceled or saved...}}extensionCNContactViewController{@objc func cancelHack(){self.delegate?.contactViewController?(self, didCompleteWith:self.contact)}}
Keyboard masih muncul sesaat tetapi turun tepat setelah pengontrol Kontak ditolak.
Mari berharap apel memperbaikinya
buka paksa digunakan untuk membuat kode kompak tentu saja Anda harus menghindarinya jika mungkin dan jika itu dapat menyebabkan crash. btw saya tidak yakin apakah itu benar untuk lulus self.contact untuk mendelegasikan, karena itu mungkin tidak dibuat jika Anda membatalkan aliran ps: mengubah implementasi saya untuk menghindari membuka paksa: D
GxocT
@GxocT - menyetujui kekuatan urwraps. Dan mereka tidak selalu mengerikan tetapi orang lain tidak seperti Anda dan mungkin selalu menggunakannya tanpa menyadari risikonya;). Saya suka jika biarkan saja! ketika saya tidak 100% yakin itu tidak akan menjadi nol. Tentang self.contact - sejatinya saya tidak tahu kode lib Apple yang biasanya dikirimkan ke delegasi secara internal tetapi self.contact memiliki data kontak dan dokumen CNContactViewController mengatakan ini adalah "kontak yang ditampilkan" sehingga sepertinya tidak masalah untuk digunakan. Kode saya tidak benar-benar menggunakan kontak yang diteruskan dalam delegasi penyelesaian jadi saya hanya bisa meneruskan nol di ekstensi.
Barrett
Konten (termasuk tampilan teks dan keyboard) di CNContactViewController harus dalam proses terpisah. Jika Anda dapat menggunakan 'Lihat Hierarki' di Xcode untuk pengontrol tampilan ini, Anda mungkin menemukan konten tidak dapat dilihat. Akibatnya, kami tidak dapat mengontrol keyboard atau tampilan teks.
WildCat
5
Saya tidak dapat menemukan cara untuk mengabaikan keyboard. Tapi setidaknya Anda bisa memunculkan ViewController menggunakan metode saya.
Tidak tahu mengapa tetapi tidak mungkin untuk mengabaikan keyboard di CNContactViewController. Saya mencoba endEditing :, buat UITextField baru firstResponder dan sebagainya. Tidak ada yang berhasil.
Saya mencoba mengubah tindakan untuk tombol "Batal". Anda dapat menemukan tombol ini di tumpukan NavigationController, Tapi tindakannya berubah setiap kali Anda mengetik sesuatu.
Akhirnya saya menggunakan metode swizzling. Saya tidak dapat menemukan cara untuk mengabaikan keyboard seperti yang saya sebutkan sebelumnya, tetapi setidaknya Anda dapat mengabaikan CNContactViewController ketika tombol "Cancel" ditekan.
Pengguna sebenarnya dapat menggesek ke bawah untuk mengabaikan keyboard dan kemudian ketuk Batalkan dan lihat lembar tindakan. Jadi masalah ini disesalkan dan jelas merupakan bug (dan saya telah mengajukan laporan bug) tetapi tidak berakibat fatal (meskipun, untuk memastikan, solusi tidak sepele bagi pengguna untuk menemukan).
Terima kasih @Gxoct untuk pekerjaannya yang luar biasa. Saya pikir ini adalah pertanyaan & posting yang sangat berguna bagi mereka yang bekerja dengannya CNContactViewController. Saya juga punya masalah ini (sampai sekarang) tetapi dalam tujuan c. Saya mengartikan kode Swift di atas menjadi objektif c.
-(void)viewDidLoad {[super viewDidLoad];Classclass=[CNContactViewControllerclass];
SEL originalSelector =@selector(editCancel:);
SEL swizzledSelector =@selector(dismiss);// we will gonna access this method & redirect the delegate via this method
Method originalMethod = class_getInstanceMethod(class, originalSelector);Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
BOOL didAddMethod =
class_addMethod(class,
originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));if(didAddMethod){
class_replaceMethod(class,
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));}else{
method_exchangeImplementations(originalMethod, swizzledMethod);}}
Membuat CNContactViewControllerkategori untuk mengakses pemberhentian;
Terima kasih, @GxocT atas solusi Anda, namun, solusi yang diposting di sini berbeda dari yang Anda posting di Reddit.
Yang ada di Reddit bekerja untuk saya, yang ini tidak jadi saya ingin memposting ulang di sini. Perbedaannya ada pada baris dengan metode swizzled yang seharusnya:
let swizzledMethod = class_getInstanceMethod(object_getClass(self), swizzledSelector){
Seluruh kode yang diperbarui adalah:
classMyClass:CNContactViewControllerDelegate{overridefunc viewDidLoad(){super.viewDidLoad()self.changeImplementation()}func changeCancelImplementation(){let originalSelector =Selector(("editCancel:"))let swizzledSelector =#selector(CNContactViewController.cancelHack)iflet originalMethod = class_getInstanceMethod(object_getClass(CNContactViewController()), originalSelector),let swizzledMethod = class_getInstanceMethod(object_getClass(self), swizzledSelector){
method_exchangeImplementations(originalMethod, swizzledMethod)}}func contactViewController(_ viewController:CNContactViewController, didCompleteWith contact:CNContact?){// dismiss the contacts controller as usual
viewController.dismiss(animated:true, completion:nil)// do other stuff when your contact is canceled or saved
...}}extensionCNContactViewController{@objc func cancelHack(){self.delegate?.contactViewController?(self, didCompleteWith:self.contact)}}
Saya tidak dapat menemukan cara untuk mengabaikan keyboard. Tapi setidaknya Anda bisa memunculkan ViewController menggunakan metode saya.
PS: Anda dapat menemukan info tambahan tentang topik reddit: https://www.reddit.com/r/swift/comments/dc9n3a/bug_with_cnviewcontroller_ios_131/
sumber
Pengguna sebenarnya dapat menggesek ke bawah untuk mengabaikan keyboard dan kemudian ketuk Batalkan dan lihat lembar tindakan. Jadi masalah ini disesalkan dan jelas merupakan bug (dan saya telah mengajukan laporan bug) tetapi tidak berakibat fatal (meskipun, untuk memastikan, solusi tidak sepele bagi pengguna untuk menemukan).
sumber
Diperbaiki di iOS 13.4 Diuji dalam Xcode Simulator
sumber
Terima kasih @Gxoct untuk pekerjaannya yang luar biasa. Saya pikir ini adalah pertanyaan & posting yang sangat berguna bagi mereka yang bekerja dengannya
CNContactViewController
. Saya juga punya masalah ini (sampai sekarang) tetapi dalam tujuan c. Saya mengartikan kode Swift di atas menjadi objektif c.Membuat
CNContactViewController
kategori untuk mengakses pemberhentian;Orang-orang yang tidak begitu terbiasa dengan Swizzling, Anda dapat mencoba posting ini oleh matt
sumber
Terima kasih, @GxocT atas solusi Anda, namun, solusi yang diposting di sini berbeda dari yang Anda posting di Reddit.
Yang ada di Reddit bekerja untuk saya, yang ini tidak jadi saya ingin memposting ulang di sini. Perbedaannya ada pada baris dengan metode swizzled yang seharusnya:
Seluruh kode yang diperbarui adalah:
sumber