一直觉得自己写的不是技术,而是情怀,一个个的教程是自己这一路走来的痕迹。靠专业技能的成功是最具可复制性的,希望我的这条路能让你们少走弯路,希望我能帮你们抹去知识的蒙尘,希望我能帮你们理清知识的脉络,希望未来技术之巅上有你们也有我。
(OC)小说翻页效果,UIPageViewController-代码事例
视频解说
效果
前言
整个页面的代码原理就是一个ViewController,上面添加了一个UIPageViewController,然后UIPageViewController上面在加一个ViewController,当手势翻下一页的时候就调用UIPageViewController的datasource返回NextViewController,当手势前下一页的时候就调用UIPageViewController的datasource返回BackViewController,
定义属性
//翻页控制器
@property (strong, nonatomic) UIPageViewController *pageViewController;
@property (strong, nonatomic) NSArray *pageData;//1-12数组 数据源方法
//保存当前控制器的目的是为了,翻页的时候,用当前控制器拿到当前的页数,看看是否有下一页或者前一页
@property (nonatomic, strong) UIViewController *currentViewController;
初始化 UIPageViewController
初始化 UIPageViewController和数据源
self.pageData = @[@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12"];
self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
self.pageViewController.delegate = self;
self.pageViewController.dataSource = self;
self.pageViewController.doubleSided = NO;//用于确定页面是否具有双面显示。将显示前一页和后一页的内容
NextViewController *startingViewController = [self viewControllerAtIndex:0];
NSArray *viewControllers = @[startingViewController];
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:NULL];
[self addChildViewController:self.pageViewController];
[self.view addSubview:self.pageViewController.view];
self.pageViewController.view.frame = self.view.bounds;
[self.pageViewController didMoveToParentViewController:self];
// Add the page view controller's gesture recognizers to the book view controller's view so that the gestures are started more easily.
self.view.gestureRecognizers = self.pageViewController.gestureRecognizers;
实现 UIPageViewController 的代理方法
// 该方法用于告诉UIPageViewController在不同设备方向下(例如横向或纵向)如何设置页面的脊柱(spine),即两个页面之间的间隔。
- (UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation
{
// 获取当前的视图控制器
UIViewController *currentViewController = self.pageViewController.viewControllers[0];
// 将当前视图控制器放入数组中
NSArray *viewControllers = @[currentViewController];
// 设置UIPageViewController的视图控制器为当前视图控制器,并指定方向为向前,带有动画效果
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];
// 设置UIPageViewController为双面显示
self.pageViewController.doubleSided = YES;
// 返回页面脊柱的位置为最小值
return UIPageViewControllerSpineLocationMin;
}
实现 UIPageViewController 的数据源方法
#pragma mark - UIPageViewController dataSource methods
// UIPageViewController数据源方法
// 前一页
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
// 如果当前页是NextViewController类型
if([viewController isKindOfClass:[NextViewController class]]) {
// 将当前视图控制器设置为当前控制器
self.currentViewController = viewController;
// 创建BackViewController实例
BackViewController *backViewController = [[BackViewController alloc] init];
// 更新BackViewController的视图控制器
[backViewController updateWithViewController:viewController];
return backViewController;
}
// 获取当前页的索引
NSUInteger index = [self indexOfViewController:(NextViewController *)_currentViewController];
// 如果当前页是第一页或者索引未找到,则返回nil
if ((index == 0) || (index == NSNotFound)) {
return nil;
}
// 索引减1,返回相应索引的视图控制器
index--;
return [self viewControllerAtIndex:index];
}
// 后一页
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
// 如果当前页是NextViewController类型
if([viewController isKindOfClass:[NextViewController class]]) {
// 将当前视图控制器设置为当前控制器
self.currentViewController = viewController;
// 创建BackViewController实例
BackViewController *backViewController = [[BackViewController alloc] init];
// 更新BackViewController的视图控制器
[backViewController updateWithViewController:viewController];
return backViewController;
}
// 获取当前页的索引
NSUInteger index = [self indexOfViewController:(NextViewController *)_currentViewController];
// 如果索引未找到,则返回nil
if (index == NSNotFound) {
return nil;
}
// 索引加1
index++;
// 如果索引等于数据源总数,则返回nil
if (index == [self.pageData count]) {
return nil;
}
// 返回相应索引的视图控制器
return [self viewControllerAtIndex:index];
}
定义两个私有方法
传入当前页数,返回当前页数的控制器(包括内容)
#pragma mark - 私有方法 - 传入当前页数,返回当前页数的控制器(包括内容)
- (NextViewController *)viewControllerAtIndex:(NSUInteger)index {
if (([self.pageData count] == 0) || (index >= [self.pageData count])) {
return nil;
}
NextViewController *dataViewController = [NextViewController new];
dataViewController.value = self.pageData[index];
return dataViewController;
}
获取当前控制器的当前页数,用于滑动时判断是否有下一页和前一页
#pragma mark - 私有方法 - 获取当前控制器的当前页数,用于滑动时判断是否有下一页和前一页
- (NSUInteger)indexOfViewController:(NextViewController *)viewController {
return [self.pageData indexOfObject:viewController.value];
}
前一个控制器
里面定义了一个方法,用于图片的内容翻页是的翻页效果
- (void)updateWithViewController:(UIViewController *)viewController {
self.backgroundImage = [self captureView:viewController.view];
}
// 捕捉指定视图的内容并返回 UIImage 对象
- (UIImage *)captureView:(UIView *)view {
// 获取视图的边界
CGRect rect = view.bounds;
// 开始一个图形上下文
UIGraphicsBeginImageContextWithOptions(rect.size, YES, 0.0f);
// 获取当前图形上下文
CGContextRef context = UIGraphicsGetCurrentContext();
// 创建仿射变换,用于翻转图像
CGAffineTransform transform = CGAffineTransformMake(-1.0, 0.0, 0.0, 1.0, rect.size.width, 0.0);
// 将仿射变换应用于当前图形上下文
CGContextConcatCTM(context,transform);
// 在当前图形上下文中渲染视图的层
[view.layer renderInContext:context];
// 从当前图形上下文中获取图像
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
// 结束图形上下文
UIGraphicsEndImageContext();
// 返回捕捉到的图像
return image;
}
下一个控制器
下一个控制器比较简单里面就一个label现实小说的内容
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor colorWithRed:241.0/255.0 green:243.0/255.0 blue:247.0/255.0 alpha:1.0];
//正页内容例如是一个label文本
self.dataLabel = [UILabel new];
self.dataLabel.text = self.value;
self.dataLabel.textColor = [UIColor blackColor];
self.dataLabel.addTo(self.view).fnt(16).makeCons(^{
make.center.equal.view(self.view);
});
}