IOS之[UIPageControl:引導頁]

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/54e1cb82933bf0212f8b5fbeios

所需控件:UIScrollView + UIPageControl數組

須要一下幾個步驟app

1.初始化自定義ViewControlleride

2.添加背景圖動畫

3.添加UIScrollViewatom

4.添加PageControl代理

5.添加前景圖code

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,因此是從下往上疊加get

經過設置透明度來顯示不一樣圖片

-(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
相關文章
相關標籤/搜索