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
#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
#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