ios 引导页

目标功能

  1. 能够快速实现普通引导页功能.
  2. 提供自定义view的加载模式.
  3. 提供特定样式的加载模式,只需要配置即可.

设计思路

  1. 创建一个类SMIntroductionView,继承于UIView.
  2. 在SMIntroductionView.h中定义类型用来区分.定义协议,用来回调.定义参数,用来配置.
  3. 在SMIntroductionView.m中定义一个ScrollView容器,用来装载可以滑动的view,实现ScrollView的协议回调,用来监听滑动位置,从而做出相应的变化.

SMIntroductionView.h

定义类型

typedef NS_ENUM(NSInteger,SMIntroductionType) {
    SMIntroductionTypeByYou=0,//加载自定义view
    SMIntroductionTypeAutoFir//自动填充内容模式1,该模式下就不要再设置isNeedBgColor的值了,需要为YES,格式为IntroductionViewFir,只需要替换imgFir文件夹中的图片即可,图片名字需要保持相同
};

定义SMIntroductionDelegate协议

@protocol SMIntroductionDelegate<NSObject>
@optional
-(NSInteger)SMIntroductionGetTotalNum:(SMIntroductionView*)view;//得到总共的引导页页数,自定义模式下必须实现

-(UIView*)SMIntroduction:(SMIntroductionView*)view getView:(NSInteger)index;//根据下标获取对应的view,自定义模式下必须实现

-(UIColor*)SMIntroduction:(SMIntroductionView*)view getColorWithIndex:(NSInteger)index;//根据下标获取对应的背景颜色,自定义模式下如果需要背景颜色渐变,必须实现

-(void)SMIntroductionGo:(SMIntroductionView*)view;//当SMIntroductionTypeAutoFir模式时,点击开始体验的回调

-(void)SMIntroduction:(SMIntroductionView*)view selectIndex:(NSInteger)index;//滑动到某一个界面时候的回调

@end

定义参数

@property(nonatomic,weak)id<SMIntroductionDelegate> delegate;

@property(nonatomic,assign)SMIntroductionType typeModel;//设置类型,默认为SMIntroductionTypeByYou自定义模式

@property(nonatomic,assign)BOOL isNeedBgColor;//是否需要背景颜色的渐变效果,如果需要显示在控件中的view背景必须为透明颜色

@property(nonatomic,strong)UIPageControl * pageControl;//指示器,自定义模式可以自己设置指示器颜色,固定模式就不要设置了

@property(nonatomic,assign)int totalNum;

@property (assign, nonatomic) BOOL needPassButton;//是否需要跳过按钮

提供开始方法

-(void)load;

SMIntroductionView.m

初始化

-(instancetype)initWithFrame:(CGRect)frame{
    self=[super initWithFrame:frame];
    [self SMIntroductionInit];
    return self;
}

-(void)awakeFromNib{
    [super awakeFromNib];
    [self SMIntroductionInit];
}

-(void)SMIntroductionInit{
    //scrollView初始化
    self.scrollView=[[UIScrollView alloc]init];
    self.scrollView.pagingEnabled=YES;
    self.scrollView.delegate=self;
    self.scrollView.showsHorizontalScrollIndicator=NO;
    self.scrollView.showsVerticalScrollIndicator=NO;
    self.scrollView.bounces=NO;
    [self addSubview:self.scrollView];
    
    self.pageControl=[[UIPageControl alloc]init];
    self.bgColors=[[NSMutableArray alloc]init];
    self.childViews=[[NSMutableArray alloc]init];
    [self addSubview:self.pageControl];
    
    [self.endBtn addTarget:self action:@selector(passBtn:) forControlEvents:UIControlEventTouchUpInside];
    [self bringSubviewToFront:_endBtn];
}

布局scrollView

-(void)layoutSubviews{
    self.w=self.frame.size.width;
    self.h=self.frame.size.height;
    self.scrollView.frame=CGRectMake(0, 0, self.w, self.h);
    for (int i=0; i<self.childViews.count; i++) {
        UIView * view=self.childViews[i];
        view.frame=CGRectMake(i*self.w, 0, self.w, self.h);
    }
    [self.scrollView setContentSize:CGSizeMake(self.w*self.childViews.count, self.h)];
    self.pageControl.frame=CGRectMake(0, self.h-40, self.w, 20);
    self.pageControl.currentPageIndicatorTintColor=[UIColor whiteColor];
    self.pageControl.userInteractionEnabled = 0;
}

