代码之家  ›  专栏  ›  技术社区  ›  Pierre Espenan meade

向AddTarget传递参数:操作:ForControlEvents

  •  121
  • Pierre Espenan meade  · 技术社区  · 14 年前

    我正在使用addTarget:action:forControlEvents,如下所示:

    [newsButton addTarget:self
    action:@selector(switchToNewsDetails)
    forControlEvents:UIControlEventTouchUpInside];
    

    我想把参数传递给我的选择器“switchtonewsdails”。 我做的唯一成功的事情就是通过写来传递(id)发送者:

    action:@selector(switchToNewsDetails:)

    但是我尝试传递像整数值这样的变量。这样写是行不通的:

    int i = 0;
    [newsButton addTarget:self
    action:@selector(switchToNewsDetails:i)
    forControlEvents:UIControlEventTouchUpInside];
    

    这样写也不起作用:

    int i = 0;
    [newsButton addTarget:self
    action:@selector(switchToNewsDetails:i:)
    forControlEvents:UIControlEventTouchUpInside];
    

    如有任何帮助,我们将不胜感激:)

    13 回复  |  直到 6 年前
        1
  •  170
  •   Vladimir    14 年前
    action:@selector(switchToNewsDetails:)
    

    不将参数传递给 switchToNewsDetails: 方法在此。您只需创建一个选择器,使按钮能够在某些操作发生时调用它(在您的情况下进行润色)。控件可以使用3种类型的选择器来响应操作,所有这些选择器都具有其参数的预定义含义:

    1. 没有参数

      action:@selector(switchToNewsDetails)
      
    2. 其中1个参数指示发送消息的控件

      操作:@selector(switchtonewsdails:)
      
    3. 有两个参数指示发送消息的控件和触发消息的事件:

      action:@selector(switchToNewsDetails:event:)
      

    目前尚不清楚您究竟要做什么,但考虑到您要为每个按钮分配一个特定的详细信息索引,您可以执行以下操作:

    1. 将每个按钮的标记属性设置为所需索引
    2. 在里面 开关按钮详细信息: 方法可以获取该索引并打开相应的详细信息:

      - (void)switchToNewsDetails:(UIButton*)sender{
          [self openDetails:sender.tag];
          // Or place opening logic right here
      }
      
        2
  •  63
  •   Yuriy Polezhayev    11 年前

    要将自定义参数与按钮一起传递,只需单击 子类ui按钮 .

    (ASR已打开,因此代码中没有任何版本。)

    这是 MyButo.h

    #import <UIKit/UIKit.h>
    
    @interface myButton : UIButton {
        id userData;
    }
    
    @property (nonatomic, readwrite, retain) id userData;
    
    @end
    

    这是 MyButo.m

    #import "myButton.h"
    @implementation myButton
    @synthesize userData;
    @end
    

    用途:

    myButton *bt = [myButton buttonWithType:UIButtonTypeCustom];
    [bt setFrame:CGRectMake(0,0, 100, 100)];
    [bt setExclusiveTouch:NO];
    [bt setUserData:**(insert user data here)**];
    
    [bt addTarget:self action:@selector(touchUpHandler:) forControlEvents:UIControlEventTouchUpInside];
    
    [view addSubview:bt];
    

    接收功能:

    - (void) touchUpHandler:(myButton *)sender {
        id userData = sender.userData;
    }
    

    如果您需要我对上述代码的任何部分做更具体的说明,请随时在评论中询问。

        3
  •  19
  •   Benoît    14 年前

    目标操作允许三种不同形式的操作选择器:

    - (void)action
    - (void)action:(id)sender
    - (void)action:(id)sender forEvent:(UIEvent *)event
    
        4
  •  15
  •   Albert Renshaw    6 年前

    不仅仅需要一个(int)via.tag?使用KVC!

    您可以通过按钮对象本身传递您想要的任何数据(通过访问calayers keyvalue dict)。


    像这样设置目标(使用“:”)

    [myButton addTarget:self action:@selector(buttonTap:) forControlEvents:UIControlEventTouchUpInside];
    

    将数据添加到按钮本身 .layer 按钮)如下:

    NSString *dataIWantToPass = @"this is my data";//can be anything, doesn't have to be NSString
    [myButton.layer setValue:dataIWantToPass forKey:@"anyKey"];//you can set as many of these as you'd like too!
    

    然后,当点击按钮时,您可以这样检查它:

    -(void)buttonTap:(UIButton*)sender{
    
        NSString *dataThatWasPassed = (NSString *)[sender.layer valueForKey:@"anyKey"];
        NSLog(@"My passed-thru data was: %@", dataThatWasPassed);
    
    }
    
        5
  •  7
  •   Abhinav Singh    11 年前

    我根据上面的部分信息制定了一个解决方案。我只是将titlelabel.text设置为要传递的字符串,并将titlelabel.hidden设置为yes

    这样地:

    UIButton *imageclick = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
    imageclick.frame = photoframe;
    imageclick.titleLabel.text = [NSString stringWithFormat:@"%@.%@", ti.mediaImage, ti.mediaExtension];
    imageclick.titleLabel.hidden = YES;
    

    这样,就不需要继承或类别,也不存在内存泄漏。

        6
  •  5
  •   rjdunwoody91    10 年前

    我为一个数组中的每个电话号码创建了几个按钮,因此每个按钮需要一个不同的电话号码来呼叫。我在for循环中创建几个按钮时使用了settag函数:

    for (NSInteger i = 0; i < _phoneNumbers.count; i++) {
    
        UIButton *phoneButton = [[UIButton alloc] initWithFrame:someFrame];
        [phoneButton setTitle:_phoneNumbers[i] forState:UIControlStateNormal];
    
        [phoneButton setTag:i];
    
        [phoneButton addTarget:self
                        action:@selector(call:)
              forControlEvents:UIControlEventTouchUpInside];
    }
    

    然后在我的call:方法中,我使用相同的for循环和if语句来选择正确的电话号码:

    - (void)call:(UIButton *)sender
    {
        for (NSInteger i = 0; i < _phoneNumbers.count; i++) {
            if (sender.tag == i) {
                NSString *callString = [NSString stringWithFormat:@"telprompt://%@", _phoneNumbers[i]];
                [[UIApplication sharedApplication] openURL:[NSURL URLWithString:callString]];
            }
        }
    }
    
        7
  •  2
  •   Kumar KL ganeshIOS    10 年前

    因为这里提到的解决方案有很多种方法,除了类别特性。

    使用类别功能将已定义(内置)元素扩展到 可定制元素。

    例如(例如):

    @interface UIButton (myData)
    
    @property (strong, nonatomic) id btnData;
    
    @end
    

    在你的视图控制器中。

     #import "UIButton+myAppLists.h"
    
    UIButton *myButton = // btn intialisation....
     [myButton set btnData:@"my own Data"];
    [myButton addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
    

    事件处理程序:

    -(void)buttonClicked : (UIButton*)sender{
        NSLog(@"my Data %@", sender. btnData);
    }
    
        8
  •  2
  •   Anton Lisitsyn    6 年前

    还有一种方法,您可以从中获取按钮所在单元格的索引路径:

    使用常见的动作选择器,如:

     UIButton *btn = ....;
        [btn addTarget:self action:@selector(yourFunction:) forControlEvents:UIControlEventTouchUpInside];
    

    然后在你的功能中:

       - (void) yourFunction:(id)sender {
    
        UIButton *button = sender;
        CGPoint center = button.center;
        CGPoint rootViewPoint = [button.superview convertPoint:center toView:self.tableView];
        NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:rootViewPoint];
        //the rest of your code goes here
        ..
    }
    

    因为你得到了一个indexpath,它变得简单多了。

        9
  •  1
  •   Aaron Saunders    14 年前

    看到我上面的评论,我相信当有多个参数时,必须使用nsinvocation

    有关nsInvocation的详细信息,请访问此处

    http://cocoawithlove.com/2008/03/construct-nsinvocation-for-any-message.html

        10
  •  1
  •   Sangram Shivankar Wostein    8 年前

    这解决了我的问题,但它崩溃了,除非我改变

    action:@selector(switchToNewsDetails:event:)                 
    

    action:@selector(switchToNewsDetails: forEvent:)              
    
        11
  •  1
  •   Marián Černý    7 年前

    通过添加一个助手闭包包装器(闭包套管)并将其作为关联对象添加到控件中,可以用闭包(Objective-C中的块)替换目标操作,以便保留它。这样就可以传递任何参数。

    斯威夫特3

    class ClosureSleeve {
        let closure: () -> ()
    
        init(attachTo: AnyObject, closure: @escaping () -> ()) {
            self.closure = closure
            objc_setAssociatedObject(attachTo, "[\(arc4random())]", self, .OBJC_ASSOCIATION_RETAIN)
        }
    
        @objc func invoke() {
            closure()
        }
    }
    
    extension UIControl {
        func addAction(for controlEvents: UIControlEvents, action: @escaping () -> ()) {
            let sleeve = ClosureSleeve(attachTo: self, closure: action)
            addTarget(sleeve, action: #selector(ClosureSleeve.invoke), for: controlEvents)
        }
    }
    

    用途:

    button.addAction(for: .touchUpInside) {
        self.switchToNewsDetails(parameter: i)
    }
    
        12
  •  0
  •   iNiko84    8 年前

    我在CustomButton中对uiButton进行了子类化,并添加了一个存储数据的属性。所以我调用方法:(customButton*)sender,在该方法中,我只读取数据sender.myproperty。

    自定义按钮示例:

    @interface CustomButton : UIButton
    @property(nonatomic, retain) NSString *textShare;
    @end
    

    方法动作:

    + (void) share: (CustomButton*) sender
    {
        NSString *text = sender.textShare;
        //your work…
    }
    

    指定动作

        CustomButton *btn = [[CustomButton alloc] initWithFrame: CGRectMake(margin, margin, 60, 60)];
        // other setup…
    
        btnWa.textShare = @"my text";
        [btn addTarget: self action: @selector(shareWhatsapp:)  forControlEvents: UIControlEventTouchUpInside];
    
        13
  •  0
  •   Bubu    6 年前

    如果只想将导航控制器显示的LeftBarButtonItem的文本与新视图一起更改,则可以在将PushViewController调用为所需文本之前更改当前视图的标题,并在ViewHasDisappered回调中将其还原为当前视图的未来显示。

    此方法保持功能(PopViewController)和所示箭头的外观不变。

    它至少在iOS12上工作,用xcode 10.1构建…