必威-必威-欢迎您

必威,必威官网企业自成立以来,以策略先行,经营致胜,管理为本的商,业推广理念,一步一个脚印发展成为同类企业中经营范围最广,在行业内颇具影响力的企业。

进入系统API你可以找到iOS 必威SDK提供的初始化方

2019-09-17 13:22 来源:未知
UIPageViewControllerOptionInterPageSpacingKey

可以控制两个控制器之间的距离,只可用于滚动样式

@property (nonatomic, readonly) UIPageViewControllerTransitionStyle transitionStyle;@property (nonatomic, readonly) UIPageViewControllerNavigationOrientation navigationOrientation;@property (nonatomic, readonly) UIPageViewControllerSpineLocation spineLocation; // If transition style is 'UIPageViewControllerTransitionStylePageCurl', default is 'UIPageViewControllerSpineLocationMin', otherwise 'UIPageViewControllerSpineLocationNone'.

这三个只读的参数,可以获取到控制器的一些基本信息

// Whether client content appears on both sides of each page. If 'NO', content on page front will partially show through back.// If 'UIPageViewControllerSpineLocationMid' is set, 'doubleSided' is set to 'YES'. Setting 'NO' when spine location is mid results in an exception.@property (nonatomic, getter=isDoubleSided) BOOL doubleSided; // Default is 'NO'.

这个参数,专门用于书本翻页样式,如果为NO,则被翻页的页面背面,会有一个默认的背面展示出来,如果被翻页的页面背景是一个比较暗的色调的话,默认的背面会偏白,会比较难看。当设置了doubleSided为YES后,就可以自己设置被翻页页面的背面,关于如何设置,后面介绍代理方法的时候会进行讨论。必威 1默认翻页的背面

// Set visible view controllers, optionally with animation. Array should only include view controllers that will be visible after the animation has completed.// For transition style 'UIPageViewControllerTransitionStylePageCurl', if 'doubleSided' is 'YES' and the spine location is not 'UIPageViewControllerSpineLocationMid', two view controllers must be included, as the latter view controller is used as the back.- setViewControllers:(nullable NSArray<UIViewController *> *)viewControllers direction:(UIPageViewControllerNavigationDirection)direction animated:animated completion:(void (^ __nullable)(BOOL finished))completion;

这个方法可以设置要展示的控制器,这边有个要注意的地方,这个viewControllers并不是要把所有的控制器传入,只用于传入可见的控制器,也就是说,如果是一般的场景的话,这个viewControllers只用传入一个控制器,当spineLocation这个属性为UIPageViewControllerSpineLocationMid,也就是书脊在页面中间的时候,传入两个才有意义,这个时候传入的两个页面就是书页的左右两页。如果spineLocation这个属性不是UIPageViewControllerSpineLocationMid,且doubleSided为YES的话,传入的第二个控制器为第一个控制器的背面(文档中写着如果doubleSided这个值设置为YES的话,要传入两个控制器,但是我试了下,传入一个也没有什么关系,只用后面数据源代理的时候保证有另外的控制器就可以)。

小结

使用UIPageViewController主要就是理解其层次结构和代理方法调用时机。作为容器加载各式各样的显示控制器。在此特别感谢一起开发阅读APP的战友小明同学 @GeekDmm 提供的丰富资料。
希望这篇文章可以帮到你。

UIPageViewController是App中常用的控制器。它提供了一种分页效果来显示其childController的View。用户可以通过手势像翻书一样切换页面。
切换页面时看起来是连续的,但静止状态下UIPageViewController同时只有一个childViewController。它的导航效果是通过替换childController实现的。
这是一种非常有效的设计:无论是三两个还上千个页面,用户的翻页与导航处理都是无差别的。因为这些页面都是即时创建的,每个页面只有当你浏览它的时候才会存在。这种设计显然苹果更多地考虑了内存的问题和通用性。
UIPageViewController替我们解决了页面导航、childController生命周期管理、 平滑过渡动画(index不相邻页面切换时)等问题。
下面做了简单是学习!

实现效果

import "ViewController.h"

@interface ViewController ()<UIPageViewControllerDelegate, UIPageViewControllerDataSource>

@property (nonatomic, strong)UIPageViewController *pageVc;
@property (nonatomic, strong)NSMutableArray *viewControllers;

@end

