想必大家用过很多app都有一个导航栏,上面各个按钮对应显示不同的列表。类似微信之类的底部的导航栏一样。而本例要说的是一个页面中间的列表导航。

先上效果图:

其中红色框内就是本文需要解决的问题。效果就是每当点击到对应区域,数字、文字以及底部横线变为红色,其他3个还原为默认灰色,且底部线隐藏。

首先创建按钮,因为布局以及可复用特点,所以应进行封装;

而决定用view来封装并添加手势,而不是直接封装成button。

一、封装并创建控件

1、封装:创建文件,创建三个控件(数字、文字、底部红线),并写好布局

2、封装:创建方法,并将接口(方法)暴露在.h文件中:

- (instancetype)initWithNumber:(NSString *)number andStateLabel:(NSString *)stateLabel{
    if(self = [super init]){
        self.numberLabel.text = number;
        self.stateLabel.text = stateLabel;
        [self setLayout];
    };
    return self;
}

创建控件:在父视图view内使用此封装接口(方法)创建4个控件并赋值即可(完成按钮创建)。

二、实现点击事件

1、使用 ReactiveObjc(即RAC),创建RAC实例subject,懒加载

/** RAC传订单状态*/
@property (nonatomic, strong) RACSubject *subject;
- (RACSubject *)subject{
    if(!_subject){
        _subject = [RACSubject subject];
    }
    return _subject;
}

2、按钮懒加载内创建tap手势,并给4个按钮不同tag,使用同个点击事件方法如3、中

3、在点击事件方法中,把点击的tag传到controller内:

- (void)tapGestureWithTag:(UITapGestureRecognizer *)tap{
    [self.subject sendNext:@(tap.view.tag)];
    }

4、在controller对应的承载view的懒加载中接收信号并判断,进行点击事件处理:

//因为传过来的@()是NSNumber类型,所以接收要类型也要为NSNumber。
[_topView.subject subscribeNext:^(NSNumber *x) {
            if([x intValue] == 1){
                [MBProgressHUD showMessage:@"待发货"];
            }else if ([x intValue] == 2){
                [MBProgressHUD showMessage:@"待收货"];
            }else if ([x intValue] == 3){
                [MBProgressHUD showMessage:@"已完成"];
            }else if ([x intValue] == 4){
                [MBProgressHUD showMessage:@"售后中"];
            }
        }];

此时点击各个按钮就会实现各自点击事件(弹出不同内容弹窗)。

三、实现点击到的按钮的高亮状态

1、首先要在封装的view.h中暴露一个接口,来判断是否为点击选中状态,只有两种状态,所以选择创建BOOL变量:

/** 选中状态*/
@property (nonatomic, assign) BOOL isSelected;

2、在view.m的set方法中进行不同状态的赋值改变

- (void)setIsSelected:(BOOL)isSelected{
    _isSelected = isSelected;
    //选中时数字和文字为红色、下部红线显示
    if(isSelected == YES){
        self.numberLabel.textColor = Red_Color;
        self.stateLabel.textColor = Red_Color;
        self.lineView.hidden = NO;
    }else{
        self.lineView.hidden = YES;
        self.numberLabel.textColor = FontGray_Color;
        self.stateLabel.textColor = FontGray_Color;
    }
}

3、在创建了4个按钮的父视图view中,的点击事件方法里,判断选中的按钮,这里用到了数组遍历:

首先创建数组并将4个按钮放到数组中:

- (NSArray *)dataArray{
    if(!_dataArray){
        _dataArray = @[self.waitView,self.receiveView,self.doneView,self.afterView];
    }
    return _dataArray;
}

方法内添加forin循环:

- (void)tapGestureWithTag:(UITapGestureRecognizer *)tap{
    [self.subject sendNext:@(tap.view.tag)];

    for (ABActivityOrderStateView *stateView in self.dataArray) {
        if(stateView.tag == tap.view.tag){
            stateView.isSelected = YES;
        }else{
            stateView.isSelected = NO;
        }
    }
}

此时就会实现点击选中的按钮为红色,其他为灰色。