美文网首页程序员
一个用经常用到的首页

一个用经常用到的首页

作者: 指尖书法 | 来源:发表于2017-03-31 15:10 被阅读234次

最近一些项目中经常用到一个首页,就是利用父子控制器搭建一个可以左右滑动显示的主页.这个页面从我接触的第一个项目到现在,已经遇到了好几次,每次都会根据不同的需求进行改动,呈现不一样的主页.但大体框架是不变的.所以干脆把首页抽出来做一个demo,以后有用到直接拖进去就好.

通用主页

总体思路

  1. 创建父控制器
  2. 给父控制器添加若干子控制器
  • 添加一个左右滚动的根视图View
  • 设置标题栏
  • 启动程序时直接选中第一个控制器

一、添加子控制器

这里只添加了三个,可以继续无限添加.

-(void)setupChildVCs
{
    //创建三个个页面
    XHHChild1ViewController *VC1 = [[XHHChild1ViewController alloc]init];
    XHHChild2ViewController *VC2 = [[XHHChild2ViewController alloc]init];
    XHHChild3ViewController *VC3 = [[XHHChild3ViewController alloc]init];
    
    //给自己添加三个子控制器
    
    [self addChildViewController:VC1];
    [self addChildViewController:VC2];
    [self addChildViewController:VC3];
    
}

二、设置scrollVIew

此招式根据自己需要,具体设置scrollVIew的各项参数

-(void)setupScrollView
{

//几个子控制器,就计算几个contentSize的宽度(缺点是:代码设置滚动必须在设置子控制器方法之后)
NSUInteger numVC = self.childViewControllers.count;
UIScrollView *scrollView = [[UIScrollView alloc]initWithFrame:self.view.bounds];
scrollView.backgroundColor = XHHRandomColor;
//不允许设置自动适应内边距
self.automaticallyAdjustsScrollViewInsets = NO;
scrollView.bounces = NO;
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.showsVerticalScrollIndicator = NO;
scrollView.pagingEnabled = YES;
scrollView.backgroundColor = XHHWhite;
scrollView.contentSize = CGSizeMake(XHHScreenW * numVC, 0);
scrollView.delegate = self;
[self.view addSubview:scrollView];
self.scrollView = scrollView;

}

三、 设置顶部菜单栏和标题下面的指示标志

这个顶部菜单栏写起来比较繁琐,但一步一步写下去整个逻辑并不难.

#pragma mark --
#pragma mark - 设置顶部View
-(void)setupTopView
{
    
    
    //设置n个button到一个View上,再设置成为nav的titleView
    UIView *titleView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, XHHScreenW, TopViewH)];
    titleView.backgroundColor = XHHCharles;
    
    CGFloat buttonW = self.view.xhh_width/self.childViewControllers.count;
    CGFloat buttonH = TopViewH;
    //循环添加button
    for (int i = 0; i < self.titles.count ; i++ ) {
        
        CGFloat buttonX = i *buttonW;
        CGFloat buttonY = 0;
        

        //button的相关设置
        UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(buttonX, buttonY,buttonW, buttonH)] ;
        button.tag = i;
        
        //选中的title加粗
        
        NSAttributedString *attrNormaltitle = [[NSAttributedString alloc]initWithString:self.titles[i] attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15],NSForegroundColorAttributeName:XHHBlack}];
        
        NSAttributedString *attrSelectedtitle = [[NSAttributedString alloc]initWithString:self.titles[i] attributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:15],NSForegroundColorAttributeName:XHHBlack}];
        [button setAttributedTitle:attrSelectedtitle forState:UIControlStateSelected];
        [button setAttributedTitle:attrNormaltitle forState:UIControlStateNormal];
        button.titleLabel.textAlignment = NSTextAlignmentCenter;
        button.userInteractionEnabled = YES;
        
        [button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
        
        [titleView addSubview:button];
        [self.btnArray addObject:button];
        
        //在添加好以后就直接选中button
        
    }
    
    [self.view addSubview:titleView];
    self.topView = titleView;
    
    
    //底部的指示器
    UIView *indicatorView = [[UIView alloc]init];
    indicatorView.backgroundColor = XHHCharles3;
    indicatorView.xhh_height = 2;
    indicatorView.xhh_y = titleView.xhh_height - 2;
    [titleView addSubview:indicatorView];
    self.indicatorView = indicatorView;
    UIButton *firstButton =  self.btnArray[0];
    
#pragma mark - 这个sizeToFit必须要写 就是立即计算titleLabel的宽度  不写就没有宽度
    [firstButton.titleLabel sizeToFit];
    
    //NSLog(@"%f",firstButton.titleLabel.xhh_width);
    indicatorView.xhh_width = firstButton.titleLabel.xhh_width;
    indicatorView.xhh_centerX = firstButton.xhh_centerX;
    [indicatorView layoutIfNeeded];

 
    
}

四、scrollView的代理

这里面有几处可以自定义的地方
a. 指示标志跟随滚动,还是停止拖拽后指示标志才动?
b. 滚动后添加view还是 开始滚动就展示出view?
c. 标题按钮直接显示还是滚动显示?
这些方面都可已根据自己的喜好在代理方法中去定制.
我采用的是跟随滚动,滚动后显示View,点击按钮显示滚动动画.

#pragma mark --
#pragma mark - ScrollView代理
//根据滚动偏移量动态的添加view,这样不会导致打开程序的长时间加载
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    
    //计算停止滚动后的控制器是哪个
    NSInteger index = scrollView.contentOffset.x / self.view.xhh_width;
    
    //用数组记录button,根据index点击
    [self buttonClick:self.btnArray[index]];
    
}


-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    //指示View跟随滚动变更中点 = scroll偏移 * 二者比例 +中点的起始距离.
    self.indicatorView.xhh_centerX = scrollView.contentOffset.x * ((XHHScreenW / self.titles.count) / XHHScreenW) + (XHHScreenW / self.titles.count)/2 ;
    
}

五、两个重要的触发方法

1.button(topView上面的button)点击

-(void)buttonClick:(UIButton *)button
{
    
    
    NSInteger index = button.tag;
    //记录的button取消选中状态
    self.selectedBtn.selected = NO;
    
    //当前选中
    button.selected = YES;
    
    
    
    
    
    //选中之后动态跳转到另一个view中去(添加子控制器View)
    [UIView animateWithDuration:0.4 animations:^{
        
        self.scrollView.contentOffset = CGPointMake(index * self.view.xhh_width, 0);
        
    }];
    //滚动完了之后再添加子控制器,因为添加子控制器的时候用到了scrollView的bounds
    [self addChildViews:index];
    //继续记录
    self.selectedBtn = button;
    
}

2.其中的添加控制器方法
记得加载过的就不用再次加载了.万一页面比较复杂,可以节省内存.

-(void)addChildViews:(NSUInteger) index
{
    
    
    UIViewController *ChildVC = self.childViewControllers[index];
    
    if (ChildVC.viewLoaded) {
        return;
    }
    ChildVC.view.frame = self.scrollView.bounds;
    
    [self.scrollView addSubview:ChildVC.view];
    
}

此外,还可以在navigationBar上直接添加,不用再加一个topView了.也就是titleView代替topView.很简单,不做示范了.

这是demo地址,里面还包含了我在工作中经常用的工具类

相关文章

网友评论

    本文标题:一个用经常用到的首页

    本文链接:https://www.haomeiwen.com/subject/ibupottx.html