@implementation ViewController

  • (void)viewDidLoad {
    [super viewDidLoad];
    /* style :这个参数是UIPageViewController翻页的过渡样式,系统提供了两种过度样式,分别是

    1. UIPageViewControllerTransitionStylePageCurl : 卷曲样式类似翻书效果
    2. UIPageViewControllerTransitionStyleScroll : UIScrollView滚动效果
    • navigationOrientation : 这个参数是UIPageViewController导航方向,系统提供了两种方式,分别是
    1. UIPageViewControllerNavigationOrientationHorizontal : 水平导航方式
    2. UIPageViewControllerNavigationOrientationVertical : 垂直导航方式
    • options : 这个参数是可选的,传入的是对UIPageViewController的一些配置组成的字典,不过这个参数只能以UIPageViewControllerOptionSpineLocationKey和UIPageViewControllerOptionInterPageSpacingKey这两个key组成的字典.
    1. UIPageViewControllerOptionSpineLocationKey 这个key只有在style是翻书效果UIPageViewControllerTransitionStylePageCurl的时候才有作用, 它定义的是书脊的位置,值对应着UIPageViewControllerSpineLocation这个枚举项,不要定义错了哦.
    2. UIPageViewControllerOptionInterPageSpacingKey这个key只有在style是UIScrollView滚动效果UIPageViewControllerTransitionStyleScroll的时候才有作用, 它定义的是两个页面之间的间距(默认间距是0).

    */
    // NSDictionary options = @{UIPageViewControllerOptionInterPageSpacingKey : @(20)};
    /

    UIPageViewControllerSpineLocationNone = 0, // 默认UIPageViewControllerSpineLocationMin
    UIPageViewControllerSpineLocationMin = 1, // 书棱在左边
    UIPageViewControllerSpineLocationMid = 2, // 书棱在中间,同时显示两页
    UIPageViewControllerSpineLocationMax = 3 // 书棱在右边
    */
    NSDictionary *options = @{UIPageViewControllerOptionSpineLocationKey : [NSNumber numberWithInteger:UIPageViewControllerSpineLocationMin]};
    self.pageVc = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:options];

    self.pageVc.delegate = self;
    self.pageVc.dataSource = self;

    self.pageVc.view.frame = self.view.bounds;

    // 要显示的第几页
    // NSArray *vcs = [NSArray arrayWithObject:self.viewControllers[2]];

    // 如果要同时显示两页,options参数要设置为UIPageViewControllerSpineLocationMid
    NSArray *vcArray = [NSArray arrayWithObject:self.viewControllers[0]];

    [self.pageVc setViewControllers:vcArray direction:UIPageViewControllerNavigationDirectionReverse animated:YES completion:nil];

    // 保存控制器
    [self addChildViewController:self.pageVc];
    // 显示控制器
    [self.view addSubview:self.pageVc.view];
    }

// 根据数组元素,得到下标值

  • (NSUInteger)indexOfViewController:(UIViewController *)viewControlller {
    return [self.viewControllers indexOfObject:viewControlller];
    }
UIPageViewControllerNavigationDirection

这个枚举用来控制页面进入的方向,也就是向左或向右。

typedef NS_ENUM(NSInteger, UIPageViewControllerNavigationDirection) { UIPageViewControllerNavigationDirectionForward, UIPageViewControllerNavigationDirectionReverse}; // For 'UIPageViewControllerNavigationOrientationHorizontal', 'forward' is right-to-left, like pages in a book. For 'UIPageViewControllerNavigationOrientationVertical', bottom-to-top, like pages in a wall calendar.

最后还有两个只读属性

// An array of UIGestureRecognizers pre-configured to handle user interaction. Initially attached to a view in the UIPageViewController's hierarchy, they can be placed on an arbitrary view to change the region in which the page view controller will respond to user gestures.// Only populated if transition style is 'UIPageViewControllerTransitionStylePageCurl'.@property(nonatomic, readonly) NSArray<__kindof UIGestureRecognizer *> *gestureRecognizers;@property (nullable, nonatomic, readonly) NSArray<__kindof UIViewController *> *viewControllers;

一个是可以拿到pageViewController的所有手势(只有书页翻动样式才能拿到),在数组里面有一个Tap手势和一个Pan手势,可以通过循环的方法,为手势添加代理,从而实现代理方法。另一个是可以拿到pageViewController的所有可见控制器,和上面setViewController方法的viewControllers是同一个意思。

结构

在使用UIPageViewController前,我们应该先搞清楚它的层次结构。(这里是我在使用过程中的理解,如有不对,欢迎指出)。

pageviewcontroller层次展示图

UIPageViewController作为子控制器加载在viewController上。作为文本控制器的容器,且提供翻页的动画效果。

创建一个TextViewController,用来显示文本,装入pageViewController中。

所以,pageViewController只是提供一个翻页特效的容器,真正显示在界面上的是里面的TextViewController。到这里是我对pageViewController有一个初步的理解。

