iOS开发—纯代码手写(不依靠第三方)实现顶部可滑动标题栏切换控制器

效果图:

iOS开发—纯代码手写(不依靠第三方)实现顶部可滑动标题栏切换控制器




实现:

创建UIView的分类UIView+SetMyView,在UIView+SetMyView.m里


#import "UIView+SetMyView.h"

@implementation UIView (SetMyView)

-(CGSize)gf_size

{

    return self.frame.size;

}

-(void)setGf_size:(CGSize)gf_size

{

    CGRect rect = self.frame;

    rect.size = gf_size;

    self.frame = rect;

}

-(CGFloat)gf_height

{

    return self.frame.size.height;

}

-(void)setGf_height:(CGFloat)gf_height

{

    CGRect rect = self.frame;

    rect.size.height = gf_height;

    self.frame = rect;

}

-(CGFloat)gf_width

{

    return self.frame.size.width;

}

-(void)setGf_width:(CGFloat)gf_width

{

    CGRect rect = self.frame;

    rect.size.width = gf_width;

    self.frame = rect;

}

-(CGFloat)gf_x

{

    return self.frame.origin.x;

}

-(void)setGf_x:(CGFloat)gf_x

{

    CGRect rect = self.frame;

    rect.origin.x = gf_x;

    self.frame = rect;

}

-(CGFloat)gf_y

{

    return self.frame.origin.y;

}

-(void)setGf_y:(CGFloat)gf_y

{

    CGRect rect = self.frame;

    rect.origin.y = gf_y;

    self.frame = rect;

}

-(CGFloat)gf_centerX

{

    return self.center.x;

}

-(void)setGf_centerX:(CGFloat)gf_centerX

{

    CGPoint point = self.center;

    point.x = gf_centerX;

    self.center = point;

}

-(CGFloat)gf_centerY

{

    return self.center.y;

}

-(void)setGf_centerY:(CGFloat)gf_centerY

{

    CGPoint point = self.center;

    point.y = gf_centerY;

    self.center = point;

}

@end



创建自定义GFTitleButton继承于UIButton,在GFTitleButton.m里

#import "GFTitleButton.h"

@implementation GFTitleButton

-(instancetype)initWithFrame:(CGRect)frame{

    

    if (self = [super initWithFrame:frame]) {

        [self setTitleColor:[UIColor darkGrayColor] forState:UIControlStateNormal];

        [self setTitleColor:[UIColor redColor] forState:UIControlStateSelected];

    }

    

    return self;

}

@end



在相应Controller中

#import "ViewController.h"

#import "UIView+SetMyView.h"

#import "GFTitleButton.h"

@interface ViewController ()<UIScrollViewDelegate>

{

    UIScrollView* myScrollView;

    UIView *titleView;//标题栏

    GFTitleButton* selectedTitleButton;//当前选中的按钮

    UIView *indicatorView;//底部指示器

}

@end

@implementation ViewController

- (void)viewDidLoad {

    [super viewDidLoad];

    

    [self setUpChildViewControllers];

    

    [self setUpScrollView];

    

    [self setUpTitleView];

}

//设置子控制器

-(void)setUpChildViewControllers{

    //全部 控制器

    UIViewController* allVC = [UIViewController new];

    allVC.view.backgroundColor = [UIColor redColor];

    [self addChildViewController:allVC];

    //视频 控制器

    UIViewController* videoVC = [UIViewController new];

    videoVC.view.backgroundColor = [UIColor orangeColor];

    [self addChildViewController:videoVC];

    //声音 控制器

    UIViewController* soundVC = [UIViewController new];

    soundVC.view.backgroundColor = [UIColor yellowColor];

    [self addChildViewController:soundVC];

    //图片 控制器

    UIViewController* picVC = [UIViewController new];

    picVC.view.backgroundColor = [UIColor greenColor];

    [self addChildViewController:picVC];

    //段子 控制器

    UIViewController* jokeVC = [UIViewController new];

    jokeVC.view.backgroundColor = [UIColor blueColor];

    [self addChildViewController:jokeVC];

}

//设置scrollView