实现UIScrollView的协议方法

-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
    CGPoint  offPoint=scrollView.contentOffset;
    int pointX=offPoint.x;
    self.indexPage=pointX/self.w;
    if (pointX%self.w>=0.5*self.w) {
        self.indexPage+=1;
    }
    self.pageControl.currentPage=self.indexPage;
    
    if (self.isNeedBgColor&&self.bgColors.count>2) {
        [self setEndStartColor:pointX];
        
        
        NSDictionary *colorDicFir= [self getRGBDictionaryByColor:self.firColor];
        float r_f = [colorDicFir[@"R"] floatValue] * 255;
        float g_f = [colorDicFir[@"G"] floatValue] * 255;
        float b_f = [colorDicFir[@"B"] floatValue] * 255;
        
        NSDictionary *colorDicSec= [self getRGBDictionaryByColor:self.secColor];
        float r_s = [colorDicSec[@"R"] floatValue] * 255;
        float g_s = [colorDicSec[@"G"] floatValue] * 255;
        float b_s = [colorDicSec[@"B"] floatValue] * 255;
        
        
        
        float pointRela=offPoint.x-pointX/self.w*self.w;
        float percent=pointRela/self.w;
        
        float r_r=(r_f+(r_s-r_f)*percent)/255.0;
        float g_r=(g_f+(g_s-g_f)*percent)/255.0;
        float b_r=(b_f+(b_s-b_f)*percent)/255.0;
        
        self.nowColor=[UIColor colorWithRed:r_r green:g_r blue:b_r alpha:1];
        self.scrollView.backgroundColor=self.nowColor;
    }
}

-(void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView{
    if (self.delegate&&[self.delegate respondsToSelector:@selector(SMIntroduction:selectIndex:)]) {
        [self.delegate SMIntroduction:self selectIndex:self.indexPage];
        
    }
    if (scrollView.contentOffset.x == 4 * SCREEN_W) {
        [self.passButton removeFromSuperview];
    }
    else{
        [self addSubview:_passButton];
    }
    if (scrollView == self.scrollView) {
        NSLog(@"%f",scrollView.contentOffset.x);

    }
}

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    if (self.delegate&&[self.delegate respondsToSelector:@selector(SMIntroduction:selectIndex:)]) {
        [self.delegate SMIntroduction:self selectIndex:self.indexPage];
        NSLog(@"%d",self.indexPage);
        if (self.indexPage == self.childViews.count - 1) {
            self.passButton.hidden = 1;
        }
        else
        {
            self.passButton.hidden = 0;
        }
    }
    
}

一些颜色渐变辅助性的方法

#pragma mark 获取rgb值
- (NSDictionary *)getRGBDictionaryByColor:(UIColor *)originColor
{
    CGFloat r=0,g=0,b=0,a=0;
    if ([self respondsToSelector:@selector(getRed:green:blue:alpha:)]) {
        [originColor getRed:&r green:&g blue:&b alpha:&a];
    }else {
        const CGFloat *components = CGColorGetComponents(originColor.CGColor);
        r = components[0];
        g = components[1];
        b = components[2];
        a = components[3];
    }
    return @{@"R":@(r),@"G":@(g),@"B":@(b),@"A":@(a)};
}

#pragma mark 设置滑动首尾颜色值
-(void)setEndStartColor:(int)pointX{
    
    int index=pointX/self.w;
    if (index==self.childViews.count-1) {
        self.firColor=self.bgColors[index];
    }else{
        self.firColor=self.bgColors[index];
        self.secColor=self.bgColors[index+1];
    }
    
//    if (pointX<self.w) {
//        self.firColor=self.bgColors[0];
//        self.secColor=self.bgColors[1];
//    }else if (self.w<=pointX&&pointX<self.w*2){
//        self.firColor=self.bgColors[1];
//        self.secColor=self.bgColors[2];
//    }else if (self.w*2<=pointX&&pointX<self.w*3){
//        self.firColor=self.bgColors[2];
//        self.secColor=self.bgColors[3];
//    }else if (pointX==self.w*3){
//        self.firColor=self.bgColors[3];
//    }
}