//从左往右(或从下往上)
//UIPageViewControllerNavigationDirectionForward,
//从左往右(或从下往上)
//UIPageViewControllerNavigationDirectionReverse

UIPageViewController 总结

关于UIPageViewController的使用就介绍这么多,关键点在于UIPageViewController的配置项的设置以及数据源的控制.
希望这篇文章会对你有所帮助
Demo地址 https://github.com/Herb-Sun/UIPageViewControllerDemo

实例代码如下:

类的方法和属性

UIPageViewControll 是苹果自带的带有翻页效果的一个API,它的内部有两种动画效果,一种是类似图书翻页的卷曲效果;

UIPageViewControllerTransitionStylePageCurl

一种是简单的滚动效果

UIPageViewControllerTransitionStyleScroll

这两个动画效果一旦执行了初始化方法后,就不可更改

- (instancetype)initWithTransitionStyle:(UIPageViewControllerTransitionStyle)style navigationOrientation:(UIPageViewControllerNavigationOrientation)navigationOrientation options:(nullable NSDictionary<UIPageViewControllerOptionsKey, id> *)options NS_DESIGNATED_INITIALIZER;

这个初始化方法还包含两个参数,一个是控制器的滚动方向:

typedef NS_ENUM(NSInteger, UIPageViewControllerNavigationOrientation) { UIPageViewControllerNavigationOrientationHorizontal = 0, UIPageViewControllerNavigationOrientationVertical = 1};

一个是控制器可以设置的options key,

// Key for specifying spine location in options dictionary argument to initWithTransitionStyle:navigationOrientation:options:.// Value should be a 'UIPageViewControllerSpineLocation' wrapped in an NSNumber.// Only valid for use with page view controllers with transition style 'UIPageViewControllerTransitionStylePageCurl'.UIKIT_EXTERN UIPageViewControllerOptionsKey const UIPageViewControllerOptionSpineLocationKey;// Key for specifying spacing between pages in options dictionary argument to initWithTransitionStyle:navigationOrientation:options:.// Value should be a CGFloat wrapped in an NSNumber. Default is '0'.// Only valid for use with page view controllers with transition style 'UIPageViewControllerTransitionStyleScroll'.UIKIT_EXTERN UIPageViewControllerOptionsKey const UIPageViewControllerOptionInterPageSpacingKey NS_AVAILABLE_IOS;

阅读API文档,这两个key分别只能对应一种滚动样式的控制器,其中

1.初始化

- (instancetype)initWithTransitionStyle:(UIPageViewControllerTransitionStyle)style navigationOrientation:(UIPageViewControllerNavigationOrientation)navigationOrientation options:(nullable NSDictionary*)options

UIPageViewController 为我们提供了2种翻页样式,一种是拟真一种是滚动。只需要使用系统的构造方法返回一个UIPageViewController的对象。并且设置它的代理和数据源并把它加入到控制器中就可以了

pageViewController.delegate = self;

pageViewController.dataSource = self;

[self addChildViewController:pageViewController];

[self.view addSubview:pageViewController.view];

通过提供的set方法将textController装入pageViewController中,这个set方法提供了一种样式,决定翻页是纵向还是横向。

typedef NS_ENUM(NSInteger, UIPageViewControllerNavigationDirection) {

UIPageViewControllerNavigationDirectionForward,//横向,像书一样

UIPageViewControllerNavigationDirectionReverse//纵向,像日历一样
};

BookTextController *readerController = [BookTextController new];//展示文本的控制器
    [_pageViewController setViewControllers:@[ readerController ]
                                  direction:UIPageViewControllerNavigationDirectionForward
                                   animated:NO
                                 completion:nil];

//
//  ViewController.m
//  DemoTest

代理 <UIPageViewControllerDelegate>

iOS SDK提供了五个代理方法:

// Sent when a gesture-initiated transition begins.
- (void)pageViewController:(UIPageViewController *)pageViewController
willTransitionToViewControllers:(NSArray<UIViewController *> *)pendingViewControllers NS_AVAILABLE_IOS(6_0);

这个方法是UIPageViewController开始滚动或翻页的时候触发

// Sent when a gesture-initiated transition ends. The 'finished' parameter indicates whether the animation finished, while the 'completed' parameter indicates whether the transition completed or bailed out (if the user let go early).
- (void)pageViewController:(UIPageViewController *)pageViewController
        didFinishAnimating:(BOOL)finished
   previousViewControllers:(NSArray<UIViewController *> *)previousViewControllers
       transitionCompleted:(BOOL)completed;

这个方法是在UIPageViewController结束滚动或翻页的时候触发

