Giter Site home page Giter Site logo

xlpageviewcontroller's Introduction

title

目录:

特点:

  • 采用UICollectionView+UIPageViewController方案,高性能,低功耗。
  • 支持刷新,内置缓存(非复用)机制,节省内存。
  • 默认配置样式丰富,可实现大部分主流App样式。
  • 支持用户自定义标题样式。
  • 兼容全屏返回手势。

结构:

结构图

App举例:

App 示例
今日头条 image
腾讯新闻 image
澎湃新闻 image
爱奇艺 image
优酷 image
腾讯视频 image
网易新闻 image
人民日报 image

基本属性:

功能 示例
基本样式-标题正常显示 image
基本样式-标题显示在导航栏上 image
Segmented样式-标题正常显示 image
Segmented样式-标题显示在导航栏上 image
标题栏-居左 image
标题栏-居中 image
标题栏-居右 image
标题栏-自定义高度 image
标题-自定义宽度 image
标题-文字居上 image
标题-文字居下 image
标题-关闭标题颜色过渡 image
阴影动画-缩放 image
阴影动画-无 image
阴影末端形状-圆角 image
阴影末端形状-直角 image
阴影-居上 image
阴影-居中 image

特殊用法:

场景 示例
自定义标题Cell image
频道定制 image
多级嵌套 image
子View手势冲突 image
手动切换 image

使用:

1、创建方法

1.1 导入头文件

#import "XLPageViewController.h"

1.2 遵守协议

@interface ViewController ()<XLPageViewControllerDelegate, XLPageViewControllerDataSrouce>

1.3 创建外观配置类

注:config负责所有的外观配置,defaultConfig方法设定了默认参数,使用时可按需配置。 →Config属性列表

  XLPageViewControllerConfig *config = [XLPageViewControllerConfig defaultConfig];

1.4 创建分页控制器

注:需要把pageViewController添加为当前视图控制器的子视图控制器,才能实现子视图控制器中的界面跳转。

  XLPageViewController *pageViewController = [[XLPageViewController alloc] initWithConfig:config];
  pageViewController.view.frame = self.view.bounds;
  pageViewController.delegate = self;
  pageViewController.dataSource = self;
  [self.view addSubview:pageViewController.view];
  [self addChildViewController:pageViewController];

2、协议

2.1 XLPageViewControllerDelegate

//回调切换位置
- (void)pageViewController:(XLPageViewController *)pageViewController didSelectedAtIndex:(NSInteger)index;

2.2 XLPageViewControllerDataSrouce

@required

//根据index创建对应的视图控制器,每个试图控制器只会被创建一次。
- (UIViewController *)pageViewController:(XLPageViewController *)pageViewController viewControllerForIndex:(NSInteger)index;
//根据index返回对应的标题
- (NSString *)pageViewController:(XLPageViewController *)pageViewController titleForIndex:(NSInteger)index;
//返回分页数
- (NSInteger)pageViewControllerNumberOfPage;

@optional

//标题cell复用方法,自定义标题cell时用到
- (__kindof XLPageTitleCell *)pageViewController:(XLPageViewController *)pageViewController titleViewCellForItemAtIndex:(NSInteger)index;

3、自定义标题cell

3.1 创建一个XLPageTitleCell的子类

#import "XLPageTitleCell.h"

@interface CustomPageTitleCell : XLPageTitleCell

@end

3.2 注册cell、添加创建cell

//需要先注册cell
[self.pageViewController registerClass:CustomPageTitleCell.class forTitleViewCellWithReuseIdentifier:@"CustomPageTitleCell"];
//自定义标题cell创建方法
- (XLPageTitleCell *)pageViewController:(XLPageViewController *)pageViewController titleViewCellForItemAtIndex:(NSInteger)index {
    CustomPageTitleCell *cell = [pageViewController dequeueReusableTitleViewCellWithIdentifier:@"CustomPageTitleCell" forIndex:index];
    return cell;
}

3.3 复写cell父类方法

//通过此父类方法配置标题cell是否被选中样式
- (void)configCellOfSelected:(BOOL)selected {

}

//通过此父类方法配置标题cell动画;type:区分是当前选中cell/将要被选中的cell;progress:动画进度0~1
- (void)showAnimationOfProgress:(CGFloat)progress type:(XLPageTitleCellAnimationType)type {
    
}

4、特殊情况处理

4.1 和子view手势冲突问题

