iOS 14,切换tabbar,tabbar消失问题
本文主要介绍使用UIBezierPath,CAShapeLayer和CABasicAnimation 来自定义具有动画效果的弹出提示框(AlertView)。
1.在这里alertView继承的是UIWindow,
(1)基本思路是:在自定义的window添加一个子视图UIView,
(2)在view的层上添加一个子层CAShapeLayer,在子层上绘制UIBezierPath路径,往层上添加CABasicAnimation动画,动画按路径运行
(3)往window上添加两个UILabel显示消息标题和内容,添加一个取消按钮和一个确定按钮
2.实现步骤
(1)XSAlertView.h
<span style=”font-size:18px;”>typedef enum : NSInteger{
/**
* 点击确定按钮
*/
XSAlertViewClickOk,
/**
* 点击取消按钮
*/
XSAlertViewClickCancel
} XSAlertViewClickType;
/**
* 提示框的样式
*/
typedef enum : NSInteger {
XSAlertviewStyleDefault, // 默认样式—-成功
XSAlertviewStyleSuccess, // 成功
XSAlertviewStyleFail, // 失败
XSAlertviewStyleWaring // 警告
} XSAlerTviewStyle;
typedef void(^Completion)(XSAlertViewClickType buttonIndex);
@interface XSAlertView : UIWindow
{
}
// 按钮单击回调block
@property (nonatomic,strong)Completion completeBlock;
/**
* 单例
*
* @return 返回XSAlertView对象
*/
+ (id)shared;
/**
* 创建AlertView并展示
*
* @param style 绘制的图片样式
* @param title 警示标题
* @param message 警示内容
* @param cancel 取消按钮标题
* @param ok 确定按钮标题
* @param completion 按钮点击时回调
*
* @return 返回XSAlertView
*/
+ (id)showAlertWithStyle:(XSAlerTviewStyle)style title:(NSString *)title message:(NSString *)message cancelButtonTitle:(NSString *)cancel okButtonTitle:(NSString *)ok completion:(Completion)completion;</span></span>
(2)创建单例,节约内存
<span style=”font-size:18px;”>static XSAlertView *alertView = nil;
+(id)shared {
// 同步锁
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
alertView = [[XSAlertView alloc]init];
});
return alertView;
}</span>
(3)创建UIView,用于绘制logo
<span style=”font-size:18px;”>- (void)_logoInit {
// 移除上一次绘制
[_logoView removeFromSuperview];
_logoView = nil;
// 创建新画布
_logoView = [[UIView alloc]init];
_logoView.center = CGPointMake(self.center.x, self.center.y);
_logoView.bounds = CGRectMake(0.f, 0.f, kScreenWidth / 1.5f, kScreenHeight / 2.5f);
_logoView.backgroundColor = [UIColor colorWithWhite:1.f alpha:0.7f];
_logoView.layer.cornerRadius = 10.f;
_logoView.layer.shadowOffset = CGSizeMake(0.f, 5.f);
_logoView.layer.shadowColor = [UIColor blackColor].CGColor;
_logoView.layer.shadowOpacity = 0.3f; // 不透明度:0表示完全透明
_logoView.layer.shadowRadius = 10.f;
// 保证画布在*底层
if (_titleLabel != nil) {
[self insertSubview:_logoView belowSubview:_titleLabel];
}
else {
[self addSubview:_logoView];
}
}
</span>
(4)往window上添加按钮和标签,此处比较简单,代码简单繁琐,就不列出了。
(5)往_logoView的层上添加层,绘制路径,此处给出绘制提示正确的弹出框的图片代码
<span style=”font-size:18px;”>- (void)_drawRight {
// 初始化画布
[self _logoInit];
// 圆的中心
CGPoint pathCenter = CGPointMake(_logoView.frame.size.width / 2.f, _logoView.frame.size.height / 2.f – 50);
// 画圆(360度的弧线)
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:pathCenter radius:40.f startAngle:0 endAngle:M_PI * 2 clockwise:YES];
// 勾的起点坐标
CGFloat x = _logoView.frame.size.width / 2.5f + 5.f;
CGFloat y = _logoView.frame.size.height / 2.f – 45.f;
path.lineCapStyle = kCGLineCapRound;
path.lineJoinStyle = kCGLineCapRound;
// 画勾的起点
[path moveToPoint:CGPointMake(x, y)];
[path addLineToPoint:CGPointMake(x + 10.f, y + 10.f)];
[path addLineToPoint:CGPointMake(x + 35.f, y – 20.f)];
// 新建层
CAShapeLayer *layer = [[CAShapeLayer alloc]init];
layer.fillColor = [UIColor clearColor].CGColor;
layer.strokeColor = [UIColor greenColor].CGColor;
layer.lineWidth = 5.f;
layer.path = path.CGPath;
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@”strokeEnd”];
animation.fromValue = @0;
animation.toValue = @1;
animation.duration = 0.5f;
[layer addAnimation:animation forKey:@”strokeEnd”];
[_logoView.layer addSublayer:layer];
</span>
在这里值得一提的是,CAshapeLayer的strokeStart,strokeEnd与CABasicAnimation 的fromValue,toValue的用法和做出的效果下面是我个人对这个的总结:
<span style=”font-size:18px;”>1 keyPath = strokeStart 动画的fromValue = 0,toValue = 1
strokeEnd默认为1,strokeStart从 0 到 1 ,strokeStart = 0 时有一条完整的路径,strokeStart = 1 时 路径消失,效果就是一条从路径起点到终点慢慢的消失
2 keyPath = strokeStart 动画的fromValue = 1,toValue = 0
strokeEnd默认为1,strokeStart从 1 到 0 ,strokeStart = 1 时无路径,strokeStart = 0 时 画出一条完整的路径,效果就是一条从路径终点到起点慢慢的出现
3 keyPath = strokeEnd 动画的fromValue = 0,toValue = 1
strokeStart默认为0,strokeEnd从 0-1,strokeEnd=0 时,无路径,strokeEnd=1 时,一条完整路径。效果就是一条从路径起点到终点慢慢的出现
4 keyPath = strokeEnd 动画的fromValue = 1,toValue = 0
效果就是反方向路径慢慢消失</span>
(6)对类方法 的实现
<span style=”font-size:18px;”>/**
* 创建AlertView并展示
*
* @param style 绘制的图片样式
* @param title 警示标题
* @param message 警示内容
* @param cancel 取消按钮标题
* @param ok 确定按钮标题
* @param completion 按钮点击时回调
*
* @return 返回XSAlertView
*/</span>
<pre name=”code” class=”objc”><span style=”font-size:18px;”>+(id)showAlertWithStyle:(XSAlerTviewStyle)style title:(NSString *)title message:(NSString *)message cancelButtonTitle:(NSString *)cancel okButtonTitle:(NSString *)ok completion:(Completion)completion {
switch (style) {
// 成功、默认
case XSAlertviewStyleDefault:
case XSAlertviewStyleSuccess:
[[self shared] _drawRight];
break;
// 失败
case XSAlertviewStyleFail:
[[self shared] _drawWrong];
break;
// 警告
case XSAlertviewStyleWaring:
[[self shared] _drawWaring];
default:
break;
}
[[self shared] _addButtonTitleWithCancle:cancel OK:ok];
[[self shared] _addTitle:title message:message];
[[self shared] setCompleteBlock:nil];//释放掉之前的Block
[[self shared] setCompleteBlock:completion];
[[self shared] setHidden:NO];//设置为不隐藏
return [self shared];
</span>
}
(7) *后调用我们自己写的弹出框
<span style=”font-size:18px;”>- (void)show:(UIButton *)button {
NSString * title = nil;
NSString * message = nil;
NSString * cancle = @”取消”;
NSString * ok = @”确定”;
switch (button.tag+1) {
// 成功
case XSAlertviewStyleSuccess:
case XSAlertviewStyleDefault:
title = @”温馨提示”;
message = @”登录成功”;
cancle = nil;
break;
// 失败
case XSAlertviewStyleFail:
title = @”错误提示”;
message = @”您输入的号码有误。”;
break;
// 警告
case XSAlertviewStyleWaring:
title = @”警告”;
message = @”您确定要开抢吗!!”;
default:
break;
}
//为成员变量Window赋值则立即显示Window
_alertWindow = [XSAlertView showAlertWithStyle:button.tag+1 title:title message:message cancelButtonTitle:cancle okButtonTitle:ok completion:^(XSAlertViewClickType buttonIndex) {
if (buttonIndex == 0) {
NSLog(@”确定”);
// …
}
else {
NSLog(@”取消”);
// …
}
//Window隐藏
_sheetWindow.hidden = YES;
//置为nil,释放内存
_sheetWindow = nil;
}];
}
</span>
*终的效