IOS之[UIPageControl:引导页]

强颜欢笑 提交于 2019-12-06 13:49:30

1.UIPageConrol API

@property(nonatomic) NSInteger numberOfPages   //>>页数
@property(nonatomic) NSInteger currentPage     //>>当前页

@property(nonatomic) BOOL hidesForSinglePage   //>>单页是否显示PageControl

@property(nullable, nonatomic,strong) UIColor *pageIndicatorTintColor        //颜色
@property(nullable, nonatomic,strong) UIColor *currentPageIndicatorTintColor //当前页的颜色

2.引导页制作

导航页

动画效果+代码参照:http://code4app.com/ios/ZWIntroductionViewController/54e1cb82933bf0212f8b5fbe

所需控件:UIScrollView + UIPageControl

需要一下几个步骤

1.初始化自定义ViewController

2.添加背景图

3.添加UIScrollView

4.添加PageControl

5.添加前景图

6.实现UIScrollViewDelegate

2.1初始化ViewController
@interface IntroductionViewController : UIViewController

 #pragma mark - Property
@property (nonatomic, strong) NSArray *coverImageNames;      //前景图
@property (nonatomic, strong) NSArray *backgroundImageNames; //背景图

 #pragma mark - init
- (id)initWithCoverImageNames:(NSArray*)coverNames backgroundImageNames:(NSArray*)bgNames;

@end

@implementation IntroductionViewController

- (id)initWithCoverImageNames:(NSArray *)coverNames backgroundImageNames:(NSArray *)bgNames
{
    if (self = [super init]) {
        self.coverImageNames = coverNames;
        self.backgroundImageNames = bgNames;
    }
    return self;
}

@end
2.2添加背景图

背景图是在UIView上叠加起来添加SubView,所以是从下往上叠加

通过设置透明度来显示不同图片

-(void)addBackgroundViews{
    
    //遍历背景图数组
    [[[self.backgroundViews reverseObjectEnumerator] allObjects] enumerateObjectsUsingBlock:^(UIView obj, NSUInteger idx, BOOL *stop) {
        [self.view addSubview:obj];
    }];
}
-(NSArray *)backgroundViews{
    
    if (_backgroundViews) {
        return _backgroundViews;
    }
    
    //遍历图片名来加载图片,将UIImageView存放在属性数组中
    NSMutableArray *tempViews = [NSMutableArray new];
    [_backgroundImageNames enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        
        UIImageView *imageView = [self loadImage:obj];
        [tempViews addObject:imageView];
        
    }];
    
    _backgroundViews = tempViews;
    return _backgroundViews;
}
-(UIImageView *)loadImage:(NSString *)imageName{
    
    UIImage *image = [UIImage imageNamed:imageName];
    UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
    imageView.frame = self.view.frame;
    
    return imageView;
}
2.3添加UIScrollView
- (void)addScrollView{

    self.scrollView = [[UIScrollView alloc] initWithFrame:self.view.frame];
    
    self.scrollView.delegate = self;
    self.scrollView.pagingEnabled = YES;  //允许分页
    self.scrollView.showsHorizontalScrollIndicator = NO;
    self.scrollView.showsVerticalScrollIndicator = NO;
    self.scrollView.contentSize = [self contentSizeOfScrollView]; //内容Size
    
    [self.view addSubview:self.scrollView];
}

/**
 内容显示部分的Size
 content.size.with 必须大于 frame.size.width才能滑动
*/
- (CGSize)contentSizeOfScrollView
{
    return CGSizeMake(self.view.frame.size.width * self.numberOfPages, self.view.frame.size.height);
}

/**
 加载图片数
*/
-(NSInteger)numberOfPages{
    return [_coverImageNames count];
}
2.4添加UIPageControl
- (void)addPageControl{

    self.pageControl = [[UIPageControl alloc] initWithFrame:[self frameOfPageControl]];
    
    //pageControl颜色设定
    self.pageControl.pageIndicatorTintColor = [UIColor whiteColor];
    self.pageControl.currentPageIndicatorTintColor = [UIColor blueColor];

    self.pageControl.numberOfPages = self.numberOfPages;
    
    [self.view addSubview:self.pageControl];
}

/**
 PageControl位置及大小
*/
- (CGRect)frameOfPageControl{

    return CGRectMake(0, self.view.frame.size.height - 30, self.view.frame.size.width, 30);
}
2.5添加前景图
-(void)addCoverImageViews{

    //遍历前景图UIImageViews,将图片依次添加到ScrollView中,一个显示在屏幕中,两个显示在屏幕外
    __block CGFloat x = 0;
    [self.coverViews enumerateObjectsUsingBlock:^(UIView *obj, NSUInteger idx, BOOL *stop) {
        
        obj.frame = CGRectOffset(obj.frame, x, 0);
        x = x + obj.frame.size.width;
        
        [self.scrollView addSubview:obj];
    }];
}

