首页 > 代码库 > 【iOS开发-57】案例改进:block动画、控件的removeFromSuperview、利用layer设置圆角矩形以及代理模式运用

【iOS开发-57】案例改进:block动画、控件的removeFromSuperview、利用layer设置圆角矩形以及代理模式运用

接上述案例,案例改进:【iOS开发-50】利用创建新的类实现代码封装,从而不知不觉实践一个简单的MVC实验,附带个动画


在上述案例中,我们最后实现了一个动画,点击“下载”按钮变成“已下载”不可点击,然后中间出现提示框。


(1)其中有一个小BUG,就是这个提示的透明度变成0之后,这个提示框并没有显示还留在内存中。需要:

[tipsLabel removeFromSuperview];

(2)其次,我们可以用另一个代码实现动画,就是用block,这一次是2个block嵌套。用如下代码实现提示框渐变,并且消失移除:

 [UIView animateWithDuration:2.5 animations:^{
        tipsLabel.alpha=1;
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:2.5 animations:^{
           tipsLabel.alpha=0;
        } completion:^(BOOL finished) {
            [tipsLabel removeFromSuperview];
        }];
    }];

(3)还有一个失误就是:

[self.superview.superview addSubview:tipsLabel];

这里面其实是:

[self.superview addSubview:tipsLabel];

因为,我们的self相当于xib的小图,它加载在ViewController的视图里,所以它的superview就是视图控制器的视图。至于为什么多了一个superview没有报错还正常运作,可想答案,是因为上面已无superview所以没有影响。


(4)增强改进:把提示框变成圆角矩形,用到图层layer。

——首先,需要拿到一个控件的图层进行形状设置。

——然后,需要了解的是,这个图层一般称之为主图层,我们一般不直接在它的上面写东西,而是把其他子图层加载上去,但是这些子图层一般是按照自己的想法显示。这个时候我们的主图层改变后,需要告诉它所有的子图层,要遵守主图层的边界规则,也就是我主图层什么样子什么边界你们就要什么样子。

——第二句和第三句的意思是一样的,只不过一个是对控件的图层的属性进行设置,一个对控件的属性进行设置。

    tipsLabel.layer.cornerRadius=15;
//    tipsLabel.layer.masksToBounds=YES;
    tipsLabel.clipsToBounds=YES;

(5)增强改进:如下代码是通过父子关系找到了视图控制器的视图,然后往里面添加控件,这种父子关系的查找很危险,比如哪一天这种父子关系破坏了,则需要修改代码。

[self.superview addSubview:tipsLabel];


我们可以把视图控制器的视图传递给一个参数,让这个参数来执行。

比如在xibView.h中:

@property (strong,nonatomic) UIView *vcView;

然后在ViewController.m中:(把视图控制器的视图传递给这个参数)

xibView.vcView=self.view;

然后,在xibView.m中:

[self.vcView addSubview:tipsLabel];

这里的self.vcView就是视图控制器的视图。

缺点:这种方法中,这个视图不是很独立,和这个视图控制器耦合度太强,当这个视图控制器不存在时,这个vcView视图也就没法起作用。

再改进:用代理。即这个类自己设定个协议(方法),把视图控制器设置成代理,这样当点击按钮的时候,就通知视图控制器添加这个label。

——在XibView.h中设置协议和代理属性:

#import <UIKit/UIKit.h>
#import "JiuGongGe.h"
@class XibView;//需要导入自己这个类?

//定义一个协议
@protocol JGXibViewDelegate <NSObject>
@optional
-(void)xibViewClickBtn:(XibView *)xibView;
@end

@interface XibView : UIView
//定义一个代理属性
@property(weak,nonatomic)id<JGXibView
@end


——在XibView.m中:

如果代理有这个方法,那么就发送消息给代理(即调用这个方法)

- (IBAction)installClick:(UIButton *)btn {
    //改变按钮文字已经设置为disable
    [btn setTitle:@"已安装" forState:UIControlStateDisabled];
    btn.enabled=NO;
    
    if ([self.delegate respondsToSelector:@selector(xibViewClickBtn:)]) {
        [self.delegate xibViewClickBtn:self];
    }
}


——在代理中(因为添加label是在视图控制器的视图中添加的,所以这些代码应该在视图控制器中,所以把视图控制器设置为代理,具体执行添加操作):

先遵守协议

@interface ViewController ()<JGXibViewDelegate>

在viewDidLoad中设置代理

xibView.delegate=self;

最后实现方法

-(void)xibViewClickBtn:(XibView *)xibView{
    //调用方法创建UILabel
    UILabel *tipsLabel=[XibView tipsView];
    //设置UILabel显示位置
    CGFloat tipW=250;
    CGFloat tipH=30;
    tipsLabel.frame=CGRectMake((self.view.frame.size.width-tipW)/2, self.view.frame.size.height/2, tipW, tipH);
    //设置UILabel文字和背景样式
    JiuGongGe *jiugongge=xibView.jiuGongGe;//这里是关键,把被点击的这个小视图的模型拿出来
    tipsLabel.text=[NSString stringWithFormat:@"%@ 已经安装成功!",jiugongge.name];//取出这个模型的name数据
    tipsLabel.textColor=[UIColor whiteColor];
    tipsLabel.backgroundColor=[UIColor grayColor];
    tipsLabel.font=[UIFont systemFontOfSize:14];
    tipsLabel.layer.cornerRadius=15;
    //    tipsLabel.layer.masksToBounds=YES;
    tipsLabel.clipsToBounds=YES;
    //设置显示时候的动画,透明和不透明的变化
    
    [UIView animateWithDuration:2.5 animations:^{
        tipsLabel.alpha=1;
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:2.5 animations:^{
            tipsLabel.alpha=0;
        } completion:^(BOOL finished) {
            [tipsLabel removeFromSuperview];
        }];
    }];
    [self.view addSubview:tipsLabel];
}

【iOS开发-57】案例改进:block动画、控件的removeFromSuperview、利用layer设置圆角矩形以及代理模式运用