接着上篇文章我们继续写PageTitleView和PageContentView用代理进行通讯,这是项目的github地址 ScrollViewDemo
当我们点击PageTittleView上的titleLabel是 虽然位置颜色都发生了改变,但是pageContentView并没有发生改变,所以我采取了用代理协议
//PageTitleView.h
@protocol PageTitleViewDelegate <NSObject>
-(void) pageTitletView:(id)contentView selectedIndex:(NSInteger)targetIndex;
@end
@property(assign,nonatomic)id<PageTitleViewDelegate>delegate;
@end
然后我们点击之后就可以通过这个代理向PageContentView“取得联系”
//PageTitleView.m
-(void)titleLabelClickedWithGes:(UITapGestureRecognizer*)ges{
if (ges.view) {
/*
...
中间省略了很多无关代码
...
*/
[self.delegate pageTitletView:self selectedIndex:self.currentIndex];
//代理方法
}else{
return;
}
}
还有设置一些两者"联系"的所需线路:暴露的方法
//PageContentView.h
@interface PageContentView : UIView
/*
省略无关属性及方法
*/
-(void)setCurrentIndex:(NSInteger)index;//向外暴露的方法,用于点击titleLabel后所调用设置当前PageContentView的子视图
@end
当点击title的时候 pageContentView的视图必须发生改变,PageContentView的CollectionViews的偏离位置发生改变
-(void)setCurrentIndex:(NSInteger)index{
CGFloat offsetX = index*self.collectionView.frame.size.width;
[self.collectionView setContentOffset:CGPointMake(offsetX, 0)];
}
然后就是在主控制器实现该代理
-(void)pageTitletView:(id)contentView selectedIndex:(NSInteger)targetIndex{
[self.pageContentView setCurrentIndex:targetIndex];
}
接着当我们滑动pageContentView时PageTitleView的titleLabel也会发生相对的改变 所以与上面类似 我们还要在PageContentView声明代理协议
@protocol PageContentViewDelegate <NSObject>
-(void) pageContentView:(id)contentView progress:(CGFloat)progress sourceIndex:(NSInteger)sourceIndex targetIndex:(NSInteger)targetIndex;
@end
@interface PageContentView : UIView
@property(assign,nonatomic)id<PageContentViewDelegate>delegate;
/*
省略部分分无关的属性和方法
*/
@end
这次是滑动发生了改变,所以要记录一开始的位置的横坐标
@interface PageContentView ()<UICollectionViewDataSource,UICollectionViewDelegate>
@property(nonatomic,assign)CGFloat startOffset;
@end
还要实现Collection的scrollViewDidScroll:(UIScrollView *)scrollView和scrollViewWillBeginDragging:(UIScrollView *)scrollView的代理方法。
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
//获取数据
CGFloat progress = 0;
NSInteger sourceIndex = 0;
NSInteger targetIndex = 0;
//判断左右滑
CGFloat currentOffsetX = scrollView.contentOffset.x;
CGFloat scrollViewW = scrollView.bounds.size.width;
if (currentOffsetX>self.startOffset) {
//左滑
progress = currentOffsetX/scrollViewW-floor(currentOffsetX/scrollViewW);
sourceIndex = (NSInteger)(currentOffsetX/scrollViewW);
targetIndex = sourceIndex+1;
if (targetIndex>=self.childVcs.count) {
targetIndex = self.childVcs.count-1;
}
if (currentOffsetX-self.startOffset==scrollViewW) {
progress = 1;
targetIndex = sourceIndex;
}
}else{
//右滑
progress = 1-(currentOffsetX/scrollViewW-floor(currentOffsetX/scrollViewW));
targetIndex = (NSInteger)(currentOffsetX/scrollViewW);
sourceIndex = targetIndex+1;
if (sourceIndex>=self.childVcs.count) {
sourceIndex=self.childVcs.count-1;
}
}
[self.delegate pageContentView:self progress:progress sourceIndex:sourceIndex targetIndex:targetIndex];
}
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
self.startOffset = scrollView.contentOffset.x;
}
当然判断向左滑还是右滑,是进行了一番计算得到的算,需要大家好好理解
当然在PageTitleView也需要提供“联系”接口
@interface PageTitleView : UIView
@property(assign,nonatomic)id<PageTitleViewDelegate>delegate;
/*
省略了部分的无关的方法
*/
-(void)setTitleWithProgress:(CGFloat)progress sourceIndex:(NSInteger)index targetIndex:(NSInteger)index;
@end
当滑动时titleLabel的颜色是渐变的
-(void)titleLabelClickedWithGes:(UITapGestureRecognizer*)ges{
if (ges.view) {
UILabel *currentLabel = (UILabel*)ges.view;
UILabel*oldLabel = self.titleLabels[self.currentIndex];
self.currentIndex = currentLabel.tag;
currentLabel.textColor = [UIColor orangeColor];
oldLabel.textColor = [UIColor darkGrayColor];
CGFloat scrollLineX = currentLabel.tag*self.scrollLine.frame.size.width;
[UIView animateWithDuration:0.15 animations:^{
self.scrollLine.frame = CGRectMake(scrollLineX, self.frame.size.height-kScrollLineH, currentLabel.frame.size.width, 2.0);
}];
[self.delegate pageTitletView:self selectedIndex:self.currentIndex];
}else{
return;
}
}
最后在视图控制器中实现代理
-(void)pageContentView:(id)contentView progress:(CGFloat)progress sourceIndex:(NSInteger)sourceIndex targetIndex:(NSInteger)targetIndex{
[self.pageTitleView setTitleWithProgress:progress sourceIndex:sourceIndex targetIndex:targetIndex];
}
这篇关于用Objective-C实现滚动标题的文章结束了,大家若还有什么问题。欢迎在评论区留言