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实现思路
首先是文字的显示,可以看出是一个label,但是文字还有背景所以可以考虑背景是一张半透明的view,上面叠加了label。接着是内容的淡出效果,显示一段时间后内容自动消失,可以看到这是定时器的功能。
实现功能前,有几种思路:
一种是继承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
实现部分
#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];
//执行显示动画
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
/**
* 根据给定的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
这个函数,其执行了以下操作:
- 生成一个toastVie作为底部背景view
- 生成一个objc toastLabel作为文字显示label
- 调整两者的布局关系,注意这里使用到了masonry
- 执行显示动画[UIView animateWithDuration:0.5 animations:block]
- 执行动画后开启定时器计时,时间到后执行[toastView removeFromSuperview]
对比这三种方式,
第一种方法,可能是最容易想到的,但也是最容易否决的,因为要复用起来非常蛋疼,代码的破碎程度太高。
第二种方法可行,复用程度高,也可扩展,但是项目中应该避免使用单例,因为一旦你使用了单例,这个单例就会一直存在于整个应用的生命周期,占这么点内存虽然没啥事,但就是不爽。
第三种方法,完美地解决了前两个问题,即可以高度复用,而且不会一直占用内存,无痛使用,只需一行代码。