【问题标题】:Reproduce tableView delegate behaviour in a custom view在自定义视图中重现 tableView 委托行为
【发布时间】:2012-09-07 12:34:03
【问题描述】:

我正在尝试开发一个模仿 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

我该如何解决这个问题?非常感谢。

【问题讨论】:

  • 请注意:不能保证你有一个委托,如果它没有被标记为强制,它也不能回答选择器。所以,这样做:if (delegate && [delegate respondsToSelector:@selector(foo:)]) { [delegate performSelector:@selector(foo:) withObject:bar]; ]

标签: objective-c ios delegates performselector uitableview


【解决方案1】:

方法崩溃是因为你在调用

didSelectChoice:

而你定义的方法是

choiceView:didSelectChoice:

我相信你可以通过调用来解决这个问题:

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

当然,您必须在 didSelectChoice: 方法中获取choiceView。

【讨论】:

    【解决方案2】:

    例如,如果您的视图名为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 检索。 senderUITapGestureRecognizer 的一个实例,因此您可以检索被点击的视图。

    要了解什么是选择器,您可以查看 Selectors in Objective CApple doc

    这么说,我也会为你委托HPSChoiceDelegate更改选择器。因此,例如,我会称之为(只是为了清楚起见):

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

    如果你使用它,选择器将是didSelectChoiceView:withSelectedIndex:。注意冒号!!

    此外,我会在调用委托方法之前添加一个控件,正如@Cirylle 所建议的那样。该控件允许您验证您是否设置了委托(我的答案的第一部分),并且委托可以响应该选择器,因为它已正确实现。

    希望对您有所帮助。

    【讨论】:

    • 非常感谢 - 不知道两个人回答如此有帮助时的程序是什么,很抱歉没有给你正确的答案
    • @whatdoesitallmean 没问题。如果你愿意,你可以投票给我的答案。干杯。
    【解决方案3】:

    应该充当委托的类必须声明并遵守HPSChoiceDelegate 协议,并且它还必须将自己注册为您的UITableView'ish 类的委托。

    另外,请尝试更改为@selector(choiceView:didSelectChoice:)

    【讨论】:

      猜你喜欢
      • 2012-06-03
      • 2016-08-25
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 2020-10-09
      相关资源
      最近更新 更多