Coder Social home page Coder Social logo

jasnig / zjscrollpageview Goto Github PK

View Code? Open in Web Editor NEW
1.1K 34.0 198.0 919 KB

网易新闻, 腾讯视频, 头条 等首页的滑块视图联动的效果OC版的简单方便的集成, 滑块 segmentVIew, scrollViewController(Providing an easy way to reach the effect that "the segment scrolls with the content")

License: MIT License

Objective-C 99.72% Ruby 0.28%

zjscrollpageview's Introduction

ZJScrollPageView

OC版的简单方便的集成网易新闻, 腾讯视频, 头条 等首页的滑块视图联动的效果, segmentVIew, scrollViewController

swift版本的请点这里

注意,如果您需要查看详细的注释, 可以下载swift版本里面, 这里很多地方就没有把注释移过来了


使用示例效果

滚动示例1.gif滚动示例2.gif滚动示例3.gif

滚动示例4.gif滚动示例5.gif滚动示例6.gif

滚动示例7.gif 滚动示例8.gif

tupian1 tupian2.gif tupian3.gif tupian4.gif


可以简单快速灵活的实现上图中的效果


书写思路移步

Requirements

  • iOS 7.0+

Installation

  • ###直接将下载文件的ZJScrollPageView文件夹下的文件拖进您的项目中然后#import "ZJScrollPageView.h"就可以使用了

使用cocoaPods, 在你项目的Podfile文件里面添加 pod ZJScrollPageView(未更新)

usage

特别说明

因为大家可能会复用同一个controller来显示内容

  • 在对应的controller的viewWillAppear()等生命周期里面可以根据不同的title来显示不同的内容或者刷新视图

  • 请注意: 如果你希望所有的子控制器的view的系统生命周期方法被正确的调用

  • 请重写父控制器的'shouldAutomaticallyForwardAppearanceMethods'方法 并且返回NO

  • 当然如果你不做这个操作, 子控制器的生命周期方法将不会被正确的调用

  • 如果你仍然想利用子控制器的生命周期方法, 请使用'ZJScrollPageViewChildVcDelegate'提供的代理方法

  • 或者'ZJScrollPageViewDelegate'提供的代理方法


更新说明

  • 2016/05/26 新增了一个通知ScrollPageViewDidShowThePageNotification, 你可以监听这个通知来获取到正在显示的页数, 使用的示例可以参照 ZJSegmentStyle.h里面的说明
  • 2016/05/27 增加了一个style属性 segmentViewBounces, 来设置segmentView是否有弹性
  • 2016/05/27 增加了一个style属性 scrollContentView, 来设置contentView是否能滑动
  • 2016/06/12 增加了一个分类, 提供了 scrollPageParentViewController属性, 方便在每个界面获取到父控制器
  • 2016/06/29 更改了初始化方法, 改为了使用代理来传递相关的自控制器 方便动态更新
  • 2016/06/30 新增加了子控制器遵守的协议ZJScrollPageViewChildVcDelegate, 用于页面出现的时候加载数据
  • 2016/08/21 增加了可以显示图片, 和设置图片的不同位置的功能
  • 2016/10/28 修复一直bug, 保证了子控制器的生命周期方法被正确调用.

可以设置的style效果

/** 是否显示遮盖 默认为NO */
@property (assign, nonatomic, getter=isShowCover) BOOL showCover;
/** 是否显示滚动条 默认为NO*/
@property (assign, nonatomic, getter=isShowLine) BOOL showLine;
/** 是否缩放标题 默认为NO*/
@property (assign, nonatomic, getter=isScaleTitle) BOOL scaleTitle;
/** 是否滚动标题 默认为YES 设置为NO的时候所有的标题将不会滚动, 并且宽度会平分 和系统的segment效果相似 */
@property (assign, nonatomic, getter=isScrollTitle) BOOL scrollTitle;
/** segmentView是否有弹性 默认为NO*/
@property (assign, nonatomic, getter=isSegmentViewBounces) BOOL segmentViewBounces;
/** 是否颜色渐变 默认为NO*/
@property (assign, nonatomic, getter=isGradualChangeTitleColor) BOOL gradualChangeTitleColor;
/** 是否显示附加的按钮 默认为NO*/
@property (assign, nonatomic, getter=isShowExtraButton) BOOL showExtraButton;
/** 内容view是否能滑动 默认为YES*/
@property (assign, nonatomic, getter=isScrollContentView) BOOL scrollContentView;
/** 设置附加按钮的背景图片 默认为nil*/
@property (strong, nonatomic) NSString *extraBtnBackgroundImageName;
/** 滚动条的高度 默认为2 */
@property (assign, nonatomic) CGFloat scrollLineHeight;
/** 滚动条的颜色 */
@property (strong, nonatomic) UIColor *scrollLineColor;
/** 遮盖的颜色 */
@property (strong, nonatomic) UIColor *coverBackgroundColor;
/** 遮盖的圆角 默认为14*/
@property (assign, nonatomic) CGFloat coverCornerRadius;
/** 遮盖的高度 默认为28*/
@property (assign, nonatomic) CGFloat coverHeight;
/** 标题之间的间隙 默认为15.0 */
@property (assign, nonatomic) CGFloat titleMargin;
/** 标题的字体 默认为14 */
@property (strong, nonatomic) UIFont *titleFont;
/** 标题缩放倍数, 默认1.3 */
@property (assign, nonatomic) CGFloat titleBigScale;
/** 标题一般状态的颜色 */
@property (strong, nonatomic) UIColor *normalTitleColor;
/** 标题选中状态的颜色 */
@property (strong, nonatomic) UIColor *selectedTitleColor;
/** segmentVIew的高度, 这个属性只在使用ZJScrollPageVIew的时候设置生效 */
@property (assign, nonatomic) CGFloat segmentHeight;

