IOS 高仿boss直聘---优雅使用UIButton与UIScrollView打造滑动标签

xiaoxiao2021-02-28  121

设计初衷:本工具主要来自个人练手小项目,仿boss直聘。文末有源码地址

先来看设计的效果:

 

 

分析:

1.控件选择分析:顶部为3个标签并且每个标签都有点击事件,控件的选择上有很多种。一般都选择UiButton ,因为这个控件可以直接为其绑定点击事件,换成其他的控件,就需要为其添加手势操作了。

 

2.控件数量的分析:对于这个一个控件,首先应满足扩展性,比如说,在当前这个例子中,是3个标签,万一哪天产品又有了另一个主意,她觉得需要再加一个或是减一个才能体现她的意图,那么这里就需要处理这种情况,不能因为小需求的变动,而又要重新设计一个控件,那样工作效率太低了,也违背了程序设计原则。

在本例中,为了解决这个问题,使用了一个可娈列表保存标题标签,根据列表的个数创建标签

3.底部滑动条的创建:可以使用图片,也可以使用UIView或其子类,设置其背景色即可;

对于平滑滑动可以使用基本动画中的位移动画:代码如下:

 

//private method---线条移动启动动画 -(void) startLineMoveAnimFromValue:(id) fromValue toValue:(id) toValue duration:(CFTimeInterval) time{ self.moveAnimation = [CABasicAnimation animationWithKeyPath:@"position"]; self.moveAnimation.fromValue = fromValue; self.moveAnimation.toValue = toValue; self.moveAnimation.delegate = self; self.moveAnimation.removedOnCompletion = NO; self.moveAnimation.fillMode = kCAFillModeForwards; self.moveAnimation.duration = time; [self.bottomLine.layer removeAllAnimations]; [self.bottomLine.layer addAnimation:self.moveAnimation forKey:@"onStart"]; }

小tips:在使用基本动画时,特别是属性动画,虽然表现位置发生了变化,但其frame属性却没变,这也就是为什么出现,动画执行完毕之后,点击按钮时事件不响应。因为点击的区域根本没有落到按钮身上。

 

4.中间滚动视图的创建:

  滚动视图使用经典的UIScrollView设计 ,UIScrollView的frame尺寸在本例中,width=屏幕宽, height= 屏幕高减去上下导航条的高度。

 

contentSize = width * 标题的数量

滑动的事件,可以实现其滑动协议,也可以使用KVO机制,本例中使用KVO机制来观察x座标的变化。

其代码设置如下:

 

//本接口主要,创建中间滚动视图 -(void)initSegmentView:(NSMutableArray*) views{ if([views count] == 0 ) return; //创建中间的滑动视图 self.segmentScroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0, 42.5, SCREEN_WIDTH, SCREEN_HEIGHT)]; self.segmentScroll.contentSize = CGSizeMake(SCREEN_WIDTH * [self.titleList count], SCREEN_HEIGHT); self.segmentScroll.alwaysBounceHorizontal = YES; self.segmentScroll.pagingEnabled = YES; [self addSubview:self.segmentScroll]; //使用kvo来监听uiscroll的滑动事件,代替它的协议接口 //添加注册实现contentOffset监听 [self.segmentScroll addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil]; [views enumerateObjectsUsingBlock:^(UIView* layout, NSUInteger idx, BOOL * _Nonnull stop) { if(idx > [views count]) *stop = true; [self.segmentScroll addSubview:layout]; }]; }

其中,中间视图也应该用一个列表保存起来,并在外面算好其在UIScrollView中位置,这样才能达到一个标签对应一个视图容器的效果。

 

为了使滑动时标签上的指示条与标签本身也随着发生状态变化(这里主要批颜色与指示条的位置变化)需要在KVO当中监听UIScrollView的contentSize的x座标,其计算代码如下:

 

//-------------------kvo 实现观察主题 ---------------- //对于滑动翻页使用kvo监听机制 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ CGPoint offset = [change[NSKeyValueChangeNewKey] CGPointValue]; CGPoint oldOffset = [change[NSKeyValueChangeOldKey] CGPointValue]; CGFloat oldOffsetX = oldOffset.x; CGFloat deltaOfOffsetX = offset.x - oldOffsetX; [self.bottomLine.layer removeAllAnimations]; CGRect frame = self.bottomLine.frame; frame.origin.x = deltaOfOffsetX / SCREEN_WIDTH * self.itemWidth; self.bottomLine.frame = frame; [self.bottomLine layoutIfNeeded]; self.nCurIndex = deltaOfOffsetX / SCREEN_WIDTH; [self updateTitleBtnStatus:self.nCurIndex]; } -(void)dealloc{ [self.segmentScroll removeObserver:self forKeyPath:@"contentOffset" context:nil]; } //-------------------kvo 实现观察主题 end----------------

 

 

 

 

 

原理分析到此结束,奉送本项目的源码地址:github

 

 

转载请注明原文地址: https://www.6miu.com/read-18571.html

最新回复(0)