//判断滑动的方向0--左;1--右
-(int)getOritation:(int)pointX{
    int oritation=0;
    if (pointX>self.lastX) {
        oritation=1;
    }
    self.lastX=pointX;
    return oritation;
}

类辅助方法

#pragma mark 点击进入
//点击最后一页开始按钮事件
-(void)goClick:(id)sender{
    if (self.delegate&&[self.delegate respondsToSelector:@selector(SMIntroductionGo:) ]) {
        [self.delegate SMIntroductionGo:self];
    }
    [self removeFromSuperview];
}

//开始加载方法
-(void)load{
    [self createPassButton];

    if (self.typeModel==SMIntroductionTypeByYou) {
        if (self.delegate&&[self.delegate respondsToSelector:@selector(SMIntroductionGetTotalNum:)]) {
            self.totalNum=(int)[self.delegate SMIntroductionGetTotalNum:self];
        }
        self.pageControl.numberOfPages=self.totalNum;
        if (self.delegate&&[self.delegate respondsToSelector:@selector(SMIntroduction:getView:)]) {
            for (int i=0; i<self.totalNum; i++) {
                UIView * view=[self.delegate SMIntroduction:self getView:i];
                [self.childViews addObject:view];
                [self.scrollView addSubview:view];
            }
        }
        
        if (self.isNeedBgColor&&self.delegate&&[self.delegate respondsToSelector:@selector(SMIntroduction:getColorWithIndex:)]) {
            self.bgColors=[[NSMutableArray alloc]init];
            for (int i=0; i<self.totalNum; i++) {
                [self.bgColors addObject:[self.delegate SMIntroduction:self getColorWithIndex:i]];
            }
            
            self.scrollView.backgroundColor=self.bgColors[0];
        }
    }else if (self.typeModel==SMIntroductionTypeAutoFir){
        self.pageControl.numberOfPages=4;
        self.isNeedBgColor=YES;
        NSArray * imgNames=@[@"second",@"first",@"third",@"four"];
        for (int i=0; i<4; i++) {
            UIView * view=[self getViewFromLib:@"IntroductionViewFir" withOwer:self];
            view.backgroundColor=[UIColor clearColor];
            [self.childViews addObject:view];
            [self.scrollView addSubview:view];
            UIImageView * imgTop=[view viewWithTag:1];
            NSString * png=[NSString stringWithFormat:@"%@%@%@",@"guide_",imgNames[i],@"_top_image.png"];
            imgTop.image=[UIImage imageNamed:png];
            UIImageView * imgCenter=[view viewWithTag:2];
            imgCenter.image=[UIImage imageNamed:[NSString stringWithFormat:@"%@%@%@",@"guide_",imgNames[i],@"_middle_image.png"]];
            UIImageView * imgBottom=[view viewWithTag:3];
            imgBottom.image=[UIImage imageNamed:[NSString stringWithFormat:@"%@%@%@",@"guide_",imgNames[i],@"_bottom_person.png"]];
            UIButton * btn=[view viewWithTag:4];
            if (i!=3) {
                btn.hidden=YES;
            }

            [btn addTarget:self action:@selector(goClick:) forControlEvents:UIControlEventTouchUpInside];
        }
        
        
        
        UIColor * firColor=[UIColor colorWithRed:0.5922 green:0.7529 blue:0.3373 alpha:1.0];
        UIColor * secColor=[UIColor colorWithRed:0.949 green:0.7059 blue:0.2941 alpha:1.0];
        UIColor * thirdColor=[UIColor colorWithRed:0.9373 green:0.5725 blue:0.6588 alpha:1.0];
        UIColor * fourthColor=[UIColor colorWithRed:0.6392 green:0.6 blue:0.8275 alpha:1.0];
        
        self.bgColors=[[NSMutableArray alloc]initWithObjects:firColor,secColor,thirdColor,fourthColor, nil];
        self.scrollView.backgroundColor=self.bgColors[0];
        
    }
    
}

