从0开始架构一个IOS程序—— 05— NavigationBar 搭建首页面

从0开始架构一个IOS程序 05 NavigationBar搭建首页面

Mac OSX 10.11 之后


效果



在这里的实现思路

  • 创建 navigationItem titleView
  • 添加ViewController
  • 关联 UIScrollView


1 创建 navigationItem titleView

1.1 WISHomeTopBarView.h
#import <UIKit/UIKit.h>

typedef NS_ENUM(NSUInteger,WISHomeTopType){
    WISHomeTopTypeDefault=0
};

@class WISHomeTopBarView;

//定义block回调
typedef void(^WISHomeTopBlock)(UIButton *topBar,WISHomeTopType idx);
//定义代理
@protocol WISHomeTopBarDelegate <NSObject>

-(void) topBar:(UIButton *) button clickIndex:(WISHomeTopType) idx;

@end

@interface WISHomeTopBarView : UIView

//block回调
@property(copy,nonatomic) WISHomeTopBlock block;
//代理回调
@property(weak,nonatomic) id<WISHomeTopBarDelegate> topBarDelegate;

//创建设置标签
- (instancetype)initWithFrame:(CGRect)frame titleNames:(NSArray*) titles;
//修改标签的位置
-(void) scrollChangTopBar:(NSInteger) tag;


@end
1.2 WISHomeTopBarView.m

在这里的实现思路是

也就是自定义了一个UIView,然后通过传入的数组中的显示标签来动态 的向其中创建添加UIButton


#import "WISHomeTopBarView.h"

@interface WISHomeTopBarView()


//tabBar条目数据集合
@property(nonatomic,strong) NSMutableArray *dataList;

//标签下的指示线
@property(nonatomic,strong) UIView *lineView;


@end

@implementation WISHomeTopBarView



