在某些情况下需要扩展第三方库的行为。对于简单的修改没有什么问题,对于复杂的修改(核心功能),我们首先要做的就是深入库的源代码中理解原理,查找线索,不断测试,最后完成我们的扩展。
下面举一例:Github中的MZTimerLabel定时器库
该定时器很简练,但功能很强大,其中包含了正计时和倒计时功能。不过我还希望增加一个新功能,就是按秒的个数而不是时间格式来显示。
比如现在已计时1分半钟,按照常规时间显示应该为:00:01:30,如果按照个数显示则为:000090.
首先查看库文档,为用户考虑周全的库都会有一定自定义行为,索性这个也不例外,我们在其MZTimerLabelDelegate代理中发现如下方法:
func timerLabel(_ timerLabel: MZTimerLabel!, customTextToDisplayAtTime time: TimeInterval) -> String!
我们马上来实现它:
///自定义按秒个数返回计时器显示内容 func timerLabel(_ timerLabel: MZTimerLabel!, customTextToDisplayAtTime time: TimeInterval) -> String! { guard !isDisplayWithClock else { //返回0长度字符串表示已默认时间格式显示 return "" } let ftString = String(format: "%06d", Int(time)) return ftString }
我怎么知道返回”“字符串表示按默认时间格式显示?打开其源代码MZTimerLabel.m文件,经过简单查看,发现所有更新Label的操作都在-(void)updateLabel方法中;进入该方法,找到下面一段:
if ([_delegate respondsToSelector:@selector(timerLabel:customTextToDisplayAtTime:)]) { NSTimeInterval atTime = (_timerType == MZTimerLabelTypeStopWatch) timeDiff : ((timeUserValue - timeDiff) < 0 0 : (timeUserValue - timeDiff)); NSString *customtext = [_delegate timerLabel:self customTextToDisplayAtTime:atTime]; if ([customtext length]) { self.timeLabel.text = customtext; //#1 }else{ self.timeLabel.text = [self.dateFormatter stringFromDate:timeToShow]; //#2 } }
很清楚!如果用户实现了代理方法则调用,并且检查其返回的值:如果为0则调用默认格式(第#2行),否则使用用户的格式(第#1行)
不过还有一个问题:在Timer暂停时修改显示格式不会立即在界面中变化,非要等到计时器启动后显示才发生变化。
只是一个小问题,不过如果不作出修改:
1.用户体验会有下降
2.强迫症的猫受不了(主要原因…)
所以我们还是尝试修改一下,在Timer暂停时要想显示界面发生变化,我们得仔细检查updateLabel方法。该方法代码实现比较长,这里就不贴出来了。关键是阅读后可以理解其更新界面的逻辑,我们很快就可以自己写一个新的出来:
///在计时器暂停时刷新Label的显示! -(void)pauseUpdate{ //如果正在计时则退出 if(_counting) return; NSTimeInterval timeDiff = [pausedTime timeIntervalSinceDate:startCountDate]; NSDate *timeToShow = [NSDate date]; if(_timerType == MZTimerLabelTypeStopWatch){ timeToShow = [date1970 dateByAddingTimeInterval:(!startCountDate)0:timeDiff]; }else{ timeToShow = [timeToCountOff dateByAddingTimeInterval:-timeDiff]; } if ([_delegate respondsToSelector:@selector(timerLabel:customTextToDisplayAtTime:)]) { NSTimeInterval atTime = (_timerType == MZTimerLabelTypeStopWatch) timeDiff : ((timeUserValue - timeDiff) < 0 0 : (timeUserValue - timeDiff)); NSString *customtext = [_delegate timerLabel:self customTextToDisplayAtTime:atTime]; if ([customtext length]) { self.timeLabel.text = customtext; }else{ self.timeLabel.text = [self.dateFormatter stringFromDate:timeToShow]; } } }
现在OK了,我们来测试一下:
完美达到我们的效果!打完收工 ;)