自定义轮播图和容视图控制器

一,轮播图

LCarouselUtils.h

#import <UIKit/UIKit.h>
@class LCarouselUtils;
@protocol LCarouselUtilsDelegate <NSObject>
@required
-(void)lcarouselUtils:(LCarouselUtils*)lscrollView didSelectedPicturedItem:(NSInteger)item;
@end
@interface LCarouselUtils : UIView
@property(nonatomic,strong)UIScrollView * lscrollView;
@property(nonatomic,strong)UIPageControl* lpageControl;
@property(nonatomic,assign)id<LCarouselUtilsDelegate> delegate;
/**
 *  创建的轮图图片的个数
 */
@property(nonatomic,assign) NSUInteger itemNumber;

//展示方法
-(void)showLscrollViewWithNSArray:(NSArray *)picArray;
LCarouselUtils.m
#import "LCarouselUtils.h"
@interface LCarouselUtils()<UIScrollViewDelegate>
@property(nonatomic,assign) CGRect ViewFrame;
@property(nonatomic,strong) NSArray * PicArray;
@end

@implementation LCarouselUtils

-(instancetype)initWithFrame:(CGRect)frame{
    if(self = [super initWithFrame:frame]){
        [self setScrollViewAndPageControl];
        _ViewFrame = frame;
        self.backgroundColor =[UIColor yellowColor];
    }
    return self;
}

/**
 *  创建scrollView和pageControl对象
 */
-(void)setScrollViewAndPageControl{
   //设置scrollView
    UIScrollView * myScrollView = [[UIScrollView alloc]initWithFrame:self.bounds];
    self.lscrollView = myScrollView;
    NSInteger ItemNum = self.itemNumber?self.itemNumber:3;//加入用户没有设置轮播图片的数量,就默认为三张.
    self.lscrollView.contentSize = CGSizeMake(self.frame.size.width *ItemNum, self.frame.size.height);
    NSLog(@"%@",NSStringFromCGSize(self.lscrollView.contentSize));
    //隐藏竖向条,显示横向条
    self.lscrollView.showsHorizontalScrollIndicator =YES;
    self.lscrollView.showsVerticalScrollIndicator =NO;
    self.lscrollView.pagingEnabled = YES;
    self.lscrollView.delegate = self;
    self.lscrollView.bounces =NO;
    [self addSubview:self.lscrollView];
    //设置pageControl
    UIPageControl * myPageControl = [[UIPageControl alloc]initWithFrame:CGRectMake(0, 0, 100, 30)];
    self.lpageControl = myPageControl;
    self.lpageControl.numberOfPages =ItemNum;
    self.lpageControl.currentPage = 0;
    self.lpageControl.center = CGPointMake(self.frame.size.width/2, self.frame.size.height*3/4);
    [self.lpageControl addTarget:self action:@selector(pageTurn:) forControlEvents:UIControlEventValueChanged];
    [self addSubview:self.lpageControl];
    [self bringSubviewToFront:self.lpageControl];
}
#pragma mark  --触发方法
//pageControl
-(void)pageTurn:(UIPageControl *)pageControl{
    double offset =pageControl.currentPage*(_ViewFrame.size.width);
    //  初始化当前视图
    self.lscrollView.contentOffset =CGPointMake(offset, 0);
}
//singleRecognizer(手势触发方法)
-(void)SingleTap:(UITapGestureRecognizer *)recognizer{
    UIImageView * imageView =(UIImageView *)recognizer.view;
    NSInteger item =imageView.tag;
    if([self.delegate respondsToSelector:@selector(lcarouselUtils:didSelectedPicturedItem:)]){
        [self.delegate lcarouselUtils:self didSelectedPicturedItem:item];//用代理实现触发图片时方法回调
    }
}
#pragma mark  --展示轮播图
-(void)showLscrollViewWithNSArray:(NSArray *)picArray{
    self.PicArray =picArray;
    NSUInteger count =picArray.count;
    for (int i = 0;i<count; i++) {
        UIImageView * imageView = [[UIImageView alloc]initWithFrame:CGRectMake(i*self.frame.size.width, 0, _ViewFrame.size.width, _ViewFrame.size.height)];
        imageView.image=[UIImage imageNamed:picArray[i]];
        imageView.userInteractionEnabled =YES;
        imageView.tag =i;
        imageView.contentMode = UIViewContentModeScaleToFill;
        UITapGestureRecognizer * singleRecognizer = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(SingleTap:)];
        singleRecognizer.numberOfTapsRequired = 1;
        [self.lscrollView addSubview:imageView];
        [imageView addGestureRecognizer:singleRecognizer];
    }
    UIWindow * window = [UIApplication sharedApplication].keyWindow;
    if (!window) {
        window =[[UIApplication sharedApplication].windows objectAtIndex:0];
    }
    UIView * view = [window.subviews objectAtIndex:0];
    [view addSubview:self];
}
#pragma mark  --scrollView的代理方法
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
    int index = fabs(self.lscrollView.contentOffset.x)/_ViewFrame.size.width;
    self.lpageControl.currentPage =index;
}