/**
 加载前景图片到UIImageView中,并添加到属性数组中
*/
-(NSArray *)coverViews{

    if (_coverViews) {
        return _coverViews;
    }
    
    NSMutableArray *tempViews = [NSMutableArray new];
    [_coverImageNames enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
       
        UIImageView *imageView = [self loadImage:obj];
        [tempViews addObject:imageView];

    }];
    
    _coverViews = tempViews;
    return _coverViews;
}
2.6实现UIScrollViewDelegate
/**
 scrollView滚动时,就调用该方法。
 任何offset值改变都调用该方法。即滚动过程中,调用多次
 */
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{

    //偏移了几个屏幕的宽度0,1,2
    NSInteger index = scrollView.contentOffset.x/scrollView.frame.size.width;
    
    //透明度:1-(相对偏移量/屏幕宽度)
    CGFloat relativeOffsetX = scrollView.contentOffset.x - index*scrollView.frame.size.width; //相对偏移量
    CGFloat alpha = 1 - (relativeOffsetX/scrollView.frame.size.width);
    
    if ([self.backgroundViews count] > index) {
    
        UIView *view = [_backgroundViews objectAtIndex:index];
        view.alpha = alpha;
    }
    
    //分页控制器设定当前页
    self.pageControl.currentPage = scrollView.contentOffset.x/scrollView.frame.size.width;
}
2.7实现至末尾页继续滑动,显示主画面

.h文件中声明属性

typedef void (^DidSelectedEnter)();

@property (nonatomic, copy) DidSelectedEnter didSelectedEnter;

/**
 代理方法:滑动减速时调用
*/
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView
{
    if ([scrollView.panGestureRecognizer translationInView:scrollView.superview].x < 0) {
        if (![self hasNext:self.pageControl]) {
            [self enter:nil];
        }
    }
}

- (BOOL)hasNext:(UIPageControl*)pageControl
{
    return pageControl.numberOfPages > pageControl.currentPage + 1;
}

 #pragma mark - Action

- (void)enter:(id)object
{
    if (self.didSelectedEnter) {
        self.didSelectedEnter();
    }
}

/**
 ViewController消失时执行
*/
-(void)dealloc{

    void(^animations)() = ^(){
        self.view.alpha = 0;
    };
    
    __block UIView *view = self.view;
    void(^completion)(BOOL finished) = ^(BOOL finished){
        view = nil; //画面消失必须
    };
    
    [UIView animateWithDuration:0.4
                     animations:animations
                     completion:completion];
}

在AppDelegate中声明didSelectedEnter属性Block方法

//关闭导航页
    __weak AppDelegate *weakSelf = self;
    self.introVC.didSelectedEnter = ^(){
        weakSelf.introVC = nil;
    };

3.所有代码如下:

:fa-location-arrow:AppDelegate.m

@interface AppDelegate ()

@property (nonatomic, strong) IntroductionViewController *introVC;

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.window.backgroundColor = [UIColor whiteColor];
    ViewController *vc = [[ViewController alloc] init];
    self.window.rootViewController = vc;
    [_window makeKeyAndVisible];
    
    
    NSArray *coverImageNames = @[@"img_index_01txt", @"img_index_02txt", @"img_index_03txt"];
    NSArray *backgroundImageNames = @[@"img_index_01bg", @"img_index_02bg", @"img_index_03bg"];

    self.introVC = [[IntroductionViewController alloc] initWithCoverImageNames:coverImageNames backgroundImageNames:backgroundImageNames];
    
    [self.window addSubview:self.introVC.view];
    
    //关闭导航页
    __weak AppDelegate *weakSelf = self;
    self.introVC.didSelectedEnter = ^(){
        weakSelf.introVC = nil;
    };
    
    return YES;
}

@end

:fa-location-arrow:IntroductionViewController.h

 #import <UIKit/UIKit.h>

typedef void (^DidSelectedEnter)();

@interface IntroductionViewController : UIViewController

//block块(类似于代理)
@property (nonatomic, copy) DidSelectedEnter didSelectedEnter;

 #pragma mark - Property
//前景图
@property (nonatomic, strong) NSArray *coverImageNames;

//背景图
@property (nonatomic, strong) NSArray *backgroundImageNames;

 #pragma mark - init
- (id)initWithCoverImageNames:(NSArray*)coverNames backgroundImageNames:(NSArray*)bgNames;

@end

:fa-location-arrow:IntroductionViewController.m

 #import "IntroductionViewController.h"

@interface IntroductionViewController ()<UIScrollViewDelegate>

@property (nonatomic, strong) NSArray *backgroundViews; //背景UIImageViews
@property (nonatomic, strong) NSArray *coverViews; //前景UIImageViews

@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UIPageControl *pageControl;

@property (nonatomic, assign) NSInteger numberOfPages;

@end

@implementation IntroductionViewController

 #pragma mark - init
- (id)initWithCoverImageNames:(NSArray *)coverNames backgroundImageNames:(NSArray *)bgNames
{
    if (self = [super init]) {
        self.coverImageNames = coverNames;
        self.backgroundImageNames = bgNames;
    }
    return self;
}

 #pragma mark - life Style
