Я отправил свое приложение чуть более недели назад и получил страшное письмо с отказом сегодня. Это говорит мне, что мое приложение не может быть принято, потому что я использую непубличный API; в частности, это говорит,
Непубличный API, включенный в ваше приложение, это firstResponder.
Теперь вызов API-интерфейса на самом деле является решением, которое я нашел здесь на SO:
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
UIView *firstResponder = [keyWindow performSelector:@selector(firstResponder)];
Как вывести текущего первого респондента на экран? Я ищу способ, которым мое приложение не будет отклонено.
objective-c
cocoa-touch
first-responder
Джастин Кредибл
источник
источник
Ответы:
В одном из моих приложений я часто хочу, чтобы первый респондент подал в отставку, если пользователь нажимает на фон. Для этого я написал в UIView категорию, которую я вызываю в UIWindow.
Следующее основано на этом и должно вернуть первого респондента.
iOS 7+
Swift:
Пример использования в Swift:
источник
[self.view endEditing:YES]
?Если вашей конечной целью является просто подать в отставку первого респондента, это должно работать:
[self.view endEditing:YES]
источник
Распространенным способом манипулирования первым респондентом является использование целевых действий с нулевым значением. Это способ отправки произвольного сообщения в цепочку респондента (начиная с первого респондента) и продолжения вниз по цепочке, пока кто-то не ответит на сообщение (не реализовал метод, соответствующий селектору).
В случае отклонения клавиатуры это наиболее эффективный способ, который будет работать независимо от того, какое окно или представление является первым респондентом:
Это должно быть более эффективным, чем даже
[self.view.window endEditing:YES]
.(Спасибо BigZaphod за напоминание о концепции)
источник
Вот категория, которая позволяет быстро найти первого респондента по телефону
[UIResponder currentFirstResponder]
. Просто добавьте следующие два файла в ваш проект:UIResponder + FirstResponder.h
UIResponder + FirstResponder.m
Хитрость в том, что отправка действия на nil отправляет его первому респонденту.
(Я первоначально опубликовал этот ответ здесь: https://stackoverflow.com/a/14135456/322427 )
источник
Вот расширение, реализованное в Swift на основе самого превосходного ответа Якоба Эггера:
Swift 4
источник
current
вместоfirst
?Это не красиво, но то, как я оставляю firstResponder, когда я не знаю, что это за ответчик:
Создайте UITextField, либо в IB, либо программно. Сделать это скрытым Свяжите это с вашим кодом, если вы сделали это в IB.
Затем, когда вы хотите отклонить клавиатуру, вы переключаете респондент в невидимое текстовое поле и немедленно отмените его:
источник
Для Swift 3 и 4 версии ответа Невина :
источник
Вот решение, которое сообщает о правильном первом респонденте (например, многие другие решения не будут сообщать
UIViewController
о первом респонденте), не требует зацикливания в иерархии представления и не использует частные API.Он использует метод Apple sendAction: to: from: forEvent:, который уже знает, как получить доступ к первому респонденту.
Нам просто нужно настроить его двумя способами:
UIResponder
чтобы он мог выполнить наш собственный код на первом респонденте.UIEvent
для того, чтобы вернуть первого респондента.Вот код:
источник
Первым респондентом может быть любой экземпляр класса UIResponder, поэтому существуют другие классы, которые могут быть первым респондентом, несмотря на UIViews. Например,
UIViewController
также может быть первым респондентом.В этом разделе вы найдете рекурсивный способ получения первого респондента, просматривая иерархию контроллеров, начиная с rootViewController окон приложения.
Вы можете получить первого респондента, выполнив
Однако, если первый респондент не является подклассом UIView или UIViewController, этот подход потерпит неудачу.
Чтобы решить эту проблему, мы можем использовать другой подход, создав категорию
UIResponder
и выполнив некоторое волшебство, чтобы иметь возможность собрать массив всех живых экземпляров этого класса. Затем, чтобы получить первого респондента, мы можем просто повторить и спросить каждый объект, если-isFirstResponder
.Этот подход может быть найден реализованным в этой другой сути .
Надеюсь, поможет.
источник
Используя Swift и с конкретным
UIView
объектом, это может помочь:Просто поместите его в свой
UIViewController
и используйте его так:Обратите внимание, что результатом является необязательное значение, поэтому оно будет равно нулю, если firstResponser не был найден в данных подпредставлениях представлений.
источник
Переберите представления, которые могут быть первым респондентом, и используйте,
- (BOOL)isFirstResponder
чтобы определить, являются ли они в данный момент.источник
Питер Штейнбергер только что написал в Твиттере о личном уведомлении
UIWindowFirstResponderDidChangeNotification
, которое вы можете наблюдать, если хотите увидеть изменение первого респондера.источник
Если вам просто нужно убить клавиатуру, когда пользователь нажимает на фоновую область, почему бы не добавить распознаватель жестов и использовать его для отправки
[[self view] endEditing:YES]
сообщения?вы можете добавить распознаватель жестов касания в файл xib или раскадровки и подключить его к действию,
выглядит примерно так потом закончил
источник
В данном случае Swift-версия удивительного подхода Якоба Эггера:
источник
Это то, что я сделал, чтобы узнать, что UITextField является firstResponder, когда пользователь нажимает Сохранить / Отмена в ModalViewController:
источник
Это то, что у меня есть в моей категории UIViewController. Полезно для многих вещей, в том числе получения первого респондента. Блоки отличные!
источник
При включенной категории
UIResponder
можно по закону попроситьUIApplication
объект сообщить вам, кто является первым респондентом.Посмотри это:
Есть ли способ спросить у iOS, кто из ее детей имеет статус первого респондента?
источник
Вы можете выбрать следующее
UIView
расширение, чтобы получить его (кредит от Daniel) :источник
Вы также можете попробовать вот так:
Я не пробовал, но это кажется хорошим решением
источник
Решение от romeo https://stackoverflow.com/a/2799675/661022 - это круто, но я заметил, что коду нужен еще один цикл. Я работал с tableViewController. Я отредактировал скрипт и затем проверил. Все работало отлично.
Я рекомендовал попробовать это:
источник
if ([textField isKindOfClass:[UITextField class]])
, разрешив использование для uitextview, и могли бы вернуть первого респондента.Это хороший кандидат на рекурсию! Нет необходимости добавлять категорию в UIView.
Использование (с вашей точки зрения контроллера):
Код:
источник
Вы можете назвать приватный API, как это, яблоко игнорировать:
источник
Быстрая версия ответа @ thomas-müller
источник
У меня немного другой подход, чем у большинства здесь. Вместо того, чтобы перебирать коллекцию представлений в поисках того, который был
isFirstResponder
установлен, я тоже отправляю сообщениеnil
, но сохраняю получателя (если есть), затем возвращаю это значение, чтобы вызывающий получил фактический экземпляр (снова, если есть) ,Затем я могу уйти в отставку первого ответчика, если таковые имеются, сделав это ...
Но теперь я тоже могу это сделать ...
источник
Я хотел бы поделиться с вами моей реализацией для поиска первого респондента в любом месте UIView. Я надеюсь, что это помогает и извините за мой английский. Спасибо
источник
Код ниже работы.
источник
Обновление: я был неправ. Вы действительно можете использовать
UIApplication.shared.sendAction(_:to:from:for:)
для вызова первого респондента, показанного по этой ссылке: http://stackoverflow.com/a/14135456/746890 .Большинство ответов здесь не могут найти текущего первого респондента, если он не находится в иерархии представлений. Например,
AppDelegate
илиUIViewController
подклассы.Существует способ гарантировать его нахождение, даже если первый объект респондента не является
UIView
.Сначала давайте реализуем его обратную версию, используя
next
свойствоUIResponder
:С помощью этого вычисленного свойства мы можем найти текущего первого респондента снизу вверх, даже если это не так
UIView
. Например, от оператораview
к тому,UIViewController
кто им управляет, если контроллер представления является первым респондентом.Однако нам все еще нужно разрешение сверху вниз, единственное,
var
чтобы получить текущий первый респондент.Сначала с иерархией представления:
Он будет искать первого респондента в обратном направлении, и если он не сможет его найти, он скажет своим подпредставлениям сделать то же самое (потому что его подпредставление
next
не обязательно само по себе). При этом мы можем найти его с любой точки зрения, в том числеUIWindow
.И, наконец, мы можем построить это:
Поэтому, когда вы хотите получить первого респондента, вы можете позвонить:
источник
Самый простой способ найти первого респондента:
Следующий шаг:
Использование: Просто получите
UIResponder.actualFirst
для своих собственных целей.источник