pageViewController的子视图中存在可滚动的子view,例如UISlider、UIScrollView等,如果子view和pageViewController发生滚动冲突时,可设置子view的xl_letMeScrollFirst属性为true。

  UISlider *slider = [[UISlider alloc] init];
  slider.xl_letMeScrollFirst = true;
  [childVC.view addSubview:slider];

4.2 全屏返回手势问题

pageViewController和全屏返回手势一起使用时,需要将其它手势的delegate的类名添加到respondOtherGestureDelegateClassList属性中。当滚动到第一个分页时,向右滑动会优先响应全屏返回。以FDFullscreenPopGesture为例:

self.pageViewController.respondOtherGestureDelegateClassList = @[@"_FDFullscreenPopGestureRecognizerDelegate"];

5、注意事项

使用时需注意标题不要重复标题是定位ViewController的唯一ID。

更新

! 2019/07/29 解决快速滑动导致显示错乱问题
! 2019/07/31 修正scrollEnabled属性不生效问题
! 2019/08/01 处理预设selectedIndex如果超出屏幕时,标题选中位置错乱问题
! 2019/08/03 处理当标题栏样式是Segmented时,点击标题切换慢的问题
+ 2019/08/03 添加UIViewController扩展标题属性,避免因title改变导致的异常
! 2019/08/19 解决因滑动距离过大,导致出现空白界面问题
! 2019/09/05 解决刷新方法可能造成的闪退问题
! 2019/09/23 解决使用多级嵌套时,可能出现界面错乱问题
! 2019/09/23 解决滑动切换时,标题栏可能会再一瞬间出现动画失效的问题
! 2020/03/19 解决滑动距离小,自动回弹后导致标题点击失效问题
! 2020/03/25 解决从网络获取标题,刷新后阴影位置没有更新问题
! 2020/04/02 解决设置selectedIndex时,可能出现底部阴影显示出错问题
! 2020/04/23 解决设置selectedIndex后,代理方法可能不执行问题
+ 2020/05/06 添加全屏手势解决方案

其他

xlpageviewcontroller's People

Contributors

mengxianliang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

xlpageviewcontroller's Issues

title点击失效

轻微的滑动页面,不让title切换,再点击title就无反应了

关于侧滑失效和弹簧效果

//滑动开关

  • (void)setScrollEnabled:(BOOL)scrollEnabled {
    _scrollEnabled = scrollEnabled;
    self.scrollView.scrollEnabled = scrollEnabled;
    }
    当我设置self.pageViewController.scrollEnabled = NO;时,第一次加载确实是不能滑动,然后我点击其它title时,既然发现又可以滑动了。

偶然的情况下:
在我想处理侧滑第1个或者最后一个tiltle时,控制侧滑没有弹簧效果时,发现实现了禁止滑动的操作,没有上面的bug了。代码如下
//滑动开关

  • (void)setScrollEnabled:(BOOL)scrollEnabled {
    _scrollEnabled = scrollEnabled;
    self.scrollView.bounces = scrollEnabled;
    }

不知道是不是我代码的原因,还请您查阅下呢。最后,想问下作者您的代码能实现侧滑第1个或者最后一个tiltle时,控制侧滑没有弹簧效果(第0个或者最后一个title时,侧滑还是会有滑动一定距离然后有弹回的效果)吗?

空白页,及UIView flush crash

1、只点击头部的titleview切换,快速来回切换,概率报UIView flush 的crash错误
2.一边滑动带有scrollview对象的viewcontroller.一边点击头部titleview。概率出现同1的问题,还有概率报”Duplicate states in queue'crash
3、点击titleview切换的时候,快速点viewcontroller对象,概率出现空白页,或者显示错乱问题
尝试修改内部实现,但是越该问题越多😹

频道定制

选中当前title最后一个,然后进去频道选择。在里面删掉最后一个(也就是自己)会崩溃,奔溃点在下面
NSIndexPath *indexPath1 = [NSIndexPath indexPathForRow:_selectedIndex inSection:0];
NSIndexPath *indexPath2 = [NSIndexPath indexPathForRow:_lastSelectedIndex inSection:0];
[UIView performWithoutAnimation:^{
[self.collectionView reloadItemsAtIndexPaths:@[indexPath1,indexPath2]];
}];

右滑返回手势与scrollView的滑动手势冲突

应该不止我一个人自定义了nav,并添加了全屏右滑返回的手势吧,如果加了就会和你这个srollview的手势冲突,需要创建一个scrollView的分类解决这个问题,希望考虑添加上

全屏手势的问题