// Delegate may specify a different spine location for after the interface orientation change. Only sent for transition style 'UIPageViewControllerTransitionStylePageCurl'.
// Delegate may set new view controllers or update double-sided state within this method's implementation as well.
- (UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController
                   spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation __TVOS_PROHIBITED;

这个方法是在style是UIPageViewControllerTransitionStylePageCurl 并且横竖屏状态变化的时候触发,我们可以重新设置书脊的位置,比如如果屏幕是竖屏状态的时候我们就设置书脊位置是UIPageViewControllerSpineLocationMin或UIPageViewControllerSpineLocationMax, 如果屏幕是横屏状态的时候我们可以设置书脊位置是UIPageViewControllerSpineLocationMid

- (UIInterfaceOrientationMask)pageViewControllerSupportedInterfaceOrientations:(UIPageViewController *)pageViewController NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;
- (UIInterfaceOrientation)pageViewControllerPreferredInterfaceOrientationForPresentation:(UIPageViewController *)pageViewController NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;

这两个方法设置了UIPageViewController支持的屏幕类型

今天再看一个旧项目时,发现这里面用的了UIPageViewController这个控件(可以理解为书籍控件)。之前只是听说过,从来没有去实际运用过。所以就来看看UIPageViewController的基本使用。本文只是对UIPageViewController它的基本介绍,对于大牛级别的可以绕行。

UIPageViewControllerOptionSpineLocationKey

可以控制类似书本的书脊的位置,只可用于书本翻动样式

必威 2UIPageViewControllerSpineLocationMin必威 3UIPageViewControllerSpineLocationMid必威 4UIPageViewControllerSpineLocationMax

typedef NS_ENUM(NSInteger, UIPageViewControllerSpineLocation) { UIPageViewControllerSpineLocationNone = 0, // Returned if 'spineLocation' is queried when 'transitionStyle' is not 'UIPageViewControllerTransitionStylePageCurl'. UIPageViewControllerSpineLocationMin = 1, // Requires one view controller. UIPageViewControllerSpineLocationMid = 2, // Requires two view controllers. UIPageViewControllerSpineLocationMax = 3 // Requires one view controller.}; // Only pertains to 'UIPageViewControllerTransitionStylePageCurl'.

2.delegate和dataSource

//向前翻页
- (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController;

//向后翻页
- (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController;

从声明中我们不难发现返回的是一个UIViewController对象,这个对象将重新装入pageViewController中,从而显示在界面上。其中参数中的viewController为当前显示的控制器(这个参数在使用doubleSided属性时非常重要,后面会讲到)。知道这2个方法的作用后,pageViewController使用起来就非常简单了。

并且这个方法执行以后,之前pageViewController里的控制器将被释放,所以pageViewController.viewControllers同样只装了1个viewController。

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
       viewControllerAfterViewController:(UIViewController *)viewController {
    //返回即将显示的控制器
    BookTextController *vc = [BookTextController new];
    return vc;
}

还有一个非常有用的代理,它在动画执行完毕后被调用,在controller切换完成后,我们可以在这个代理中进行一些后续操作。例如用UIPageViewController实现轮播分页等功能。

- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray*)previousViewControllers transitionCompleted:(BOOL)completed;

到这里pageViewController的基本使用已经差不多了。通过合理的设置,我们很容易就可以实现一个翻页效果。但是在开发阅读软件中我还遇到一个非常严重的体验问题。在翻页的时候,书页背面的颜色默认为白色。在黑夜模式中非常“辣眼睛”

黑夜模式书页背面为白色 ![Uploading 1F5EC677-326D-4BAF-96D6-5A885FA07C9F_639563.png . . .]

  • (void)setUpPageViewController {
        [self addChildViewController:self.pageViewController];
        [self.view addSubview:self.pageViewController.view];
    }

UIPageViewController使用

  UIPageViewController也有自己的delegate和dataSource 相信这两个熟悉在做iOS开发使用UITableView你已经很熟悉了。dataSource 也有两个必须实现的协议方法,分别用了返回当前控制器的上个控制器和当前控制器的下一个控制器。

    在使用UIPageViewController控件时尤为注意的时当使用UIPageViewControllerOptionSpineLocationKey的值为UIPageViewControllerSpineLocationMid时也就书脊的位置在中间,同时显示两页内容初始设置显示时一定要设置两个自控制器 否则会报错。如果只显示一页内容则初始设置时只是一个一个控制器。
TAG标签:
版权声明:本文由必威发布于必威-编程,转载请注明出处:进入系统API你可以找到iOS 必威SDK提供的初始化方