效果图:


总结:

轮播图中的两个重要的方法

#pragma mark  --触发方法
//pageControl
-(void)pageTurn:(UIPageControl *)pageControl{
    double offset =pageControl.currentPage*(_ViewFrame.size.width);
    //  初始化当前视图
    self.lscrollView.contentOffset =CGPointMake(offset, 0);//设置偏移量
}


#pragma mark  --scrollView的代理方法
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
    int index = fabs(self.lscrollView.contentOffset.x)/_ViewFrame.size.width;
    self.lpageControl.currentPage =index;//设置当前page
}
仅仅是一个简单的demo,仍可以有很多的拓展方法.比如加定时器实现无线轮播,给没张图片添加标题等等
二,容视图控制器

.h文件

#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end

.m文件

#import "ViewController.h"
#import "FirstViewController.h"
#import "SecondViewController.h"
#import "ThirdViewController.h"
#import "FourViewController.h"
#import "FivewViewController.h"
#import "UIView+GCSExtension.h"
@interface ViewController ()<UIScrollViewDelegate>
/**
 *  标签栏底部的红色指示器
 */
@property(nonatomic,weak) UIView * indicatorView;
/**
 *  当前选中的按钮
 */
@property(nonatomic,weak) UIButton * selectedButton;
/**
 *  顶部的所有标签
 */
@property(nonatomic,weak) UIView * titlesView;
/**
 *  顶部所有内容
 */
@property(nonatomic,weak) UIScrollView * contentView;
/**
 *  菜单的数据源
 */
@property(nonatomic,strong) NSArray * sourceArray;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //第一步:添加子控制器
    [self setupChildVces];
    //第二步:设置标题栏
    [self setupTitleView];
    //第三步:设置底部的scrollView
    [self setupContentView];
    // Do any additional setup after loading the view, typically from a nib.
}
#pragma mark --添加子控制器
-(void)setupChildVces{
    FirstViewController * firstVC = [[FirstViewController alloc]init];
    [self addChildViewController:firstVC];//将ViewController作为容视图控制器
    
    SecondViewController * secondVC = [[SecondViewController alloc]init];
    [self addChildViewController:secondVC];
    
    ThirdViewController * thirdVC =[[ThirdViewController alloc]init];
    [self addChildViewController:thirdVC];
    
    FourViewController * fourVC =[[FourViewController alloc]init];
    [self addChildViewController:fourVC];
    
    FivewViewController * fiveVC =[[FivewViewController alloc]init];
    [self addChildViewController:fiveVC];
}