一. 使用ScrollPageView , 提供了各种效果的组合,但是不能修改segmentView和ContentView的相对位置,两者是结合在一起的

- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"效果示例";

//必要的设置, 如果没有设置可能导致内容显示不正常
self.automaticallyAdjustsScrollViewInsets = NO;

ZJSegmentStyle *style = [[ZJSegmentStyle alloc] init];
//显示遮盖
style.showCover = YES;
style.segmentViewBounces = NO;
// 颜色渐变
style.gradualChangeTitleColor = YES;
// 显示附加的按钮
style.showExtraButton = YES;
// 设置附加按钮的背景图片
style.extraBtnBackgroundImageName = @"extraBtnBackgroundImage";

self.titles = @[@"新闻头条",
                @"国际要闻",
                @"体育",
                @"**足球",
                @"汽车",
                @"囧途旅游",
                @"幽默搞笑",
                @"视频",
                @"无厘头",
                @"美女图片",
                @"今日房价",
                @"头像",
                ];
// 初始化
CGRect scrollPageViewFrame = CGRectMake(0, 64.0, self.view.bounds.size.width, self.view.bounds.size.height - 64.0);
ZJScrollPageView *scrollPageView = [[ZJScrollPageView alloc] initWithFrame:scrollPageViewFrame segmentStyle:style titles:_titles parentViewController:self delegate:self];
self.scrollPageView = scrollPageView;
// 额外的按钮响应的block
__weak typeof(self) weakSelf = self;


self.scrollPageView.extraBtnOnClick = ^(UIButton *extraBtn){
    weakSelf.title = @"点击了extraBtn";
    NSLog(@"点击了extraBtn");
    
};
[self.view addSubview:self.scrollPageView];

}

代理方法

- (NSInteger)numberOfChildViewControllers {
return self.titles.count;// 传入页面的总数, 推荐使用titles.count
}

- (UIViewController *)childViewController:(UIViewController *)reuseViewController forIndex:(NSInteger)index {

UIViewController *childVc = reuseViewController;
// 这里一定要判断传过来的是否是nil, 如果为nil直接使用并返回
// 如果不为nil 就创建
if (childVc == nil) {
    childVc = [UIViewController new];
    
    if (index%2 == 0) {
        childVc.view.backgroundColor = [UIColor redColor];
    } else {
        childVc.view.backgroundColor = [UIColor cyanColor];

    }
    
}
return childVc;
}

二 使用 ZJScrollSegmentView 和 ZJContentView, 提供相同的效果组合, 但是同时可以分离开segmentView和contentView,可以单独设置他们的frame, 使用更灵活

- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"效果示例";

//必要的设置, 如果没有设置可能导致内容显示不正常
self.automaticallyAdjustsScrollViewInsets = NO;
self.childVcs = [self setupChildVc];
// 初始化
[self setupSegmentView];
[self setupContentView];

}

setupSegmentView

    // 注意: 一定要避免循环引用!!
__weak typeof(self) weakSelf = self;
ZJScrollSegmentView *segment = [[ZJScrollSegmentView alloc] initWithFrame:CGRectMake(0, 64.0, 160.0, 28.0) segmentStyle:style titles:titles titleDidClick:^(UILabel *label, NSInteger index) {
    
    [weakSelf.contentView setContentOffSet:CGPointMake(weakSelf.contentView.bounds.size.width * index, 0.0) animated:YES];
    
}];
// 自定义标题的样式
segment.layer.cornerRadius = 14.0;
segment.backgroundColor = [UIColor redColor];
// 当然推荐直接设置背景图片的方式
//    segment.backgroundImage = [UIImage imageNamed:@"extraBtnBackgroundImage"];

