【问题标题】:Passing custom data in [UIButton addTarget]在 [UIButton addTarget] 中传递自定义数据
【发布时间】:2013-08-29 20:13:50
【问题描述】:

如何在UIButton 中指定目标时添加自定义数据?

id data = getSomeData();
[button addTarget:self 
           action:@selector(buyButtonTapped:event:) 
 forControlEvents:UIControlEventTouchUpInside];

我希望buyButtonTapped 函数看起来像:

(void) buyButtonTapped: (UIButton *) button event: (id) event data: (id) data

【问题讨论】:

    标签: iphone objective-c


    【解决方案1】:

    不可能。由 UIControl 触发的动作可以有 3 个不同的签名。

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

    它们都不允许您发送自定义数据。


    根据您想要做什么,您可以通过不同的方式访问数据。

    例如,如果按钮位于 UITableView 中,您可以使用如下内容:

    - (IBAction)buttonPressed:(UIButton *)sender {
        CGPoint buttonOriginInTableView = [sender convertPoint:CGPointZero toView:tableView];
        NSIndexPath *indexPath = [tableView indexPathForRowAtPoint:buttonOriginInTableView];
        NSData *customData = [myDataSource customDataForIndexPath:indexPath];
        // do something
    }
    

    总有一种方法可以在不将数据传递给按钮的情况下获取数据。

    【讨论】:

    • 这行得通。谢谢!它确实是 UITableView 中的自定义按钮。我想要的数据是 UITableView 本身,以找出单击了哪个按钮。
    • 它总是一个tableview ^^
    • “总有办法……”你确定吗?
    • 是的,我是。随意挑战我。但我不得不承认,有时需要一些丑陋的变通方法或添加更多实例变量。
    • @Michael 您可以为单元格中的每个按钮调用不同的 IBAction。因此,如果您有一个向上按钮和一个向下按钮,例如,您可以在按下向上按钮时设置一个函数 upButtonPressed,在按下向下按钮时设置一个函数 downButtonPressed。
    【解决方案2】:

    您不能向操作方法发送额外的数据。有多种方法可以将数据与按钮相关联,但没有一种方法特别简单,除非数据是单个 NSInteger。

    • 您可以使用tag 属性来保存单个NSInteger。这可能就是您所需要的,或者您可以使用它在数组或字典中查找对象。
    • 您可以继承 UIButton 来添加 ivars/属性来存储您需要的数据。
    • 您可以使用[NSValue valueWithNonretainedObject:button] 作为字典的键。
    • 我个人最喜欢一次性的,您可以使用 [associative references] 将数据对象与按钮相关联。

    【讨论】:

    • 子类化 UIButton 绝对可以解决问题,并且应该是正确的答案之一,恕我直言
    • tag 最终成为了我所需要的,并为我节省了一些时间 :) 否则,我会子类化。这是更好的答案 IMO
    • 选项 4 没有意义:你必须有某种选择器才能传递给 objc_setAssociatedObject,NSHipster 使用类别来解决它,所以为什么要使用 opt。 4个?
    【解决方案3】:

    你真的不能那样做。您可以做的是将数据放入字典中,稍后使用按钮获取。

    例如

    myDataDict = [NSDictionary dictionaryWithObjectsAndKeys:someData, button, nil];
    

    然后;

    -(void) buttonPress:(id)sender
    {
      data = [dataDict objectForKey:sender];
    }
    

    如果您的按钮是在 InterfaceBuilder 中指定的,您可以使用按钮的 'tag' 属性来查找数据,但您需要将其转换为 NSNumber 以便与字典一起使用。

    【讨论】:

    • 请注意,使用按钮本身作为字典键将复制按钮对象,此时它可能不再与原始对象进行比较。 tag 属性可以与 IB 一起使用,也可以不与 IB 一起使用。
    • @Anomie:其实我什至不认为按钮可以复制,因为它们不符合NSCopying
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-03
    相关资源
    最近更新 更多