因为我的项目里面都是全屏右滑返回,需要拿到您代码里面内容的scrollview,让它继承CustomScrollView,实现一个代理方法触发,让内容的scrollview允许多手势。。从而实现滑动视图和全屏手势的冲突问题。现在的问题是:没找到相应的scrollview,暂时也没有时间慢慢去研究您写的代码。。

class CustomScrollView: UIScrollView {

}
extension CustomScrollView : UIGestureRecognizerDelegate {
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
if otherGestureRecognizer.state == UIGestureRecognizerState.began && self.contentOffset.x == 0 {
return true
}
return false
}
}

快速滑动导致页面混乱的问题

我的项目里面用了这个, 出现快速滑动页面混乱的情况, 没有找到问题的根本原因。 所以就用了一个比较笨的方法, 就是在左右滚动的动画开始的时候 禁用交互,动画结束的时候再打开。 这样能暂时解决一下这个问题, 希望作者能抽空改一下这个bug _

#pragma mark 开始滚动时 禁止交互, 防止滚动还未结束时 抬手重新滚动 导致的bug

  • (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView{
    self.contentView.userInteractionEnabled = NO;
    }
  • (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    self.contentView.userInteractionEnabled = YES;
    }

在进行频繁的左右活动的时候,会出现页面混乱现象

//获取当前vc和当前标题
UIViewController *currentVC = self.pageVC.viewControllers.firstObject;
NSString *currentTitle = currentVC.title;

NSString *targetTitle = [self titleForIndex:index];

//如果和当前位置一样,则返回当前vc
if ([currentTitle isEqualToString:targetTitle]) {
    return currentVC;
}

//如果之前显示过,则从内存中读取
for (UIViewController *vc in self.shownVCArr) {
    if ([vc.title isEqualToString:targetTitle]) {
        return vc;
    }
}

上面这个段代码导致的

所以我提供的解决方案是:

//如果之前显示过,则从内存中读取
if (index < self.shownVCArr.count) {
UIViewController *vc = self.shownVCArr[index];
return vc;
}

请问如何返回呢?

在和FDFullscreenPopGesture 配套使用的时候。如何拉动到最左边的时候。返回上级呢?

cellForItemAtIndexPath nil

当SelectedIndex不可见时,shadowLineCenterForIndex方法中的cellForItemAtIndexPath返回nil,故阴影位置对不上SelectedIndex
demo里可复现:选中第二个title后,向左滑动至第二个title不可见时,滑动vc

XLPageViewController的dealloc方法没走

XLPageViewController.m文件138行
在block中应该都使用weakSelf
self.scrollView.xl_otherGestureRecognizerBlock = ^BOOL(UIGestureRecognizer * _Nonnull otherGestureRecognizer) {
return weakSelf.selectedIndex == 0 && [weakSelf.respondOtherGestureDelegateClassList containsObject:NSStringFromClass(otherGestureRecognizer.delegate.class)];
};

请求下来的标题如果超过7个 最后2个就点不到 也滑动不到最后2个标题

@"撒大声地",@"撒大声地" ,@"撒大声地",@"测试",@"测试",@"测试",@"测试",@"测试"
XLPageViewControllerConfig *config = [XLPageViewControllerConfig defaultConfig];
config.titleSpace = 10;
config.titleViewInset = UIEdgeInsetsMake(0, 10, 0, 10);
self.pageViewController = [[XLPageViewController alloc] initWithConfig:config];

self.pageViewController.view.frame = CGRectMake(0, NavBar_Height, kWidth, kHeight-NavBar_Height);
self.pageViewController.delegate = self;
self.pageViewController.dataSource = self;

[self addChildViewController:self.pageViewController];
[self.view addSubview:self.pageViewController.view];
123123

延迟加载数据第一页不显示 滑动崩溃 reason: 'Invalid parameter not satisfying: [views count] == 3'

延迟加载数据第一页不显示 滑动崩溃

伪代码

[self addChildViewController: self.pageController];
[self.view addSubView:self.pageController.view];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 延迟加载数据
[self.pageController reloadData];
});

必现BUG
延迟加载后设置selectedIndex = 0也没有效果

self.pageViewController.selectedIndex用来跳转异常

但有很多tabbar的时候,我初始化想直接进入第x个tabbar时使用self.pageViewController.selectedIndex异常,可以复线。比如你创建15个tabbar,然后self.pageViewController.selectedIndex = 10,显示异常

发现2个bug

bug1:多个titleview,从左到右滑动到最后一页,然后从右到左,会发现某一瞬间居中滚动动画失效。
bug2:多层级page,第一层级正常,第二层级(10个以上的页面)中titleview会乱跳,伴随着出现空白页,titleview异常选中。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.