-(void)dealloc{

    void(^animations)() = ^(){
        self.view.alpha = 0;
    };
    
    __block UIView *view = self.view;
    void(^completion)(BOOL finished) = ^(BOOL finished){
        view = nil;
    };
    
    [UIView animateWithDuration:0.4
                     animations:animations
                     completion:completion];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self addBackgroundViews];
    [self addScrollView];
    [self addPageControl];
    
    [self reloadPage];
}

-(void)reloadPage{
    
    [self addCoverImageViews];
    
    if (self.scrollView.contentSize.width == self.scrollView.frame.size.width) {
        self.scrollView.contentSize = CGSizeMake(self.scrollView.contentSize.width + 1, self.scrollView.contentSize.height);
    }
}

 #pragma mark - AddScrollView
- (void)addScrollView{

    self.scrollView = [[UIScrollView alloc] initWithFrame:self.view.frame];
    
    self.scrollView.delegate = self;
    self.scrollView.pagingEnabled = YES;  //允许分页
    self.scrollView.showsHorizontalScrollIndicator = NO;
    self.scrollView.showsVerticalScrollIndicator = NO;
    self.scrollView.contentSize = [self contentSizeOfScrollView]; //内容Size
    
    [self.view addSubview:self.scrollView];
}

- (CGSize)contentSizeOfScrollView
{
    
    return CGSizeMake(self.view.frame.size.width * self.numberOfPages, self.view.frame.size.height);
}

-(NSInteger)numberOfPages{
    return [_coverImageNames count];
}


 #pragma mark - AddPageControl
- (void)addPageControl{

    self.pageControl = [[UIPageControl alloc] initWithFrame:[self frameOfPageControl]];
    
    //pageControl颜色设定
    self.pageControl.pageIndicatorTintColor = [UIColor whiteColor];
    self.pageControl.currentPageIndicatorTintColor = [UIColor blueColor];

    self.pageControl.numberOfPages = self.numberOfPages;
    
    [self.view addSubview:self.pageControl];
}

- (CGRect)frameOfPageControl{

    return CGRectMake(0, self.view.frame.size.height - 30, self.view.frame.size.width, 30);
}

 #pragma mark - 添加前景,背景图
/**
  加载前景图
 */
-(void)addCoverImageViews{

    __block CGFloat x = 0;
    [self.coverViews enumerateObjectsUsingBlock:^(UIView *obj, NSUInteger idx, BOOL *stop) {
        
        obj.frame = CGRectOffset(obj.frame, x, 0);
        x = x + obj.frame.size.width;
        
        [self.scrollView addSubview:obj];
    }];
}
-(NSArray *)coverViews{

    if (_coverViews) {
        return _coverViews;
    }
    
    NSMutableArray *tempViews = [NSMutableArray new];
    [_coverImageNames enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
       
        UIImageView *imageView = [self loadImage:obj];
        [tempViews addObject:imageView];

    }];
    
    _coverViews = tempViews;
    return _coverViews;
}

-(UIImageView *)loadImage:(NSString *)imageName{
    
    UIImage *image = [UIImage imageNamed:imageName];
    UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
    imageView.frame = self.view.frame;
    
    return imageView;
}

-(void)addBackgroundViews{
    
    [[[self.backgroundViews reverseObjectEnumerator] allObjects] enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [self.view addSubview:obj];
    }];
}
-(NSArray *)backgroundViews{
    
    if (_backgroundViews) {
        return _backgroundViews;
    }
    
    NSMutableArray *tempViews = [NSMutableArray new];
    [_backgroundImageNames enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        
        UIImageView *imageView = [self loadImage:obj];
        [tempViews addObject:imageView];
        
    }];
    
    _backgroundViews = tempViews;
    return _backgroundViews;
}



 #pragma mark - ScrollViewDelegate
/**
 scrollView滚动时,就调用该方法。
 任何offset值改变都调用该方法。即滚动过程中,调用多次
 */
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{

    //偏移了几个屏幕的宽度0,1,2
    NSInteger index = scrollView.contentOffset.x/scrollView.frame.size.width;
    
    //透明度:1-(相对偏移量/屏幕宽度)
    CGFloat relativeOffsetX = scrollView.contentOffset.x - index*scrollView.frame.size.width; //相对偏移量
    CGFloat alpha = 1 - (relativeOffsetX/scrollView.frame.size.width);
    
    if ([self.backgroundViews count] > index) {
    
        UIView *view = [_backgroundViews objectAtIndex:index];
        view.alpha = alpha;
    }
    
    //分页控制器
    self.pageControl.currentPage = scrollView.contentOffset.x/scrollView.frame.size.width;
}

- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView
{
    if ([scrollView.panGestureRecognizer translationInView:scrollView.superview].x < 0) {
        if (![self hasNext:self.pageControl]) {
            [self enter:nil];
        }
    }
}

 #pragma mark - UIScrollView & UIPageControl DataSource

- (BOOL)hasNext:(UIPageControl*)pageControl
{
    return pageControl.numberOfPages > pageControl.currentPage + 1;
}

 #pragma mark - Action

- (void)enter:(id)object
{
    if (self.didSelectedEnter) {
        self.didSelectedEnter();
    }
}

@end
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!