Aktionsblatt zur Tastaturüberlagerung in iOS 13.1 auf CNContactViewController
12
Dies scheint spezifisch für iOS 13.1 zu sein, da es unter iOS 13.0 und früheren Versionen wie erwartet funktioniert, um einen Kontakt in CNContactViewController hinzuzufügen. Wenn ich auf "Abbrechen" klicke, überlappt sich das Aktionsblatt mit der Tastatur. Es werden keine Aktionen ausgeführt und die Tastatur wird nicht geschlossen.
Ein großes Lob an @GxocT für die großartige Problemumgehung! Hat meinen Nutzern sehr geholfen.
Aber ich wollte meinen Code basierend auf der @ GxocT-Lösung teilen, in der Hoffnung, dass er anderen in diesem Szenario hilft.
Ich musste CNContactViewControllerDelegatecontactViewController(_:didCompleteWith:)beim Abbrechen angerufen werden (und auch erledigt).
Auch mein Code war nicht in einem UIViewControllerso gibt es keinself.navigationController
Ich mag es auch nicht, Gewalt auszuwickeln, wenn ich helfen kann. Ich wurde in der Vergangenheit gebissen, also habe ich if lets im Setup angekettet
Folgendes habe ich getan:
Erweitern CNContactViewControllerund platzieren Sie die Swizzle-Funktion
dort.
In meinem Fall in der Swizzle-Funktion rufen Sie einfach den CNContactViewControllerDelegateDelegaten contactViewController(_:didCompleteWith:)mit selfund self.contactObjekt vom Kontakt-Controller auf
Stellen Sie im Setup-Code sicher, dass der Aufruf von swizzleMethod
class_getInstanceMethoddie CNContactViewController
Klasse anstelle von angibtself
Und der Swift-Code:
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)}}
Die Tastatur wird weiterhin kurz angezeigt, fällt jedoch unmittelbar nach dem Schließen des Kontakt-Controllers ab.
Hoffen wir, dass Apple das behebt
Force Unwraps werden verwendet, um Code zu kompaktieren. Natürlich sollten Sie sie nach Möglichkeit vermeiden und wenn dies zum Absturz führen kann. Übrigens bin ich mir nicht sicher, ob es richtig ist, self.contact an delegate zu übergeben, da es wahrscheinlich nicht erstellt wird, wenn Sie flow ps abbrechen: Meine Implementierung wurde geändert, um Force-Unwraps zu vermeiden: D
GxocT
@GxocT - vereinbart auf die Kraft urwraps. Und sie sind nicht immer schrecklich, aber andere sind nicht wie Sie und können sie immer benutzen, ohne das Risiko zu erkennen;). Ich mag wenn statt lassen! wenn ich nicht 100% sicher bin, wird es nicht Null sein. Über den self.contact - es ist wahr Ich weiß nicht, was der lib-Code von Apple normalerweise intern an den Delegaten weitergibt, aber self.contact hatte die Kontaktdaten und das CNContactViewController-Dokument sagt, es sei "der angezeigte Kontakt", daher schien es in Ordnung zu sein, ihn zu verwenden. Mein Code verwendet nicht den Kontakt, der im Abschlussdelegierten übergeben wurde, sodass ich in der Erweiterung einfach Null übergeben konnte.
Barrett
Der Inhalt (einschließlich Textansichten und Tastaturen) in CNContactViewController sollte sich in einem separaten Prozess befinden. Wenn Sie in Xcode für diesen Ansichtscontroller die Ansichtshierarchie verwenden können, wird der Inhalt möglicherweise nicht angezeigt. Daher können wir weder die Tastatur noch die Textansicht steuern.
WildCat
5
Ich konnte keinen Weg finden, die Tastatur zu schließen. Aber zumindest können Sie ViewController mit meiner Methode öffnen.
Ich weiß nicht warum, aber es ist unmöglich, die Tastatur in CNContactViewController zu schließen. Ich habe versucht, endEditing:, neue UITextField firstResponder und so weiter zu machen. Nichts hat geklappt.
Ich habe versucht, die Aktion für die Schaltfläche "Abbrechen" zu ändern. Sie finden diese Schaltfläche im NavigationController-Stapel. Die Aktion wird jedoch jedes Mal geändert, wenn Sie etwas eingeben.
Schließlich habe ich Methode Swizzling verwendet. Ich konnte keine Möglichkeit finden, die Tastatur zu schließen, wie ich bereits erwähnt habe, aber zumindest können Sie CNContactViewController schließen, wenn die Schaltfläche "Abbrechen" gedrückt wird.
Der Benutzer kann tatsächlich nach unten wischen, um die Tastatur zu schließen, und dann auf Abbrechen tippen, um das Aktionsblatt anzuzeigen. Daher ist dieses Problem bedauerlich und definitiv ein Fehler (und ich habe einen Fehlerbericht eingereicht), aber nicht schwerwiegend (obwohl die Problemumgehung für den Benutzer nicht trivial ist).
Vielen Dank an @Gxoct für seine hervorragende Arbeit. Ich denke, dies ist eine sehr nützliche Frage und Post für diejenigen, die mit arbeiten CNContactViewController. Ich hatte auch dieses Problem (bis jetzt), aber in Ziel c. Ich interpretiere den obigen Swift-Code in Ziel 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);}}
Erstellen einer CNContactViewControllerKategorie für den Zugriff auf Entlassung;
Vielen Dank, @GxocT, für Ihre Problemumgehung. Die hier veröffentlichte Lösung unterscheidet sich jedoch von der auf Reddit veröffentlichten.
Der auf Reddit funktioniert für mich, dieser nicht, also möchte ich ihn hier erneut veröffentlichen. Der Unterschied liegt in der Zeile mit swizzledMethod, die sein sollte:
let swizzledMethod = class_getInstanceMethod(object_getClass(self), swizzledSelector){
Der gesamte aktualisierte Code lautet:
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)}}
Ich konnte keinen Weg finden, die Tastatur zu schließen. Aber zumindest können Sie ViewController mit meiner Methode öffnen.
PS: Weitere Informationen zum Thema reddit finden Sie unter: https://www.reddit.com/r/swift/comments/dc9n3a/bug_with_cnviewcontroller_ios_131/
quelle
Der Benutzer kann tatsächlich nach unten wischen, um die Tastatur zu schließen, und dann auf Abbrechen tippen, um das Aktionsblatt anzuzeigen. Daher ist dieses Problem bedauerlich und definitiv ein Fehler (und ich habe einen Fehlerbericht eingereicht), aber nicht schwerwiegend (obwohl die Problemumgehung für den Benutzer nicht trivial ist).
quelle
In iOS 13.4 behoben. In Xcode Simulator getestet
quelle
Vielen Dank an @Gxoct für seine hervorragende Arbeit. Ich denke, dies ist eine sehr nützliche Frage und Post für diejenigen, die mit arbeiten
CNContactViewController
. Ich hatte auch dieses Problem (bis jetzt), aber in Ziel c. Ich interpretiere den obigen Swift-Code in Ziel c.Erstellen einer
CNContactViewController
Kategorie für den Zugriff auf Entlassung;Leute, die Swizzling nicht so gut kennen, können diesen Beitrag von matt ausprobieren
quelle
Vielen Dank, @GxocT, für Ihre Problemumgehung. Die hier veröffentlichte Lösung unterscheidet sich jedoch von der auf Reddit veröffentlichten.
Der auf Reddit funktioniert für mich, dieser nicht, also möchte ich ihn hier erneut veröffentlichen. Der Unterschied liegt in der Zeile mit swizzledMethod, die sein sollte:
Der gesamte aktualisierte Code lautet:
quelle