UIPageViewController实现界面左右滑动
实现 界面 滑动 左右
2023-09-11 14:14:25 时间
UIPageViewController是iOS 5.0之后提供的一个分页控件可以实现图片轮播效果和翻书效果,使用起来也很简单方便。
初始化
- (instancetype)initWithTransitionStyle:(UIPageViewControllerTransitionStyle)style
navigationOrientation:(UIPageViewControllerNavigationOrientation)navigationOrientation
options:(nullable NSDictionary<UIPageViewControllerOptionsKey, id> *)options;
- style:
这个参数是UIPageViewController翻页的过渡样式,系统提供了两种过度样式,分别是
typedef NS_ENUM(NSInteger, UIPageViewControllerTransitionStyle) {
UIPageViewControllerTransitionStylePageCurl = 0, //卷曲样式类似翻书效果
UIPageViewControllerTransitionStyleScroll = 1 //UIScrollView滚动效果
};
- navigationOrientation:
这个参数是UIPageViewController导航方向,系统提供了两种方式,分别是
typedef NS_ENUM(NSInteger, UIPageViewControllerNavigationOrientation) {
UIPageViewControllerNavigationOrientationHorizontal = 0, //水平导航方式
UIPageViewControllerNavigationOrientationVertical = 1 //垂直导航方式
};
对应只读属性:
- options:
这个参数是可选的,传入的是对UIPageViewController的一些配置组成的字典,不过这个参数只能以UIPageViewControllerOptionSpineLocationKey和UIPageViewControllerOptionInterPageSpacingKey这两个key组成的字典。
- UIPageViewControllerOptionSpineLocationKey 这个key只有在style是翻书效果UIPageViewControllerTransitionStylePageCurl的时候才有作用,它定义的是书脊的位置,值对应着UIPageViewControllerSpineLocation这个枚举项。
- UIPageViewControllerOptionInterPageSpacingKey 这个key只有在style是滚动效果UIPageViewControllerTransitionStyleScroll的时候才有作用,它定义的是两个页面之间的间距(默认间距是0)。
属性
- 翻页过渡样式:
只读属性,对应initWithTransitionStyle方法的style参数
@property (nonatomic, readonly) UIPageViewControllerTransitionStyle transitionStyle;
- 导航方向:
只读属性,对应initWithTransitionStyle方法的navigationOrientation参数
@property (nonatomic, readonly) UIPageViewControllerNavigationOrientation navigationOrientation;
- 书脊位置:
@property (nonatomic, readonly) UIPageViewControllerSpineLocation spineLocation;
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'.
- 双页样式:
@property (nonatomic, getter=isDoubleSided) BOOL doubleSided;
这个属性默认为NO,如果我们当前屏幕仅展示一个页面那么不用设置这个属性,如果spineLocation设置了UIPageViewControllerSpineLocationMid这个选项,效果是翻开的书,这样屏幕展示的就是两个页面,这个属性就必须设置为YES了。
- 设置UIPageViewController要显示的页面:
- (void)setViewControllers:(nullable NSArray<UIViewController *> *)viewControllers
direction:(UIPageViewControllerNavigationDirection)direction
animated:(BOOL)animated
completion:(void (^ __nullable)(BOOL finished))completion;
如果doubleSided设为YES了,那么viewControllers这个参数至少包含两个页面。
UIPageViewControllerNavigationDirection为翻页方向:
typedef NS_ENUM(NSInteger, UIPageViewControllerNavigationDirection) {
UIPageViewControllerNavigationDirectionForward, //前进
UIPageViewControllerNavigationDirectionReverse //后退
};
数据源和代理
- 代理
<UIPageViewControllerDelegate>
// UIPageViewController开始滚动或翻页的时候触发
- (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray<UIViewController *> *)pendingViewControllers API_AVAILABLE(ios(6.0));
// UIPageViewController结束滚动或翻页的时候触发
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray<UIViewController *> *)previousViewControllers transitionCompleted:(BOOL)completed;
// 在style是UIPageViewControllerTransitionStylePageCurl 并且横竖屏状态变化的时候触发, 我们可以重新设置书脊的位置
// 比如屏幕是竖屏状态的时候我们就设置书脊位置是UIPageViewControllerSpineLocationMin或UIPageViewControllerSpineLocationMax
// 如果屏幕是横屏状态的时候我们可以设置书脊位置是UIPageViewControllerSpineLocationMid
- (UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation API_UNAVAILABLE(tvos);
// 设置UIPageViewController支持的屏幕类型
- (UIInterfaceOrientationMask)pageViewControllerSupportedInterfaceOrientations:(UIPageViewController *)pageViewController API_AVAILABLE(ios(7.0)) API_UNAVAILABLE(tvos);
- (UIInterfaceOrientation)pageViewControllerPreferredInterfaceOrientationForPresentation:(UIPageViewController *)pageViewController API_AVAILABLE(ios(7.0)) API_UNAVAILABLE(tvos);
- 数据源
<UIPageViewControllerDataSource>
// 返回前一个页面,如果返回为nil,那么UIPageViewController就会认为当前页面是第一个页面不可以向前滚动或翻页
- (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController;
// 返回下一个页面,如果返回为nil,那么UIPageViewController就会认为当前页面是最后一个页面不可以向后滚动或翻页
- (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController;
@optional
// A page indicator will be visible if both methods are implemented, transition style is 'UIPageViewControllerTransitionStyleScroll', and navigation orientation is 'UIPageViewControllerNavigationOrientationHorizontal'.
// Both methods are called in response to a 'setViewControllers:...' call, but the presentation index is updated automatically in the case of gesture-driven navigation.
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController API_AVAILABLE(ios(6.0)); // The number of items reflected in the page indicator.
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController API_AVAILABLE(ios(6.0)); // The selected item reflected in the page indicator.
实现示例
@interface ViewController ()<UIPageViewControllerDelegate, UIPageViewControllerDataSource>
@property (nonatomic, strong) UIPageViewController *pageViewController;
@property (nonatomic, strong) NSArray *controllers;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSDictionary *options = @{UIPageViewControllerOptionSpineLocationKey:@(UIPageViewControllerSpineLocationMin)};
_pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:options];
_pageViewController.delegate = self;
_pageViewController.dataSource = self;
_pageViewController.view.frame = self.view.bounds;
[self addChildViewController:self.pageViewController];
[self.view addSubview:self.pageViewController.view];
UIViewController *leftCtrl = [[UIViewController alloc] init];
leftCtrl.view.backgroundColor = [UIColor redColor];
UIViewController *midCtrl = [[UIViewController alloc] init];
midCtrl.view.backgroundColor = [UIColor greenColor];
UIViewController *rightCtrl = [[UIViewController alloc] init];
rightCtrl.view.backgroundColor = [UIColor blueColor];
self.controllers = @[leftCtrl, midCtrl, rightCtrl];
// 设置UIPageViewController的配置项
[_pageViewController setViewControllers:@[_controllers[0]]
direction:UIPageViewControllerNavigationDirectionForward
animated:NO
completion:nil];
}
#pragma mark - UIPageViewControllerDataSource
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController {
NSUInteger index = [self.controllers indexOfObject:viewController];
index = (index+self.controllers.count-1)%self.controllers.count;
return self.controllers[index];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController {
NSUInteger index = [self.controllers indexOfObject:viewController];
index = (index+1)%self.controllers.count;
return self.controllers[index];
}
#pragma mark - UIPageViewControllerDelegate
- (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray *)pendingViewControllers {
NSLog(@"%s", __func__);
}
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed {
NSLog(@"%s", __func__);
}
@end
相关文章
- Java+MyEclipse+Tomcat (五)DAO和Java Bean实现数据库和界面分开操作
- IOS开发--iPad之仿制QQ空间(登录界面搭建+登录逻辑实现)
- iOS开发UI篇—使用xib自定义UItableviewcell实现一个简单的团购应用界面布局
- Java实现 蓝桥杯VIP 算法提高 高精度乘法
- 66、多种多样的App主界面Tab(1)------ ViewPager实现Tab
- 什么是 IP 隧道,Linux 怎么实现隧道通信?
- 66、多种多样的App主界面Tab(1)------ ViewPager实现Tab
- vue+elementui 项目el-menu导航栏实现路由跳转及当前项的设置
- Android TextInputLayout 实现动画登录界面
- Qt 使用QSharedMemory方式实现数据跨界面传输
- 利用Astar算法实现飞行轨迹的三维规划(基于Matlab代码实现)
- 基于径向基函数RBF网络的手写数字分类(Matlab代码实现)
- 使用OpenCV的kmeans实现图像分割
- QT开发教程:QScroller实现home界面滑动效果
- python四十几行代码实现界面化贪吃蛇
- 【华为机试真题详解 Python实现】找数字【2023 Q1 | 100分】
- 简易的聊天界面以及聊天机器人的实现
- python 利用quick sort思路实现median函数
- Django实现友好的注册界面【带提示错误信息】
- Java Swing星座选择器界面的实现
- Docker-ubuntu18.04容器内部 install QT5 (C++)及启动界面编译demo:分形几何(曼德布罗集)实现