接上述案例,案例改进:【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]; }