#pragma mark  --设置标题栏
-(void)setupTitleView{
   //标签栏整体
    UIView * titlesView = [[UIView alloc] init];
    titlesView.backgroundColor =[[UIColor yellowColor] colorWithAlphaComponent:0.7];
    titlesView.width =self.view.width;
    titlesView.height = 35;
    titlesView.y =20;
    [self.view addSubview:titlesView];
    self.titlesView =titlesView;
    //底部红色指示器
    UIView * indicatorView = [[UIView alloc]init];
    indicatorView.backgroundColor = [[UIColor redColor] colorWithAlphaComponent:1];
    indicatorView.height = 2;
    indicatorView.tag = -1;
    indicatorView.y =titlesView.height-indicatorView.height;
    self.indicatorView = indicatorView;
    //内部的子标签
    NSArray * titles =@[@"全部",@"视频",@"声音",@"图片",@"段子"];
    CGFloat width =titlesView.width /titles.count;
    CGFloat height =titlesView.height;
    self.sourceArray =titles;
    /**
     *  循环创建button按钮
     */
    for(NSInteger i = 0;i<titles.count;i++){
        UIButton * button = [[UIButton alloc]init];
        button.tag = i;
        button.height = height;
        button.width = width;
        button.x =i * width;
        [button setTitle:titles[i] forState:UIControlStateNormal];
        [button setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
        [button setTitleColor:[UIColor redColor] forState:UIControlStateDisabled];
        button.titleLabel.font = [UIFont systemFontOfSize:14];
        [button addTarget:self action:@selector(titleclick:) forControlEvents:UIControlEventTouchUpInside];
        [titlesView addSubview:button];
        
        //默认点击第一个按钮
        if(i==0){
            button.enabled =NO;
            self.selectedButton=button;
            //button 内部label根据文字的内容计算
            [button.titleLabel sizeToFit];
            //在创建button的循环方法中,对indicatorView进行宽度和X坐标的设置
            self.indicatorView.width =button.titleLabel.width;
            self.indicatorView.centerX =button.centerX;
        }
    }
    [titlesView addSubview:indicatorView];
}
#pragma mark  --设置底部的scrollView
-(void)setupContentView{
    //不要自动调整inset
    self.automaticallyAdjustsScrollViewInsets =NO;
    UIScrollView * contentView =[[UIScrollView alloc]init];
    contentView.frame =CGRectMake(0, 55, [UIScreen mainScreen].bounds.size.width,[UIScreen mainScreen].bounds.size.height-55);
    contentView.delegate = self;
    contentView.pagingEnabled = YES;
    [self.view insertSubview:contentView atIndex:0];//使用[self.view addSubview:contentView];效果一样
    contentView.contentSize = CGSizeMake(contentView.width * self.childViewControllers.count, 0);
    self.contentView = contentView;
    //添加第一个控制器view
    for (int i = 0;i<self.sourceArray.count; i++) {
        //取出子控制器
        UIViewController *vc = self.childViewControllers[i];
        vc.view.x =self.view.width*i;
        vc.view.y = 0;//设置控制器view的y值为0 默认是20;
        vc.view.height = self.contentView.bounds.size.height;//设置控制器view的height值为整个屏幕的高度
        [self.contentView addSubview:vc.view];
    }
}

#pragma mark  --button的触发方法
-(void)titleclick:(UIButton *)button{
    //修改按钮状态
    self.selectedButton.enabled = YES;
    button.enabled = NO;
    self.selectedButton = button;
    //动画
    [UIView animateWithDuration:0.25 animations:^{
        self.indicatorView.width =button.titleLabel.width;
        self.indicatorView.centerX = button.centerX;
    }];
    
    //滚动
    CGPoint offset = self.contentView.contentOffset;
    offset.x =button.tag * self.contentView.width;
    [self.contentView setContentOffset:offset animated:YES];
}
#pragma mark  --scrollView的代理方法
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView{
    //当前索引
    NSInteger index = scrollView.contentOffset.x / scrollView.width;
    //取出子控制器
    UIViewController *vc = self.childViewControllers[index];
    vc.view.x = scrollView.contentOffset.x;
    vc.view.y = 0;//设置控制器view的y值为0 默认是20;
    vc.view.height = scrollView.height;//设置控制器view的height值为整个屏幕的高度
    [scrollView addSubview:vc.view];
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    [self scrollViewDidEndScrollingAnimation:scrollView];
    //点击按钮
    NSInteger index = scrollView.contentOffset.x / scrollView.width;
    [self titleclick:self.titlesView.subviews[index]];
}

效果图:

自定义轮播图和容视图控制器_第1张图片自定义轮播图和容视图控制器_第2张图片

总结:类比轮播图来实现,只不过,pageControl变成了自己封装的菜单栏.

比较重要的方法实现.(实现方法很多,仅供参考)

#pragma mark  --button的触发方法
-(void)titleclick:(UIButton *)button{
    //修改按钮状态
    self.selectedButton.enabled = YES;
    button.enabled = NO;
    self.selectedButton = button;
    //动画
    [UIView animateWithDuration:0.25 animations:^{
        self.indicatorView.width =button.titleLabel.width;
        self.indicatorView.centerX = button.centerX;
    }];
    
    //滚动
    CGPoint offset = self.contentView.contentOffset;
    offset.x =button.tag * self.contentView.width;
    [self.contentView setContentOffset:offset animated:YES];
}
#pragma mark  --scrollView的代理方法
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView{
    //当前索引
    NSInteger index = scrollView.contentOffset.x / scrollView.width;
    //取出子控制器
    UIViewController *vc = self.childViewControllers[index];
    vc.view.x = scrollView.contentOffset.x;
    vc.view.y = 0;//设置控制器view的y值为0 默认是20;
    vc.view.height = scrollView.height;//设置控制器view的height值为整个屏幕的高度
    [scrollView addSubview:vc.view];
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    [self scrollViewDidEndScrollingAnimation:scrollView];
    //点击按钮
    NSInteger index = scrollView.contentOffset.x / scrollView.width;
    [self titleclick:self.titlesView.subviews[index]];
}

你可能感兴趣的:(自定义轮播图和容视图控制器)