前言
APP做得好不在于一些細(xì)節(jié)的處理,用戶可以看得到珍促,但是也最容易忽略校镐,我們要提升體驗(yàn)垦细,但是用戶又感覺不到。這篇文章主要處理播放按鈕的動(dòng)畫压恒,以及runtime中Method Swizzling 使用影暴;
我們先來看看效果:
效果很細(xì)微,不容易被用戶察覺探赫,所以長期看也不會(huì)覺得厭煩型宙。
實(shí)現(xiàn)
初始化
按鈕很簡單,我們直接用CAShapeLayer
畫出來期吓,因?yàn)?code>CAShapeLayer有強(qiáng)大的path
屬性所以我選著它
按鈕在暫停的時(shí)候有三條線段早歇,播放的時(shí)候兩條線段。我直接初始化三條線段讨勤;
動(dòng)畫
動(dòng)畫還是直接調(diào)用path屬性
/**
path動(dòng)畫
@param path 變?yōu)榈膒ath
@param duration 持續(xù)時(shí)間
@return 返回動(dòng)畫
*/
- (CABasicAnimation*)animationToPath:(UIBezierPath* )path duration:(NSTimeInterval)duration {
CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
pathAnimation.toValue = (__bridge id)(path.CGPath);
pathAnimation.fillMode = kCAFillModeForwards;
pathAnimation.removedOnCompletion = NO;
pathAnimation.duration = duration;
return pathAnimation;
}
layer3的時(shí)候會(huì)有出現(xiàn)和消失,這里會(huì)做一個(gè)不透明度的動(dòng)畫
/**
不透明度動(dòng)畫
@param layer 要執(zhí)行動(dòng)畫的layer
@param from 從多少開始
@param to 到多少
*/
- (void)opacityAnimationWithLayer:(CALayer*)layer fromValue:(CGFloat)from toValue:(CGFloat)to {
CABasicAnimation *opacityAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
opacityAnimation.toValue = @(to);
opacityAnimation.fromValue = @(from);
opacityAnimation.duration = .2;
opacityAnimation.fillMode = kCAFillModeForwards;
opacityAnimation.removedOnCompletion = NO;
[layer addAnimation:opacityAnimation forKey:nil];
}
動(dòng)畫很簡單接下來是替換系統(tǒng)方法
+(void)load {
SEL actionA = @selector(sendAction:to:forEvent:);
SEL actionB = @selector(__ai__sendAction:to:forEvent:);
//原有的方法
Method aMetod = class_getInstanceMethod([AIPlayerButton class],actionA);
//自定義的方法
Method bMetod = class_getInstanceMethod([AIPlayerButton class], actionB);
//這句是為了保護(hù)系統(tǒng)的方法
BOOL isAdd = class_addMethod([AIPlayerButton class], actionA, method_getImplementation(bMetod), method_getTypeEncoding(bMetod));
if (isAdd) {
class_replaceMethod([AIPlayerButton class], actionB, method_getImplementation(aMetod), method_getTypeEncoding(aMetod));
}else{
method_exchangeImplementations(aMetod, bMetod);
}
}
- (void)__ai__sendAction:(SEL)action to:(nullable id)target forEvent:(nullable UIEvent *)event {
if (self.ignoreEvent) {
return;
}
if (self.acceptEventInterval > 0) {
self.ignoreEvent = YES;
[self performSelector:@selector(setIgnoreEvent:) withObject:@(NO) afterDelay:self.acceptEventInterval];
if (self.isSelected) {
[self changeToPlayingAnimation];
} else {
[self changeToStopAnimation];
}
[self __ai__sendAction:action to:target forEvent:event];
}
}
對(duì)于可以看OC Method Swizzling 使用
源碼已放在GitHub上喜歡的給個(gè)star支持下
源碼位置
參考博客:http://www.cocoachina.com/ios/20150911/13260.html