Таблица действий наложения клавиатуры в iOS 13.1 на CNContactViewController
12
Похоже, это характерно для iOS 13.1, так как в iOS 13.0 и более ранних версиях он работает, как и ожидалось, для добавления контакта в CNContactViewController. Если я «Отмена», лист действий перекрывается клавиатурой. Никакие действия не выполняются и клавиатура не сбрасывает со счетов.
Слава @GxocT за отличный обходной путь! Очень помогли мои пользователи.
Но я хотел поделиться своим кодом на основе решения @GxocT, надеясь, что он поможет другим в этом сценарии.
Мне нужно было, CNContactViewControllerDelegatecontactViewController(_:didCompleteWith:)чтобы меня вызвали при отмене (а также сделали).
Также мой код не был в UIViewControllerтак что нетself.navigationController
Я также не люблю использовать распаковки с применением силы, когда могу помочь. Я был укушен в прошлом, поэтому я приковал if lets в настройке
В моем случае в функции swizzle просто вызовите CNContactViewControllerDelegateделегата contactViewController(_:didCompleteWith:)с помощью selfи self.contactобъекта из контроллера контактов
В коде установки убедитесь, что вызов swizzleMethod
class_getInstanceMethodуказывает CNContactViewController
класс вместоself
И код 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)}}
Клавиатура по-прежнему отображается на мгновение, но падает сразу после закрытия контроллера контактов.
Будем надеяться, что яблоко исправит это
Принудительное развертывание используется, чтобы сделать код компактным, конечно, вы должны избегать их, если это возможно, и если это может привести к сбою. Кстати, я не уверен, правильно ли передавать self.contact делегату, потому что он, вероятно, не создан, если вы отменяете поток ps: изменил мою реализацию, чтобы избежать принудительного развертывания: D
GxocT
@GxocT - согласился на насильственные действия. И они не всегда ужасны, но другие не такие, как вы, и могут всегда использовать их, не осознавая риска;). Мне нравится, если пусть вместо! когда я не на 100% уверен, что это не будет ноль. Что касается self.contact - это правда. Я не знаю, какой код lib Apple обычно передает делегату внутренне, но self.contact имел контактные данные, а документ CNContactViewController говорит, что это «отображаемый контакт», поэтому его можно было использовать нормально. Мой код на самом деле не использует контакт, переданный в делегате завершения, поэтому я мог просто передать nil в расширении.
Баррет
Содержимое (включая текстовые представления и клавиатуры) в CNContactViewController должно находиться в отдельном процессе. Если вы можете использовать 'View Hierarchy' в Xcode для этого контроллера представления, вы можете обнаружить, что содержимое не видно. В результате мы не можем контролировать ни клавиатуру, ни текстовое представление.
WildCat
5
Я не мог найти способ отклонить клавиатуру. Но, по крайней мере, вы можете открыть ViewController, используя мой метод.
Не знаю почему, но нельзя отклонить клавиатуру в CNContactViewController. Я попытался endEditing:, сделать новый UITextField firstResponder и так далее. Ничего не получалось.
Я пытался изменить действие для кнопки «Отмена». Вы можете найти эту кнопку в стеке NavigationController, но ее действие меняется каждый раз, когда вы что-то печатаете.
Наконец-то я использовал метод Swizzling. Я не мог найти способ отклонить клавиатуру, как я упоминал ранее, но по крайней мере вы можете отклонить CNContactViewController, когда нажата кнопка «Отмена».
Пользователь может провести пальцем вниз, чтобы закрыть клавиатуру, а затем нажать «Отмена» и просмотреть лист действий. Таким образом, эта проблема вызывает сожаление и определенно является ошибкой (и я подал отчет об ошибке), но не является фатальной (хотя, безусловно, обходной путь для пользователя не тривиален).
Спасибо @Gxoct за его отличную работу. Я думаю, что это очень полезный вопрос и пост для тех, кто работает с CNContactViewController. У меня также была эта проблема (до сих пор), но в цели c. Я интерпретирую приведенный выше код Swift в цель 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);}}
Создание CNContactViewControllerкатегории для доступа к увольнению;
Я не мог найти способ отклонить клавиатуру. Но, по крайней мере, вы можете открыть ViewController, используя мой метод.
PS: Вы можете найти дополнительную информацию по теме reddit: https://www.reddit.com/r/swift/comments/dc9n3a/bug_with_cnviewcontroller_ios_131/
источник
Пользователь может провести пальцем вниз, чтобы закрыть клавиатуру, а затем нажать «Отмена» и просмотреть лист действий. Таким образом, эта проблема вызывает сожаление и определенно является ошибкой (и я подал отчет об ошибке), но не является фатальной (хотя, безусловно, обходной путь для пользователя не тривиален).
источник
Исправлено в iOS 13.4 Протестировано в Xcode Simulator
источник
Спасибо @Gxoct за его отличную работу. Я думаю, что это очень полезный вопрос и пост для тех, кто работает с
CNContactViewController
. У меня также была эта проблема (до сих пор), но в цели c. Я интерпретирую приведенный выше код Swift в цель c.Создание
CNContactViewController
категории для доступа к увольнению;Ребята, которые не очень знакомы с Swizzling, вы можете попробовать этот пост по мат
источник
Спасибо, @GxocT за ваш обходной путь, однако решение, размещенное здесь, отличается от того, которое вы разместили на Reddit.
Тот, что на Reddit, работает для меня, а этот нет, поэтому я хочу опубликовать его здесь. Разница на линии с swizzledMethod, который должен быть:
Весь обновленный код:
источник