• IOS UIScrollView + UIButton 实现segemet页面和顶部标签页水平滚动效果


      很长一段时间没有写博客了,最近在学习iOS开发,看了不少的代码,自己用UIScrollView和UIButton实现了水平滚动的效果,有点类似于今日头条的主界面框架,效果如下:

    代码如下:

    MyScrollView.h

    #import <UIKit/UIKit.h>
    #import "MySegementView.h"
    
    @interface MyScrollView : UIView<UIScrollViewDelegate>
    
    - (instancetype) initWithFrame:(CGRect)frame titleArray:(NSArray *)titleArray viewArray:(NSArray *)viewArray;
    
    //滚动页面
    @property (strong, nonatomic)UIScrollView *myScrollView;
    
    //顶部标签按钮滚动视图
    @property (strong, nonatomic)MySegementView *mySegementView;
    
    @end

    MyScrollView.m

    #define SCROLLVIEW_WIDTH [UIScreen mainScreen].bounds.size.width
    #define SCROLLVIEW_HEIGTH self.bounds.size.height
    #define SEGEMENT_HEIGTHT 44
    
    #import "MyScrollView.h"
    
    @implementation MyScrollView
    
    /*
    // Only override drawRect: if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    - (void)drawRect:(CGRect)rect {
        // Drawing code
    }
    */
    
    - (instancetype) initWithFrame:(CGRect)frame titleArray:(NSArray *)titleArray viewArray:(NSArray *)viewArray
    {
        self = [super initWithFrame:frame];
        if (_mySegementView == nil) {
            _mySegementView = [[MySegementView alloc] initWithFrame:CGRectMake(0, 0, SCROLLVIEW_WIDTH, SEGEMENT_HEIGTHT) titleArray:titleArray block:^void(int index){  //用block实现回调,顶部按钮点击的时候滚动到指定位置
                [_myScrollView setContentOffset:CGPointMake((index - 1) * SCROLLVIEW_WIDTH, 0)];
            }];
        }
        [self addSubview:_mySegementView];
        [self addSubview:self.myScrollView];
        
        if (self) {
            for (int i = 0; i < viewArray.count; i++) {
                UIViewController *viewController = viewArray[i];
                viewController.view.frame = CGRectMake(i * SCROLLVIEW_WIDTH, 0, SCROLLVIEW_WIDTH, self.myScrollView.frame.size.height);
                [self.myScrollView addSubview:viewController.view];
            }
            self.myScrollView.contentSize = CGSizeMake(viewArray.count * SCROLLVIEW_WIDTH, 0);
        }
        
        return self;
    }
    
    
    // 滚动页面视图懒加载
    - (UIScrollView *)myScrollView
    {
        if (_myScrollView == nil) {
            _myScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, _mySegementView.frame.size.height, SCROLLVIEW_WIDTH, SCROLLVIEW_HEIGTH - _mySegementView.frame.size.height)];
            _myScrollView.backgroundColor = [UIColor clearColor];
            _myScrollView.delegate = self;
            _myScrollView.showsVerticalScrollIndicator = NO;
            _myScrollView.showsHorizontalScrollIndicator = NO;
            _myScrollView.bounces = NO;
            _myScrollView.scrollsToTop = NO;
            _myScrollView.pagingEnabled = YES;
            
        }
        return _myScrollView;
    }
    
    //滚动结束,更新按钮下方线条
    -(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
    {
        if (scrollView==_myScrollView)
        {
            int p=_myScrollView.contentOffset.x / SCROLLVIEW_WIDTH;
            [_mySegementView setPageIndex:p + 1];
        }
    }
    
    @end

    MySegementView.h

    #import <UIKit/UIKit.h>
    
    typedef void (^btnClickedBlock)(int index);
    
    @interface MySegementView : UIView<UIScrollViewDelegate>
    {
        int nPageIndex;
        int titleCount;
        UIButton *currentBtn;
        NSMutableArray *btnArray;
    }
    
    - (void)setPageIndex:(int)nIndex;
    
    - (instancetype) initWithFrame:(CGRect)frame titleArray : (NSArray *)titleArray block : (btnClickedBlock) clickedBlock;
    
    @property (nonatomic, copy) btnClickedBlock block;
    
    @property (strong, nonatomic) UIScrollView *segementScrollView;
    
    @property (strong, nonatomic) UIView *selectedLine;
    
    @end

    MySegementView.m

    #import "MySegementView.h"
    #define SEGEMENT_BTN_WIDTH 48
    
    @implementation MySegementView
    
    /*
    // Only override drawRect: if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    - (void)drawRect:(CGRect)rect {
        // Drawing code
    }
    */
    - (instancetype) initWithFrame:(CGRect)frame titleArray : (NSArray *)titleArray block : (btnClickedBlock) clickedBlock
    {
        self = [super initWithFrame:frame];
        [self addSubview:self.segementScrollView];
        if (self) {
            [self setBackgroundColor:[UIColor colorWithRed:0x2d/255.0 green:0x2a/255.0 blue:0x2b/255.0 alpha:1]];
            self.block = clickedBlock;
            nPageIndex = 1;
            titleCount = titleArray.count;
            btnArray = [NSMutableArray array];
            for (int i = 0; i < titleCount; i++) {
                UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(i * SEGEMENT_BTN_WIDTH, 0, SEGEMENT_BTN_WIDTH, 42)];
                [btn setTitle:titleArray[i] forState:UIControlStateNormal];
                btn.titleLabel.font = [UIFont fontWithName:@"Arial" size:14];
                [btn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
                btn.tag = i + 1;
                [btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchDown];
                [self.segementScrollView addSubview:btn];
                [btnArray addObject:btn];
            }
            self.selectedLine.frame = CGRectMake(0, 42, SEGEMENT_BTN_WIDTH, 2);
            [self.segementScrollView addSubview: self.selectedLine];
            self.segementScrollView.contentSize = CGSizeMake(titleCount * SEGEMENT_BTN_WIDTH, 0);
        }
        return self;
    }
    
    //懒加载
    - (UIScrollView *)segementScrollView
    {
        if (_segementScrollView == nil) {
            CGRect rect = self.frame;
            _segementScrollView = [[UIScrollView alloc] initWithFrame:rect];
            _segementScrollView.showsHorizontalScrollIndicator = NO;
            _segementScrollView.showsVerticalScrollIndicator = NO;
            _segementScrollView.bounces = NO;
            _segementScrollView.pagingEnabled = NO;
            _segementScrollView.delegate = self;
            _segementScrollView.scrollsToTop = NO;
        }
        return _segementScrollView;
    }
    
    //懒加载
    - (UIView *)selectedLine
    {
        if (_selectedLine == nil) {
            _selectedLine = [[UIView alloc] init];
            _selectedLine.backgroundColor = [UIColor redColor];
        }
        return _selectedLine;
    }
    
    //设置当前页面,并更新顶部标签页
    - (void)setPageIndex:(int)nIndex
    {
        if (nIndex != nPageIndex) {
            nPageIndex = nIndex;
            [self refreshSegement];
        }
    }
    
    - (void)refreshSegement
    {
        //找到当前选中页面对应的顶部按钮
        for (UIButton *btn in btnArray) {
            if (btn.tag == nPageIndex) {
                currentBtn = btn;
            }
        }
        
        //如果选中页面对应按钮超出可视范围,顶部滚动视图滚动
        int x = currentBtn.frame.origin.x;
         if (currentBtn.frame.origin.x + SEGEMENT_BTN_WIDTH > self.frame.size.width + self.segementScrollView.contentOffset.x) {
         [self.segementScrollView setContentOffset:CGPointMake(self.segementScrollView.contentOffset.x + SEGEMENT_BTN_WIDTH, 0) animated:YES];
         }
         else if (currentBtn.frame.origin.x < self.segementScrollView.contentOffset.x)
         {
         [self.segementScrollView setContentOffset:CGPointMake(currentBtn.frame.origin.x, 0) animated:YES];
         }
    
        //下方选中标记线条滚动效果
        [UIView animateWithDuration:0.2 animations:^{
        _selectedLine.frame = CGRectMake(currentBtn.frame.origin.x, self.frame.size.height - 2, SEGEMENT_BTN_WIDTH, 2);
        }completion:^(BOOL finished) {
            
        }];
    }
    
    - (void)btnClick:(UIButton*)btn
    {
        currentBtn = btn;
        if (nPageIndex != btn.tag) {
            nPageIndex = btn.tag;
            [self refreshSegement];
            self.block(nPageIndex);
        }
    }
    @end

    使用方法:

    - (void)viewDidLoad {
        [super viewDidLoad];
        
        NSMutableArray *array=[NSMutableArray array];//显示的标签页
        for (int i = 0; i < 12; i++) {
                MyViewController1 *viewController1 = [[MyViewController1 alloc] initWithIndex:i + 1];//initWithIndex : 自定义的构造方法,用于显示页面编号
                [array addObject:viewController1];//滚动视图列表
        }
        myScrollView = [[MyScrollView alloc] initWithFrame:self.view.frame titleArray:@[@"第1页",@"第2页",@"第3页",@"第4页",@"第5页",@"第6页",@"第7页",@"第8页",@"第9页",@"第10页",@"第11页",@"第12页"] viewArray:array];
        
        [self.view addSubview:myScrollView];
        // Do any additional setup after loading the view, typically from a nib.
    }

    源码下载链接:http://download.csdn.net/detail/lzm2625347497/9562677

  • 相关阅读:
    XGBoost参数
    算法
    Python2 和Python3 的区别
    解决ubuntu上ifconfig没有eth0/ens33且无法上网的问题
    Ubuntu 忘记root user密码 关闭图形界面
    rabbitmq消息队列
    CMDB 数据加密 最终整合API验证+AES数据加密
    CMDB API验证
    使用Python生成ASCII字符画
    google 技巧
  • 原文地址:https://www.cnblogs.com/lzmfywz/p/5626294.html
Copyright © 2020-2023  润新知