Воспроизведение поведения делегата tableView в настраиваемом представлении

Я пытаюсь разработать элемент управления, имитирующий поведение элемента управления UITableView. Я определил протокол делегата следующим образом:

@protocol HPSChoiceDelegate

- (void)choiceView:(HPSChoice *)choiceView didSelectChoice:(NSNumber*)selectedIndex;

@end

Пользователь может коснуться подвидов в главном окне управления. У меня есть распознаватели TapGesture, которые запускают методы в основном представлении управления. Я подключаю их так:

UITapGestureRecognizer *containerTap = 
        [[UITapGestureRecognizer alloc] initWithTarget:self
                                                action:@selector(didSelectChoice:)];

Затем у меня есть метод в представлении, который пытается вызвать правильный метод в делегате. Метод в представлении выглядит так:

-(void)didSelectChoice:(UITapGestureRecognizer*)sender
{
    NSNumber* selectedIndex = [NSNumber numberWithInt:sender.view.tag];

    [(id)self.delegate performSelector:@selector(didSelectChoice:) withObject:selectedIndex afterDelay:0.0f];
}

В контроллере делегата определен следующий метод:

- (void)choiceView:(HPSChoice *)choiceView didSelectChoice:(NSNumber*)selectedChoice
{
    NSLog(@"HPSFormController didSelectChoice:(HPSChoice*)choiceView tag = %@",[[choiceView class] description]);
}

Все это компилируется, и когда я нажимаю на элемент управления, в представлении вызывается didSelectChoice, который затем вызывает метод в делегате. Однако метод делегата аварийно завершает работу со следующей ошибкой:

-[HPSFormController didSelectChoice:]: unrecognized selector sent to instance 0x29b4e0

Как я могу это исправить? Большое спасибо.


person whatdoesitallmean    schedule 07.09.2012    source источник
comment
Просто примечание: у вас не гарантируется наличие делегата, а также то, что он отвечает селектору, если он не отмечен как обязательный. Итак, сделайте это: if (delegate && [delegate respondsToSelector:@selector(foo:)]) { [delegate performSelector:@selector(foo:) withObject:bar]; ]   -  person Cyrille    schedule 07.09.2012


Ответы (3)


Метод не работает, потому что вы звоните

didSelectChoice:

в то время как метод, который вы определили,

choiceView:didSelectChoice:

Я считаю, что это можно исправить, позвонив:

[(id)self.delegate performSelector:@selector(choiceView:didSelectChoice:) withObject:choiceView withObject:selectedIndex];

Конечно, вам нужно будет получить selectionView в методе didSelectChoice :.

person Darren    schedule 07.09.2012

Если ваше представление, например, называется HPSChoiceView, вам также необходимо указать, что его делегат - это контроллер, на котором вы создаете это представление.

Например, где-то в контроллере делегата (полагаю, HPSFormController) вам нужно сделать:

HPSChoiceView* choiceView = // alloc-init here
// self refers to an instance of HPSFormController at run-time
choiceView.delegate = self;

Это означает, что каждый раз, когда вы касаетесь этого представления, контроллер будет реагировать на это касание, поскольку он был установлен в качестве его делегата.

Вдобавок вы вызываете неправильный селектор. Вместо звонка

[self.delegate performSelector:@selector(didSelectChoice:) withObject:selectedIndex afterDelay:0.0f];

вызов

[self.delegate performSelector:@selector(choiceView:didSelectChoice:) withObject:choiceView withObject:selectedIndex];

choiceView можно получить из sender.view. sender - это istance UITapGestureRecognizer, и по этой причине вы можете получить вид, который был нажат.

Чтобы понять, что такое селектор, вы можете увидеть Селекторы в цели C и Apple doc.

Сказал, что я бы также изменил селектор для вас, делегата HPSChoiceDelegate. Так, например, я бы назвал это (для ясности):

- (void)didSelectChoiceView:(HPSChoice *)choiceView withSelectedIndex:(NSNumber*)selectedIndex;

Если вы используете это, селектор будет didSelectChoiceView:withSelectedIndex:. Обратите внимание на двоеточия !!

Кроме того, я бы добавил элемент управления перед вызовом метода делегата, как тот, который предлагается @Cirylle. Этот элемент управления позволяет вам проверить, настроили ли вы делегата (первая часть моего ответа), и делегат может ответить на этот селектор, поскольку он был реализован правильно.

Надеюсь, это поможет.

person Lorenzo B    schedule 07.09.2012
comment
Большое спасибо - не знаю, какова процедура, когда два человека так услужливо отвечают, извиняюсь за то, что не наградили вас правильным ответом - person whatdoesitallmean; 07.09.2012
comment
@whatdoesitallmean Нет проблем. Если хотите, можете проголосовать за мой ответ. Ваше здоровье. - person Lorenzo B; 07.09.2012

Класс, который должен действовать как делегат, должен объявить и соответствовать протоколу HPSChoiceDelegate, а также должен зарегистрироваться как делегат вашего UITableView'ish класса.

Также попробуйте перейти на @selector(choiceView:didSelectChoice:).

person Ricky Helgesson    schedule 07.09.2012