self.segmentView = segment;
self.navigationItem.titleView = self.segmentView;

setupContentView

    ZJContentView *content = [[ZJContentView alloc] initWithFrame:CGRectMake(0.0, 64.0, self.view.bounds.size.width, self.view.bounds.size.height - 64.0) segmentView:self.segmentView parentViewController:self delegate:self];
self.contentView = content;
[self.view addSubview:self.contentView];

代理方法

- (NSInteger)numberOfChildViewControllers {
return self.titles.count;
}

- (UIViewController *)childViewController:(UIViewController *)reuseViewController forIndex:(NSInteger)index {
UIViewController *childVc = reuseViewController;
if (childVc == nil) {
    childVc = self.childVcs[index];
    
    if (index%2 == 0) {
        childVc.view.backgroundColor = [UIColor redColor];
    } else {
        childVc.view.backgroundColor = [UIColor cyanColor];
        
    }
    
}
return childVc;
}

这是我写的<iOS自定义控件剖析>这本书籍中的一个demo, 如果你希望知道具体的实现过程和其他的一些常用效果的实现, 那么你应该能轻易在网上下载到免费的盗版书籍.

当然作为本书的写作者, 还是希望有人能支持正版书籍. 如果你有意购买书籍, 在这篇文章中, 介绍了书籍中所有的内容和书籍适合阅读的人群, 和一些试读章节, 以及购买链接. 在你准备购买之前, 请一定读一读里面的说明. 否则, 如果不适合你阅读, 虽然书籍售价35不是很贵, 但是也是一笔损失.

如果你希望联系到我, 可以通过简书联系到我

License

ScrollPageView is released under the MIT license. See LICENSE for details.

zjscrollpageview's People

Contributors

bryant1410 avatar jasnig avatar onekyle 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  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

zjscrollpageview's Issues

NSLog

NSLog 到处打印

预加载当前页的前一页和后一页机制

非常好的库, 相见恨晚吖

:D

如果在滑动时加载将要显示的页, 可能会有些卡顿, 可否增加一个 preload page 的机制, 滑动停止后,预加载当前页的前一页或者后一页, 我会看看源码, 如果我能实现就在下面说说我的思路

不支持新的 Timer API

现象:
调用接口 [NSTimer scheduledTimerWithTimeInterval:repeats:block:] 后闪退。

提示错误 :[NSTimer scheduledTimerWithTimeInterval:repeats:block:]: unrecognized selector sent to class 0x3995ced4

建议:
应该是没有适配新的 API (iOS 10),楼主可以考虑适配下就更完美了。

颜色渐变导致程序直接崩溃

我把字体颜色这么设置
_normalTitleColor = [UIColor blackColor];
_selectedTitleColor = [UIColor grayColor];
导致程序直接崩了.这个bug很严重..请尽快修复.

微博个人界面 bug

微博个人界面 如果ZJPageTableViewController cell个数很多,比如说30个,在向上滑动的过程中最下面的几个cell会展示不出来
image

autolayout 排版错乱

能支持一下 autolayout么,嵌套用autolayout布局的界面,取到的self.view.frame 是错误的。

给个建议,增加两个回调

建议增加 1回调已经选中某个标签的viewController(模仿系统的tabbar, didSelectViewChontroller)
2. 滑动到某个viewController的回调

因为,现在有个需求:4个vc公用某一个状态view, 但是会根据对应的VC更新状态。现在尝试自己增加这样的回调

建议优化

为了实现点击状态栏可以滚动到顶部,建议在
ZJContentView.m 225行添加 “collectionView.scrollsToTop = NO;”

ZJScrollSegmentView.m 551行 添加 “scrollView.scrollsToTop = NO;”

ios 10 isFirstTime 失效

  • (void)setUpWhenViewWillAppearForTitle:(NSString *)title forIndex:(NSInteger)index firstTimeAppear:(BOOL)isFirstTime {
    }

希望作者及时更新。万分感谢。

崩溃 提示:设置普通状态的文字颜色时 请使用RGB空间的颜色值 是什么问题

// 渐变
style.gradualChangeTitleColor = YES;
// 遮盖背景颜色
style.coverBackgroundColor = [UIColor whiteColor];
// style.coverBackgroundColor = [UIColor redColor];
//标题一般状态颜色 --- 注意一定要使用RGB空间的颜色值
style.normalTitleColor = [UIColor blackColor];
//标题选中状态颜色 --- 注意一定要使用RGB空间的颜色值
style.selectedTitleColor = [UIColor redColor];
经常崩溃,标题所示文字

发现一个小bug

发现一个bug,手指快速滑动时,这个时候在用手点击一个tab,之前滑动到的tab 状态没有取消选中状态。

