toast效果圖

showtoast.gif
toast用法
- (void)replaceTabBar{
SUPCustomTabBar *tabBar = [[SUPCustomTabBar alloc] init];
__weak typeof(self) wSelf = self;
tabBar.pressPlusBtnBlock = ^(void){
//測試toast
[wSelf.view sup_makeToast:@"哈哈哈哈哈哈哈哈"];
};
[self setValue:tabBar forKey:@"tabBar"];
}
toast實現(xiàn)思路
首先是文字的顯示,可以看出是一個label,但是文字還有背景所以可以考慮背景是一張半透明的view,上面疊加了label。接著是內容的淡出效果,顯示一段時間后內容自動消失,可以看到這是定時器的功能。
實現(xiàn)功能前,有幾種思路:
一種是繼承UIView,命名為ToastView,然后令其添加到當前顯示的currentView上,同時開啟定時器的功能,設定時間比如1s后就把這張ToastView給removeFromSuperview,下次用時再加上去,不用時再remove。
另一種思路是寫個單例類,每次要調用,直接通過[ToastView showToast]來顯示,單例內部做好定時器的操作就行。
還有一種思路,寫UIView的分類。這樣如果要用currentView來顯示,直接[currentView showToast],定時器操作也寫在分類中。
接口部分
@interface UIView (Toast)
-(void) sup_makeToast:(NSString *)toast;
-(void) sup_makeToast:(NSString *)toast duration:(NSTimeInterval)duration;
-(void) sup_makeToast:(NSString *)toast duration:(NSTimeInterval)duration position:(SUPToastPosition) position;
@end
實現(xiàn)部分
#pragma mark - Toast
const double SUP_TOAST_DURATION = 1;
@implementation UIView (Toast)
-(void)sup_makeToast:(NSString *)toast{
[self sup_makeToast:toast duration:SUP_TOAST_DURATION];
}
-(void)sup_makeToast:(NSString *)toast duration:(NSTimeInterval)duration{
[self sup_makeToast:toast duration:duration position:SUPToastPositionBottom];
}
-(void) sup_makeToast:(NSString *)toast duration:(NSTimeInterval)duration position:(SUPToastPosition) position{
//底部的toastView
UIView *toastView = [[UIView alloc] init];
toastView.layer.cornerRadius = 10;
toastView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.8];
//顯示的文字
UILabel *toastLabel = [[UILabel alloc] init];
toastLabel.text = toast;
toastLabel.textColor = [UIColor whiteColor];
toastLabel.textAlignment = NSTextAlignmentCenter;
[toastView addSubview:toastLabel];
[toastLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(toastView);
}];
[self addSubview:toastView];
[toastLabel layoutIfNeeded];
//設置底部view的大小和位置
toastView.sup_width = toastLabel.sup_width + 30;
toastView.sup_height = toastLabel.sup_height + 20;
toastView.center = [self sup_centerByPosition:position];
//執(zhí)行顯示動畫
toastView.alpha = 0.0;
[UIView animateWithDuration:0.5 animations:^{
toastView.alpha = 1;
} completion:^(BOOL finished) {
NSTimer *timer = [NSTimer timerWithTimeInterval:duration target:self selector:@selector(sup_endUpShowingToast:) userInfo:toastView repeats:false];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}];
}
#pragma mark - private methods
/**
* 根據(jù)給定的position找中心點
*
* @param position 枚舉類型,SUPToastPosition 上中下
*
* @return 中心點
*/
-(CGPoint) sup_centerByPosition:(SUPToastPosition)position{
CGPoint center = CGPointZero;
switch (position) {
case SUPToastPositionTop:
center = CGPointMake(self.sup_width / 2, 100);
break;
case SUPToastPositionMiddle:
center = CGPointMake(self.sup_width / 2, self.sup_height / 2);
break;
case SUPToastPositionBottom:
center = CGPointMake(self.sup_width / 2, self.sup_height - 100);
break;
default:
break;
}
return center;
}
/**
* 定時器時間到調用的方法,用于消除toastView
*
* @param timer 傳入該定時器,主要為了獲得userInfo
*/
-(void) sup_endUpShowingToast:(NSTimer *)timer{
UIView *toastView = (UIView *)timer.userInfo;
[UIView animateWithDuration:0.5 animations:^{
toastView.alpha = 0;
} completion:^(BOOL finished) {
[toastView removeFromSuperview];
}];
}
@end
代碼的主要部分就是
-(void) sup_makeToast:(NSString *)toast duration:(NSTimeInterval)duration position:(SUPToastPosition) position
這個函數(shù),其執(zhí)行了以下操作:
- 生成一個toastVie作為底部背景view
- 生成一個objc toastLabel作為文字顯示label
- 調整兩者的布局關系,注意這里使用到了masonry
- 執(zhí)行顯示動畫[UIView animateWithDuration:0.5 animations:block]
- 執(zhí)行動畫后開啟定時器計時,時間到后執(zhí)行[toastView removeFromSuperview]
對比這三種方式,
第一種方法,可能是最容易想到的,但也是最容易否決的,因為要復用起來非常蛋疼,代碼的破碎程度太高。
第二種方法可行,復用程度高,也可擴展,但是項目中應該避免使用單例,因為一旦你使用了單例,這個單例就會一直存在于整個應用的生命周期,占這么點內存雖然沒啥事,但就是不爽。
第三種方法,完美地解決了前兩個問題,即可以高度復用,而且不會一直占用內存,無痛使用,只需一行代碼。