iOS如何自定义UIBarButtonItem的target和action
创始人
2024-12-19 20:41:47
0次

需求描述:

在项目开发过程中,遇到一种情况,需要自定义UIBarButtonItem,来实现分享样式,并在iPad中弹出系统分享框(UIActivityViewController),系统分享框需要指定显示位置(barButtonItem)。而自定义的UIBarButtonItem target指向的是UIButton。这与需求不符,需自定义UIBarButtonItem。

在介绍自定义UIBarButtonItem前,先介绍一下相关控件的子父类关系(也可以说继承关系)。

1、UIBarItem

NS_CLASS_AVAILABLE_IOS(2_0) @interface UIBarItem : NSObject

2、UIBarButtonItem

NS_CLASS_AVAILABLE_IOS(2_0) @interface UIBarButtonItem : UIBarItem

3、UITabBarItem

NS_CLASS_AVAILABLE_IOS(2_0) @interface UITabBarItem : UIBarItem

UIBarButtonItem有三种效果显示,分别是

1、导航左侧返回按钮,UINavigationItem中的backBarButtonItem属性

@property(nullable,nonatomic,strong) UIBarButtonItem *backBarButtonItem

2、纯文本的UIBarButtonItem

- (instancetype)initWithTitle:(nullable NSString *)title style:(UIBarButtonItemStyle)style target:(nullable id)target action:(nullable SEL)action;

3、纯图片的UIBarButtonItem,其中包括自定义图片和系统样式

- (instancetype)initWithImage:(nullable UIImage *)image style:(UIBarButtonItemStyle)style target:(nullable id)target action:(nullable SEL)action;

- (instancetype)initWithBarButtonSystemItem:(UIBarButtonSystemItem)systemItem target:(nullable id)target action:(nullable SEL)action;

UIToolBar使用UIBarButtonItem与导航效果一致。

关于UITabBarItem在这里就不多介绍,只是拿其显示效果与UIBarButtonItem对比。

在开发过程中,我们会使用到自定义UIBarButtonItem,来显示我们想要的界面效果。使用的方法常为:

- (instancetype)initWithCustomView:(UIView *)customView;

- (void)viewDidLoad { [super viewDidLoad]; //自定义View UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 60.0, 40.0)]; view.backgroundColor = [UIColor redColor]; //自定义按钮 UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; btn.frame = view.bounds; [btn addTarget:self action:@selector(clickRight:) forControlEvents:UIControlEventTouchUpInside]; [view addSubview:btn]; //自定义Item UIBarButtonItem *barItem = [[UIBarButtonItem alloc] initWithCustomView:view]; // self.navigationItem.leftBarButtonItem = barItem;}#pragma mark -- (void)clickRight:(id)sender { NSLog(@"sender:%@",sender);}

其中打印sender,其类型是UIButton。

2017-10-17 16:08:43.917 TestImage[5482:163865] sender:>

通过上面描述,发现系统方法不能实现项目需求效果。当然也可以通过属性保存UIBarButtonItem方法来实现需求效果。即在点击按钮响应后,直接使用保存的UIBarButtonItem,但是我没有采用这种方法。

下面是我给出的两种解决方案:

方案一

继承UIBarButtonItem,实现子类。

定义子类

#import @interface LLBarButtonItem : UIBarButtonItem@end

#import "LLBarButtonItem.h"@implementation LLBarButtonItem- (id)initWithCustomView:(UIView *)customView { self = [super initWithCustomView:customView]; if (self) { UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; btn.frame = customView.bounds; btn.backgroundColor = [UIColor clearColor]; [btn addTarget:self action:@selector(clickButton:) forControlEvents:UIControlEventTouchUpInside]; [customView addSubview:btn]; } return self;}- (void)clickButton:(UIButton *)sender { if (self.target && [self.target respondsToSelector:self.action]) { //[self.target performSelector:self.action withObject:self]; IMP imp = [self.target methodForSelector:self.action]; void (*func)(id, SEL, id) = (void *)imp; func(self.target, self.action, self); }}@end

定义子类对象,调用子类对象

- (void)viewDidLoad { [super viewDidLoad]; //自定义View UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 60.0, 40.0)]; view.backgroundColor = [UIColor clearColor]; //自定义Item LLBarButtonItem *barItem = [[LLBarButtonItem alloc] initWithCustomView:view]; barItem.target = self; barItem.action = @selector(clickRight:); // self.navigationItem.leftBarButtonItem = barItem;}#pragma mark -- (void)clickRight:(id)sender { NSLog(@"sender:%@",sender);}

打印target对象

2017-10-17 16:24:11.696 TestImage[5557:170144] sender:

方案二

UIBarButtonItem类别

定义类别

#import @interface UIBarButtonItem (Custom)- (void)addCutomTarget:(id)target action:(SEL)action;@end

#import "UIBarButtonItem+Custom.h"@implementation UIBarButtonItem (Custom)- (void)addCutomTarget:(id)target action:(SEL)action { if (self.customView != nil) { self.target = target; self.action = action; // UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; btn.frame = self.customView.bounds; btn.backgroundColor = [UIColor clearColor]; [btn addTarget:self action:@selector(clickButton:) forControlEvents:UIControlEventTouchUpInside]; [self.customView addSubview:btn]; }}- (void)clickButton:(UIButton *)sender { if (self.target && [self.target respondsToSelector:self.action]) { //[self.target performSelector:self.action withObject:self]; IMP imp = [self.target methodForSelector:self.action]; void (*func)(id, SEL, id) = (void *)imp; func(self.target, self.action, self); }}@end

调用类别方法

- (void)viewDidLoad { [super viewDidLoad]; //自定义View UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 60.0, 40.0)]; view.backgroundColor = [UIColor clearColor]; //自定义Item UIBarButtonItem *barItem = [[UIBarButtonItem alloc] initWithCustomView:view]; [barItem addCutomTarget:self action:@selector(clickRight:)]; // self.navigationItem.leftBarButtonItem = barItem;}#pragma mark -- (void)clickRight:(id)sender { NSLog(@"sender:%@",sender);}

打印target对象

2017-10-17 16:28:14.407 TestImage[5598:172418] sender:

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...