会有手势冲突 和 抽屉的框架

继承collectionView的类

  • (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
    if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
    UIPanGestureRecognizer *pan = (UIPanGestureRecognizer *)gestureRecognizer;
    if ([pan translationInView:self].x > 0.0f && self.contentOffset.x == 0.0f) {
    return NO;
    }
    }
    return [super gestureRecognizerShouldBegin:gestureRecognizer];
    }

把它换成
// 用于处理重用和内容的显示
@Property (weak, nonatomic) CustomCollectionView *collectionView;

学习学习 😄

朋友,最近新需求需要使用这种框架,写到一半遇到一些问题。发现你的框架挺好的,借鉴了一些,特此感谢。

frame布局的局限性

框架挺好的,赞赞赞,要是能改成约束布局那就更好了,因为frame布局并不适应某些特殊场景,比如无法适配阿拉伯语从右到左的阅读习惯..

复用问题

可以支持复用么,如果我有300个卡片的话,还能使用么?
或者说我的滑动浏览视图,有多少个数据源我是不确定的.

可以写一个频道的排序界面吗

或者说一下思路,带有本地缓存的,重新启动仍然按照退出时的顺序显示,和NewsChannel框架类似,不过是push另一个界面的,NewsChannel没开源,不能改,好扯淡NewsChannel

底部滑块bug

快速滑动时 有时会出现残影 (不滚动标题 ,显示滚动条, 颜色渐变的模式下会这样)

在设置3个title的情况,点击中间的title后,segmentBar出现不响应的情况

经排查,pod install安装的0.4.0版本与git clone下来的不一样
通过pod安装的代码,在ZJScrollSegmentView.m的adjustTitleOffSetToCurrentIndex:方法里有userInteractionEnabled属性相关的设置(问题就是出在将userInteractionEnabled设为NO之后,没有将起设为YES),但是git clone下来的代码里是去掉了对userInteractionEnabled属性的操作的。可否将最新的问题代码推到pod服务器上?

在有tabBar的情况下,内部子VC的View布局会贯穿底部tabBar

测试如下:


    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    UITabBarController *tab = [[UITabBarController alloc]init];
    ZJVc1Controller *VC1 = [[ZJVc1Controller alloc]init];
    ZJVc2Controller *VC2 = [[ZJVc2Controller alloc]init];
    ZJVc3Controller *VC3 = [[ZJVc3Controller alloc]init];
    ZJVc4Controller *VC4 = [[ZJVc4Controller alloc]init];
    
    UINavigationController *nav1 = [[UINavigationController alloc]initWithRootViewController:VC1];
    UINavigationController *nav2 = [[UINavigationController alloc]initWithRootViewController:VC2];
    UINavigationController *nav3 = [[UINavigationController alloc]initWithRootViewController:VC3];
    UINavigationController *nav4 = [[UINavigationController alloc]initWithRootViewController:VC4];
    
    [tab addChildViewController:nav1];
    [tab addChildViewController:nav2];
    [tab addChildViewController:nav3];
    [tab addChildViewController:nav4];
    
    self.window.rootViewController = tab;
    [self.window makeKeyWindow];

通过视图层可以看到,内部子VC的View布局会贯穿底部tabBar

ios8.0 gesture conflict crash

- (void)commonInit {

    if (self.parentViewController.parentViewController && [self.parentViewController.parentViewController isKindOfClass:[UINavigationController class]]) {
        UINavigationController *navi = (UINavigationController *)self.parentViewController.parentViewController;

        if (navi.interactivePopGestureRecognizer) {
            navi.interactivePopGestureRecognizer.delegate = self;
            [self.collectionView.panGestureRecognizer requireGestureRecognizerToFail:navi.interactivePopGestureRecognizer];
        }
    }
//    // 发布通知 默认为0
//    [self addCurrentShowIndexNotificationWithIndex:0];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveMemoryWarningHander:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
//    [self.collectionView addObserver:self forKeyPath:kContentOffsetOffKey options:NSKeyValueObservingOptionNew context:nil];
}

crash when swipe back to a view then do swipe gesture on this view.
removed the above code is work. but i don't know why ...

视图的生命周期

在子控制器内点击button push、pop回来的时候 , 不走视图的生命周期方法

下载完demo之后会崩溃

之前使用过您的demo 然后今天看到您有更新 移除自己原来工程中的ZJS到废纸篓 然后add新的ZJS到工程中 运行之后出现崩溃
invalid mode 'kCFRunLoopCommonModes' provided to CFRunLoopRunSpecific - break on _CFRunLoopError_RunCalledWithInvalidMode to debug. This message will only appear once per execution.
libc++abi.dylib: terminate_handler unexpectedly threw an exception

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.