//创建跳过按钮
-(void)createPassButton
{
    _passButton = [[UIButton alloc]init];
    _passButton.frame = CGRectMake(SCREEN_W - 50 - 15, 25, 50, 25);
    _passButton.titleLabel.adjustsFontSizeToFitWidth = 1;
    [_passButton setTitle:@"跳过" forState:UIControlStateNormal];
    [_passButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    [_passButton setFont:[UIFont systemFontOfSize:13]];
    _passButton.layer.cornerRadius = 3;
    _passButton.layer.masksToBounds = 1;
    _passButton.layer.borderWidth = 1;
    _passButton.layer.borderColor = [UIColor whiteColor].CGColor;
    [_passButton addTarget:self action:@selector(passBtn:) forControlEvents:UIControlEventTouchUpInside];
    [self addSubview:_passButton];
}

//跳过按钮点击事件
-(IBAction)passBtn:(id)sender
{
    if (self.delegate&&[self.delegate respondsToSelector:@selector(SMIntroductionGo:) ]) {
        [self.delegate SMIntroductionGo:self];
    }
    [self removeFromSuperview];
}

//从xib加载view
-(UIView*)getViewFromLib:(NSString*)libName withOwer:(id)owner{
    return [[[NSBundle mainBundle] loadNibNamed:libName owner:owner options:nil] lastObject];
}

使用方法

xib中设置好布局,并将Class改为SMIntroductionView

xib设置.png

关联到你的Controller中

@property (weak, nonatomic) IBOutlet SMIntroductionView *introductionView;

实现各种协议

//固定模式1下点击开始按钮回调
-(void)SMIntroductionGo:(SMIntroductionView *)view{
    [self topMoreClick];
}
//当前选中的页面
-(void)SMIntroduction:(SMIntroductionView *)view selectIndex:(NSInteger)index{
    
}
//自定义模式下得到页面总数,自定义模式必须实现
-(NSInteger)SMIntroductionGetTotalNum:(SMIntroductionView *)view{
    return 4;
}

//自定义模式下得到每页的view
-(UIView*)SMIntroduction:(SMIntroductionView *)view getView:(NSInteger)index{
    UILabel * label=[[UILabel alloc]init];
    label.text=[NSString stringWithFormat:@"这是第%ld页",(long)index];
    
    return label;
}
//自定义模式下,需要背景渐变功能的情况下必须实现
-(UIColor*)SMIntroduction:(SMIntroductionView *)view getColorWithIndex:(NSInteger)index{
    if (index==0) {
        return [UIColor redColor];
    }else if (index==1){
        return [UIColor greenColor];
    }else if (index==2){
        return [UIColor blueColor];
    }else {
        return [UIColor brownColor];
    }
}

进行简单的设置并开始加载

self.introductionView.delegate=self;//设置协议
    self.introductionView.typeModel=SMIntroductionTypeAutoFir;//设置展示类型
//    self.introductionView.typeModel=SMIntroductionTypeByYou;
//    self.introductionView.isNeedBgColor=YES;//设置是否需要背景颜色渐变
    [self.introductionView load];//开始加载

效果图

自定义界面
样式1

源码地址

https://github.com/StoneMover/SMLeadPage.git

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,045评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,114评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,120评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,902评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,828评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,132评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,590评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,258评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,408评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,335评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,385评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,068评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,660评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,747评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,967评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,406评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,970评论 2 341

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,279评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,982评论 4 60
  • 前两天闺蜜聚会,思姜很气愤的向一众闺蜜吐槽,自己的老公实在是不解风情到了人神共愤的地步,引得另两个小姐妹也是义愤填...
    黎老猫阅读 1,707评论 0 1
  • 名门望族心自远, 才名京华第一人。 纳兰心事几人知, 情深人间几多愁。
    空城锦阅读 225评论 0 0
  • 刚读完胡竹峰先生的《旧味》 ,掩卷而思,竟无太多记忆。进来越发懒怠了,现在如此萎靡。罪过,罪过。只好从后往前,大概...
    日出而息阅读 947评论 0 1