【问题标题】:Selectors with arguments in Obj-CObj-C 中带参数的选择器
【发布时间】:2010-02-12 15:13:55
【问题描述】:

所以基本上我有一个很大的按钮列表,其中包含下拉列表和其他内容,并且这些按钮是动态创建的。因此,要捕获相应按钮数据的值,我需要将其操作选择器设置为一个需要 1 个额外参数的函数。

例如,在此下拉列表中使用此选择器,使用以下方法,将返回选择器无法识别的错误。如何让选择器识别我传入的参数? (在本例中为变量“名称”)

苹果文档位于: http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocSelectors.html#//apple_ref/doc/uid/TP30001163-CH23-SW1

在标题“目标动作设计模式”的最后一段,Apple 文档暗示可以做到这一点,但没有给出使用自定义消息的示例,或者可能我只是误会了?

SEL sel = @selector(openDropdown:name:);
[dropdownSelector addTarget:self action:sel forControlEvents:UIControlEventTouchUpInside];


-(void) openDropdown: (NSString *) anotherArg : (id) sender {
 // Stuff here based on anotherArg
}

【问题讨论】:

  • 你上面的方法不正确,顺便说一句。

标签: iphone objective-c sdk


【解决方案1】:

您应该能够从id 输入参数中获取单击按钮的信息

    UIButton *button = (UIButton *) sender
     NSString *title = [button currentTitle];

不需要传递额外的参数

【讨论】:

  • 我需要比按钮名称更详细的信息。该按钮具有分配的按钮类型,核心数据中的 id 等。我会扩展 UIButton 并添加我需要的参数,但是由于 UIButton 的工作方式..您实际上不能通过扩展它来添加那种类型的东西。这也没有解决真正的问题,即我只需要传递比发送者更多的数据。如果我想这样做,我需要为应用程序中的每种类型的对象扩展我使用的每个类,并添加大量冗余数据。
  • 不看你的代码,就在我的脑海里——你能不能创建一个数据结构,比如一个 NSDictionary,比如 {key=buttonId, value=buttonData}。然后,您可以从 Action 方法中访问 buttonData
  • 我认为我最终可能会这样做。我所有的数据实际上已经在 Core Data 中,所以我可以使用谓词过滤掉具有指定标题的按钮。唯一的问题是如果有两个具有相同标题的按钮,希望我能找到一种有用的方法来使用标签组件从核心数据中获取正确的值。
【解决方案2】:

您的要求无法完成。来自文档:

UIKit 允许三种不同形式的动作选择器:

- (void)action
- (void)action:(id)sender
- (void)action:(id)sender forEvent:(UIEvent *)event

由于您对事件参数没有影响,sender 对象必须包含您要传递给操作方法的所有信息。

尽管您在对 mihirsm 的回答的评论中写了些什么,但您确实可以继承 UIButton 以将您想要的所有附加信息添加到每个按钮实例。您还可以使用按钮的tag 属性来识别它(为每个按钮分配一个唯一标签)并将所有附加信息存储在数组或字典中,使用标签作为键。

更新: 未来,您还可以使用associative storage 向对象添加数据,而无需对它们进行子类化,但这项技术(目前)还不能在 iPhone 平台上使用(目前仅 10.6 )。

【讨论】:

  • 你可以继承 UIButton 但你不能访问它的组件。创建按钮时,您使用静态函数 [MyCustomUIButton buttonWithType:UIButtonTypeRoundedRect] 因此,当您稍后访问它时,您不会获得 MyCustomUIButton 对象,而是获得 UIButtonTypeRoundedRect 对象的派生。我知道发生这种情况是因为我尝试过,然后通过在网上四处查看来确认。这是可能的,但它实际上涉及子类化 UIView 并在其中放置一个按钮。这一切都非常复杂和hack-ish。你有替代方法吗?
  • 使用标签组件可能就足够了,感谢您的提醒。
【解决方案3】:

CALayers 支持任意键进行键值编码;您可以使用它来附加任意层:

[[button1 layer] setValue:@"firstButtonData" forKey:@"myKey"];
[[button2 layer] setValue:@"secondButtonData" forKey:@"myKey"];

后来:

- (void)action:(id)sender forEvent:(UIEvent *)event
{
    NSLog(@"Data for the button that was pressed: %@", [[sender layer] valueForKey:@"myKey"]);
}

注意不要与CALayer上的任何现有属性发生冲突

【讨论】:

  • 感谢这是我正在寻找的。它对我来说就像魅力
猜你喜欢
  • 2011-06-17
  • 1970-01-01
  • 2010-10-11
  • 1970-01-01
  • 1970-01-01
  • 2012-04-15
  • 1970-01-01
  • 2017-03-10
  • 2021-11-24
相关资源
最近更新 更多