-(void)setUpScrollView{

    

    myScrollView = [[UIScrollView alloc] init];

    myScrollView.backgroundColor = [UIColor purpleColor];

    

    myScrollView.delegate = self;

    myScrollView.frame = self.view.bounds;

    myScrollView.pagingEnabled = YES;

    myScrollView.showsVerticalScrollIndicator = NO;

    myScrollView.showsHorizontalScrollIndicator = NO;

    [self.view addSubview:myScrollView];

    

    myScrollView.contentSize = CGSizeMake(self.view.gf_width * self.childViewControllers.count, 0);

}

//添加标题栏titleView

-(void)setUpTitleView{

    

    titleView = [[UIView alloc] init];

    titleView.backgroundColor = [[UIColor whiteColor]colorWithAlphaComponent:0.8];

    titleView.frame = CGRectMake(0, 64 , self.view.gf_width, 35);

    [self.view addSubview:titleView];

    

    NSArray *titles = @[@"全部",@"视频",@"声音",@"图片",@"段子"];

    NSInteger count = titles.count;

    

    CGFloat titleButtonW = titleView.gf_width / count;

    CGFloat titleButtonH = titleView.gf_height;

    

    for (NSInteger i = 0;i < count; i++) {

        

        GFTitleButton* titleButton = [GFTitleButton buttonWithType:UIButtonTypeCustom];

        

        titleButton.tag = i; //绑定tag

        [titleButton addTarget:self action:@selector(titelClick:) forControlEvents:UIControlEventTouchUpInside];

        [titleButton setTitle:titles[i] forState:UIControlStateNormal];

        CGFloat titleX = i * titleButtonW;

        titleButton.frame = CGRectMake(titleX, 0, titleButtonW, titleButtonH);

        

        [titleView addSubview:titleButton];

    }

    //第一个按钮

    GFTitleButton *firstTitleButton = titleView.subviews.firstObject;

    //底部指示器

    indicatorView = [[UIView alloc]init];

    indicatorView.backgroundColor = [firstTitleButton titleColorForState:UIControlStateSelected];

    

    indicatorView.gf_height = 2;

    indicatorView.gf_y = titleView.gf_height - indicatorView.gf_height;

    

    [titleView addSubview:indicatorView];

    

    [firstTitleButton.titleLabel sizeToFit];

    indicatorView.gf_width = firstTitleButton.titleLabel.gf_width;

    indicatorView.gf_centerX = firstTitleButton.gf_centerX;

    //默认选中第一个按钮

    [self scrollViewDidEndScrollingAnimation:myScrollView];

}

//标题栏按钮点击

-(void)titelClick:(GFTitleButton *)sender

{

    selectedTitleButton.selected = NO;

    sender.selected = YES;

    selectedTitleButton = sender;

    

    //指示器

    [UIView animateWithDuration:0.25 animations:^{

        

        indicatorView.gf_width = sender.titleLabel.gf_width;

        indicatorView.gf_centerX = sender.gf_centerX;

    }];

    

    //让myScrollView滚动

    CGPoint offset = myScrollView.contentOffset;

    offset.x = myScrollView.gf_width * sender.tag;

    [myScrollView setContentOffset:offset animated:YES];

}

#pragma mark - UIScrollViewDelegate

//滚动完毕就会调用(不是人为拖拽scrollView导致滚动完毕,才会调用这个方法)

-(void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView{

    

    [self jumpToChildViewController];

}

//跳转到相应的控制器

-(void)jumpToChildViewController{

    

    NSInteger index = myScrollView.contentOffset.x / myScrollView.gf_width;

    //取出子控制器

    UIViewController *childVc = self.childViewControllers[index];

    

    if (childVc.view.superview) {

        return;//如果这个子控制器已经添加过了,就直接返回

    }

    childVc.view.frame = CGRectMake(index * myScrollView.gf_width, 0, myScrollView.gf_width, myScrollView.gf_height);

    [myScrollView addSubview:childVc.view];

}

//滚动完毕就会调用(如果是人为拖拽scrollView导致滚动完毕,才会调用这个方法)

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{

    

    NSInteger index = scrollView.contentOffset.x / scrollView.gf_width;

    GFTitleButton *titleButton = titleView.subviews[index];

    [self titelClick:titleButton];

[self jumpToChildViewController];

}

@end