#ios #delegates #subview
#iOS #делегаты #подпросмотр
Вопрос:
Я уже некоторое время задавался вопросом, как лучше всего это сделать…
В настоящее время, чтобы получить подвидение подвида UIViewController для отправки сообщения UIViewController, я попрошу подвидение второго уровня связаться с родительским подвидом с помощью делегата, а затем настроить другого делегата для подвида первого уровня для связи с UIViewController.
Если у меня есть только подвиды, которые общаются со своими родителями, я полагаю, я мог бы просто создать свойство для родительского элемента в дочернем элементе, установить для него значение weak и отправлять сообщения таким образом.
Есть ли другой, лучший способ сделать это?
Комментарии:
1. Не могли бы вы подробнее рассказать о том, что представление должно передавать контроллеру представления? Более подробная информация внесла бы больше ясности в то, каким должно быть соответствующее решение. 🙂
2. В частности, дело обычно во встроенной кнопке, но я хочу, чтобы контроллер выполнил действие.
Ответ №1:
Почему бы не создать кодовое соединение? Просто нажмите кнопку в раскадровке и перетащите ее в свой контроллер просмотра?
Тогда это должно выглядеть примерно так:
- (IBAction)goToVC3:(id)sender {
// whatever you wanna do when button is pressed
}
Есть также опция ручного управления. Допустим, вы хотите что-то сделать с кнопкой, которую вы только что создали и добавили в свой вид. Ну, просто добавьте это:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.button addTarget:self
action:@selector(doSomething)
forControlEvents:UIControlEventTouchUpInside];
}
- (void)doSomething
{
// whatever you want
}
Комментарии:
1. Я попробую это! Это звучит именно так, как я хочу. Просто вместо self.button это было бы что-то вроде self.subview.subview.button?
2. Да, конечно. Где бы он ни находился, это будет работать до тех пор, пока вы можете получить ссылку на него.
3. @RyJ Если мой ответ сделал то, что вы хотите, пожалуйста, примите его. В противном случае, дайте мне знать.
Ответ №2:
Есть несколько способов сделать это, но идеальным способом в вашем примере является использование цепочки ответчиков.
Я не буду вдаваться в подробное объяснение здесь, потому что связанная статья объясняет все это в великолепных деталях, но главное — отделить действие вашей кнопки от кода, который для нее выполняется. Вы могли бы, как вы предлагаете, использовать делегирование, но что, если вы вставите другое представление в иерархию? Теперь вам нужно распространить делегирование через «другое» представление, что означает другое представление, содержащее детали реализации для передачи события. Фу.
С помощью цепочки ответчиков система будет обходить цепочку объектов, которые имеют право отвечать, пока не найдет объект, который реализует желаемое поведение. Это именно то, что мы хотим! Затем действие вашей кнопки должно вызывать код примерно так:
[[UIApplication sharedApplication] sendAction:@selector(doFoo:)
to:nil
from:nil
forEvent:nil];
Комментарии:
1. И тогда тот, кто ответит на doFoo: (в цепочке ответчиков), выполнит действие?
2. @RyJ Да, но, насколько я могу судить из статьи, это больше относится к OSX. Я говорю это, потому что не думаю, что вам нужно прибегать к этому варианту. Это немного небезопасно и немного эзотерично, потому что, как вы сказали, тот, кто ответит на это первым, выполнит это.
3. @doctordoder Не совсем. Цепочка ответчиков жива и исправна на iOS. Его корни находятся в меню файлов OS X, но наиболее распространенной практикой использования цепочки ответчиков на iOS является
UITextField
отключение клавиатуры.4. @doctordoder Да. В приведенном выше примере вы бы заменили
doFoo:
наresignFirstResponder
.5. @WayneHartman Я всегда просто делал
[self.view endEditing:YES];
, что должен использовать цепочку ответчиков.