//初始化创建view
- (instancetype)initWithFrame:(CGRect)frame titleNames:(NSArray*) titles
{
    self = [super initWithFrame:frame];
    if (self) {

        //每个item的宽度
        CGFloat width = self.width/titles.count;
        //item的高度
        CGFloat height = self.height;

        for (NSInteger i=0; i<titles.count; i++) {
            //创建Button
            //创建Button
            UIButton *button =[UIButton buttonWithType:UIButtonTypeCustom];
            //设置文字
            NSString *title = titles[i];
            [button setTitle:title forState:UIControlStateNormal];
            //设置按钮文字颜色
            [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
            //设置按钮字体
            button.titleLabel.font=[UIFont systemFontOfSize:18];

            //设置frame
            button.frame=CGRectMake(i*width, 0, width, height);
            //设置点击事件
            [button addTarget:self action:@selector(titleClick:) forControlEvents:UIControlEventTouchUpInside];
            //tag
            button.tag = i;
            //添加到数组中
            [self.dataList addObject:button];
            //添加
            [self addSubview:button];

            //创建标签下的小白线条
            //默认显示到中间

            if (i==1) {

                CGFloat h=2;
                CGFloat y=40;
                [button.titleLabel sizeToFit];
                self.lineView = [[UIView alloc]init];
                self.lineView.backgroundColor=[UIColor whiteColor];
                self.lineView.height=h;
                self.lineView.width=button.titleLabel.width;
                self.lineView.top = y;
                self.centerX=button.centerX;
                [self addSubview:self.lineView];
                self.centerX=button.centerX;
            }


        }
    }

    return self;
}
//懒加载机制
-(NSMutableArray *)dataList{
    if (!_dataList) {
        _dataList = [NSMutableArray array];
    }
    return _dataList;
}

//UIScrollview滑动回调改变标签下的小白线的位置
-(void)scrollChangTopBar:(NSInteger)tag{

    //获取对应tag下的UIButton
    UIButton *button = self.dataList[tag];
    //将小标签下的小白线与UIButton对齐
    [UIView animateWithDuration:0.5 animations:^{
        self.lineView.centerX=button.centerX;
    }];
}

//本View中(navigationItem.view)条目的点击事件
-(void) titleClick:(UIButton*) button{

    //block函数回调
    if(self.block){
        self.block(button, button.tag);
    }
    //代理方法回调
    if ([self.topBarDelegate respondsToSelector:@selector(topBar:clickIndex:)]) {
        [self.topBarDelegate topBar:button clickIndex:button.tag];
    }
    //移动小白条
    [UIView animateWithDuration:0.5 animations:^{
        self.lineView.centerX=button.centerX;
    }];
}
@end

2 将WISHomeTopBarView 添加到显示视图 WISHomeViewController中

2.1 WISHomeViewController.h
//CXBaseViewController.h 继承于UIViewController
#import "CXBaseViewController.h"

@interface WISHomeViewController : CXBaseViewController

@end
2.1 WISHomeViewController.m
  • 根布局下添加了UIScrollView
  • 实现自定义代理协议 WISHomeTopBarDelegate (监听WISHomeTopBarView 中item的点击回调)
@interface WISHomeViewController ()<UIScrollViewDelegate,WISHomeTopBarDelegate>

//头部标签显示文字
@property(strong,nonatomic) NSArray *topDataList;
//头部标签控件
@property(strong,nonatomic) WISHomeTopBarView *topBarView;

//加载Controller的布局文件
@property(strong,nonatomic) IBOutlet UIScrollView *contentScrollView;

@end

@implementation WISHomeViewController

-(NSArray *)topDataList{
    if (!_topDataList) {
        _topDataList= @[@"推荐",@"文章",@"视频"];
    }
    return _topDataList;
}

-(WISHomeTopBarView *)topBarView{
    if (!_topBarView) {

        _topBarView = [[WISHomeTopBarView alloc]initWithFrame:CGRectMake(0,0, 200, 50) titleNames:self.topDataList];
        //设置按键的点击回调
        _topBarView.topBarDelegate=self;
        //设置block回调
        _topBarView.block = ^(UIButton *topBar, WISHomeTopType idx) {
            NSLog(@"block 数据回调 ");
        };
    }
    return _topBarView;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    //1 设置navigationBar 的颜色
    [self.navigationController.navigationBar setBarTintColor:[UIColor colorWithHexString:@"#4169E1"]];
    [self.navigationController.navigationBar setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor whiteColor],UITextAttributeTextColor,nil]];

    //2 加载设置头标签
    self.navigationItem.titleView=self.topBarView;
    //3 添加子视图
    //WISHomeRecommendViewController
    //WISHomeArtViewController
    //WISHomeVideoViewController 
    //是已创建好的子视图控制器
    NSArray *array = @[@"WISHomeRecommendViewController",@"WISHomeArtViewController",@"WISHomeVideoViewController"];
    for (NSInteger i=0; i<array.count; i++) {
        //取出数据
        NSString *item = array[i];
        //创建
        UIViewController *controller = [[NSClassFromString(item) alloc] init];
        //设置标题
        controller.title = self.topDataList[i];

        [self addChildViewController:controller];
    }
    //将子控制器的View添加到MainView的scrollView中

    //4 设置scrollview的contentsize
    self.contentScrollView.contentSize=CGSizeMake([UIScreen mainScreen].bounds.size.width*self.topDataList.count, 0);
    //5 设置uiscrollView的代理
    self.contentScrollView.delegate=self;

    //进入主控制器的第一个页面
    [self scrollViewDidEndDecelerating:self.contentScrollView];
}
-(void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView{
    //每一个子控制器的宽度
    CGFloat width =scrollView.frame.size.width;
    //每一个子控制器的高度
    CGFloat height =[UIScreen mainScreen].bounds.size.height;
    //获取当前索引值
    NSInteger idx = scrollView.contentOffset.x/width;

    //设置联动
    [self.topBarView scrollChangTopBar:idx];
    //根据索引值返回引用
    UIViewController *vc=self.childViewControllers[idx];

    //判断当前的vc是否执行过viewLoaded
    if([vc isViewLoaded]){
        return;
    }else{
        //设置子控制器的视图大小
        vc.view.frame=CGRectMake(scrollView.contentOffset.x, 0, scrollView.frame.size.width, height);
        //将子控制器的view加入到scrollview中
        [scrollView addSubview:vc.view];
    }
}

//滑动减速结束
//调用加载子控制器的view的方法
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{

    NSLog(@"滑动结束 ...");
    [self scrollViewDidEndScrollingAnimation:scrollView];
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

//头部标签点击代理回调
-(void)topBar:(UIButton *)button clickIndex:(WISHomeTopType)idx{
    NSLog(@"click === ");

    CGPoint point = CGPointMake((idx-WISHomeTopTypeDefault)*[UIScreen mainScreen].bounds.size.width, self.contentScrollView.contentOffset.y);
    [self.contentScrollView setContentOffset:point animated:YES];
}


/*
 #pragma mark - Navigation

 // In a storyboard-based application, you will often want to do a little preparation before navigation
 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
 // Get the new view controller using [segue destinationViewController].
 // Pass the selected object to the new view controller.
 }
 */

@end
早起的年轻人 CSDN认证博客专家 移动开发 项目管理 Java
只要用心去做,每一件事情还是有可能成功的,当然成功是没有界限的,只不过是达到自己心里的那个目标,公众号:我的大前端生涯,一个爱喝茶的程序员,通常会搞搞SpringBoot 、Herbinate、Mybatiys、Android、iOS、Flutter、Vue、小程序等.
©️2020 CSDN 皮肤主题: 代码科技 设计师:Amelia_0503 返回首页