toast效果圖

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實(shí)現(xiàn)思路
首先是文字的顯示,可以看出是一個(gè)label,但是文字還有背景所以可以考慮背景是一張半透明的view,上面疊加了label。接著是內(nèi)容的淡出效果,顯示一段時(shí)間后內(nèi)容自動(dòng)消失,可以看到這是定時(shí)器的功能。
實(shí)現(xiàn)功能前,有幾種思路:
一種是繼承UIView,命名為ToastView,然后令其添加到當(dāng)前顯示的currentView上,同時(shí)開啟定時(shí)器的功能,設(shè)定時(shí)間比如1s后就把這張ToastView給removeFromSuperview,下次用時(shí)再加上去,不用時(shí)再remove。
另一種思路是寫個(gè)單例類,每次要調(diào)用,直接通過[ToastView showToast]來顯示,單例內(nèi)部做好定時(shí)器的操作就行。
還有一種思路,寫UIView的分類。這樣如果要用currentView來顯示,直接[currentView showToast],定時(shí)器操作也寫在分類中。
接口部分
@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
實(shí)現(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];
//設(shè)置底部view的大小和位置
toastView.sup_width = toastLabel.sup_width + 30;
toastView.sup_height = toastLabel.sup_height + 20;
toastView.center = [self sup_centerByPosition:position];
//執(zhí)行顯示動(dòng)畫
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找中心點(diǎn)
*
* @param position 枚舉類型,SUPToastPosition 上中下
*
* @return 中心點(diǎn)
*/
-(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;
}
/**
* 定時(shí)器時(shí)間到調(diào)用的方法,用于消除toastView
*
* @param timer 傳入該定時(shí)器,主要為了獲得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
這個(gè)函數(shù),其執(zhí)行了以下操作:
- 生成一個(gè)toastVie作為底部背景view
- 生成一個(gè)objc toastLabel作為文字顯示label
- 調(diào)整兩者的布局關(guān)系,注意這里使用到了masonry
- 執(zhí)行顯示動(dòng)畫[UIView animateWithDuration:0.5 animations:block]
- 執(zhí)行動(dòng)畫后開啟定時(shí)器計(jì)時(shí),時(shí)間到后執(zhí)行[toastView removeFromSuperview]
對比這三種方式,
第一種方法,可能是最容易想到的,但也是最容易否決的,因?yàn)橐獜?fù)用起來非常蛋疼,代碼的破碎程度太高。
第二種方法可行,復(fù)用程度高,也可擴(kuò)展,但是項(xiàng)目中應(yīng)該避免使用單例,因?yàn)橐坏┠闶褂昧藛卫?,這個(gè)單例就會一直存在于整個(gè)應(yīng)用的生命周期,占這么點(diǎn)內(nèi)存雖然沒啥事,但就是不爽。
第三種方法,完美地解決了前兩個(gè)問題,即可以高度復(fù)用,而且不會一直占用內(nèi)存,無痛使用,只需一行代碼。