iOS -- 通过runtime向Button的点击方法里传递参数实现单选效果

本文介绍如何通过Objective-C的runtime技术,在点击Button时传递参数,以实现单选效果。当点击其中一个Button时,其他Button的选中状态会自动取消,提升代码复用性。主要涉及objc_setAssociatedObject和objc_getAssociatedObject这两个方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

效果:

有三个button点击其中一个将其他两个的选中状态取消,相当于单选的效果:

由于三个不同是同一类型的按钮,如果点击三个按钮都调用一个方法将会避免我们的代码重复,提高工作效率。那么要实现这样的代码效果我们就必须在点击方法里边将另外两个button的状态改变,并且点击的button不确定,其他的button也是不能确定的,这就需要我们在点击button调用点击方法的时候将另外两个button作为参数传到点击方法中去,

实现方法:

现在来分享一种传递的方法:

首先引入头文件#import <objc/runtime.h>

运用以下两个方法存取对象


                                         本对象              对应的标识                 需要关联的对象      关联类型

objc_setAssociatedObject(<#id object#>, <#const void *key#>, <#id value#>, <#objc_AssociationPolicy policy#>)    //这是关联方法



                                          本对象              对应的标识

objc_getAssociatedObject(<#id object#>, <#const void *key#>)   //这是取出关联对象的方法

  

代码示例:

    //初始化三个button
    SelectButton *inAndOutsideSelectBtn = [[SelectButton alloc]initWithSelected:YES Title:@"内包装-外包装"];
    [self addSelectButtonWithSelectButton:inAndOutsideSelectBtn Count:0];
    SelectButton *outsideSelectBtn = [[SelectButton alloc]initWithSelected:NO Title:@"物品-外包装"];
    [self addSelectButtonWithSelectButton:outsideSelectBtn Count:1];
    SelectButton *insideSelectBtn = [[SelectButton alloc]initWithSelected:NO Title:@"物品-内包装"];
    [self addSelectButtonWithSelectButton:insideSelectBtn Count:2];

    ///添加点击方法
    [inAndOutsideSelectBtn addTarget:self action:@selector(selectBaozhuangButtonDidClicked:) forControlEvents:UIControlEventTouchUpInside];
    ///关联另外两个按钮

    objc_setAssociatedObject(inAndOutsideSelectBtn, @"firstOtherButton", outsideSelectBtn, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    objc_setAssociatedObject(inAndOutsideSelectBtn, @"secondOtherButton", insideSelectBtn, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
   ///第二个按钮添加点击方法
    [outsideSelectBtn addTarget:self action:@selector(selectBaozhuangButtonDidClicked:) forControlEvents:UIControlEventTouchUpInside];
    ///关联另外两个按钮
    objc_setAssociatedObject(outsideSelectBtn, @"firstOtherButton", inAndOutsideSelectBtn, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    objc_setAssociatedObject(outsideSelectBtn, @"secondOtherButton", insideSelectBtn, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
   ///第三个按钮添加点击方法
    [insideSelectBtn addTarget:self action:@selector(selectBaozhuangButtonDidClicked:) forControlEvents:UIControlEventTouchUpInside];
    ///关联另外两个按钮
    objc_setAssociatedObject(insideSelectBtn, @"firstOtherButton", inAndOutsideSelectBtn, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    objc_setAssociatedObject(insideSelectBtn, @"secondOtherButton", outsideSelectBtn, OBJC_ASSOCIATION_RETAIN_NONATOMIC);


 button的点击方法 ,将点击之后button应该有的状态通过定义是block传到自定义button的初始化方法里边包含的block代码块中做相应的操作。 

#pragma mark -- 选择包装模式button点击方法
- (void)selectBaozhuangButtonDidClicked:(SelectButton *)sender{
    SelectButton *firstBtn = objc_getAssociatedObject(sender, @"firstOtherButton");
    SelectButton *seconBtn = objc_getAssociatedObject(sender, @"secondOtherButton");
    if (sender.isSlected == NO){
        //运用block将button点击后应该显示的状态传过去
        sender.clicedBlock(YES);
        firstBtn.clicedBlock(NO);
        seconBtn.clicedBlock(NO);

    }

}

自定义button的.h文件

#import <UIKit/UIKit.h>

typedef void(^CLICDEDBLOCK)(BOOL isSelected);

@interface SelectButton : UIButton

///是否被选中的标志
@property(nonatomic,assign)BOOL isSlected;

@property(nonatomic,copy)CLICDEDBLOCK clicedBlock;

#pragma mark -- 重写初始化方法
- (instancetype)initWithSelected:(BOOL)isSlected Title:(NSString *)title;



@end

自定义button的.m文件

#import "SelectButton.h"

@implementation SelectButton
///初始化的时候选择是否被选中
- (instancetype)initWithSelected:(BOOL)isSlected Title:(NSString *)title
{
    self = [super init];
    if (self) {
        self.backgroundColor = RGBCOLOR(227, 221, 198);
        [self.titleLabel setFont:TEXT_FONT];
        [self setTitle:title forState:UIControlStateNormal];

              _isSlected = isSlected;
        if (_isSlected == YES) {
            //如果需要选中状态
            [self setBackgroundImage:[UIImage imageNamed:@"selected_btn_bg"] forState:UIControlStateNormal];
        }else{
            //如果需要不选中状态
            [self setBackgroundImage:nil forState:UIControlStateNormal];
            [self setTitleColor:RGBCOLOR(63, 183, 158) forState:UIControlStateNormal];
        }

    //此block外部点击时会调用做出相应的改变
        __weak __typeof(self) ws = self;
        self.clicedBlock = ^(BOOL isSelect){

            if (isSelect == YES) {
                //改变button的状态
                ws.isSlected = YES;
                [ws setBackgroundImage:[UIImage imageNamed:@"selected_btn_bg"] forState:UIControlStateNormal];
                [ws setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
            }else{
                ws.isSlected = NO;
                [ws setBackgroundImage:nil forState:UIControlStateNormal];
                [ws setTitleColor:RGBCOLOR(63, 183, 158) forState:UIControlStateNormal];
            }
        };
        

    }
    return self;
}


@end
关联两个button是这样,依次类推可以关联多个对象,以实现单选效果。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值