【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];
}
时间: 2024-10-06 18:01:21

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

iOS开发UI篇—自定义瀑布流控件(蘑菇街数据刷新操作)

iOS开发UI篇—自定义瀑布流控件(蘑菇街数据刷新操作) 一.简单说明 使用数据刷新框架: 该框架提供了两种刷新的方法,一个是使用block回调(存在循环引用问题,_ _weak),一个是使用调用. 问题:在进行下拉刷新之前,应该要清空之前的所有数据(在刷新数据这个方法中). 移除正在显示的cell: (1)把字典中的所有的值,都从屏幕上移除 (2)清除字典中的所有元素 (3)清除cell的frame,每个位置的cell的frame都要重新计算 (4)清除可复用的缓存池. 该部分的代码如下: 1

iOS开发UI篇—DatePicker和UIToolBar控件简单介绍

iOS开发UI篇—DatePicker和UIToolBar控件简单介绍 一.Date Picker控件 1.简单介绍: Date Picker显示时间的控件 有默认宽高,不用设置数据源和代理 如何改成中文的? (1)查看当前系统是否为中文的,把模拟器改成是中文的 (2)属性,locale选择地区 如果默认显示不符合需求.时间有四种模式可以设置,在model中进行设置 时间可以自定义(custom). 设置最小时间和最大时间,超过就会自动回到最小时间. 最大的用途在于自定义键盘:弹出一个日期选择器

iOS开发UI篇—自定义瀑布流控件(基本实现)

iOS开发UI篇—自定义瀑布流控件(基本实现) 一.基本实现 说明:在View加载的时候,刷新数据. 1.实现代码 YYViewController.m文件 1 // 2 // YYViewController.m 3 // 06-瀑布流 4 // 5 // Created by apple on 14-7-28. 6 // Copyright (c) 2014年 wendingding. All rights reserved. 7 // 8 9 #import "YYViewControll

iOS开发UI篇—自定义瀑布流控件(蘑菇街实现)

iOS开发UI篇—自定义瀑布流控件(蘑菇街瀑布流) 一.简单说明 关于瀑布流 1.是使用UIScrollView实现的 2.刷新数据(reloadData)方法里面做哪些事情 3.layoutSubviews方法里面做哪些事情 4.模仿UItableView进行设计 完善: 瀑布流控件第一次显示到屏幕上的时候自动的向数据源索要数据,而不需要手动调用.这需要监听View的显示,View的显示有一个方法,叫做willMoveToSuperview:在该方法中直接刷新一次数据即可. 二.把自定义的瀑布

iOS开发UI篇—使用picker View控件完成一个简单的选餐应用 - 文顶顶

原文  http://www.cnblogs.com/wendingding/p/3771047.html iOS开发UI篇—使用picker View控件完成一个简单的选餐应用 一.实现效果 说明: 点击随机按钮,能够自动选取,下方数据自动刷新. 二.实现思路 1.picker view的有默认高度为162,不可修改. 2.显示数据,需要设置数据源,也有两种方式(成为数据源,遵守协议) 3.实现数据源里面的两个方法 1)返回一共有多少列 2)在这一列中一共有多少行 4.通过代理告诉它那一列的哪

iOS开发UI篇—自定义瀑布流控件(接口设计)

iOS开发UI篇—自定义瀑布流控件(接口设计) 一.简单说明 1.关于瀑布流 电商应用要展示商品信息通常是通过瀑布流的方式,因为每个商品的展示图片,长度和商都都不太一样. 如果不用瀑布流的话,展示这样的格子数据,还有一种办法是使用九宫格. 但利用九宫格有一个缺点,那就是每个格子的宽高是一样的,如果一定要使用九宫格来展示,那么展示的商品图片可能会变形. 为了保证商品图片能够按照原来的宽高比进行展示,一般采用的是瀑布流的方式. 2.瀑布流的特点: 由很多的格子组成,但是每个格子的宽度和高速都是不确定

iOS开发UI篇—自定义瀑布流控件(cell的循环利用)

iOS开发UI篇—自定义瀑布流控件(cell的循环利用) 一.简单说明 当滚动的时候,向数据源要cell. 当UIScrollView滚动的时候会调用layoutSubviews在tableView中也是一样的,因此,可以用这个方法来监听scrollView的滚动,可以在在这个地方向数据源索要对应位置的cell(frame在屏幕上的cell). 示例: 当scrollView在屏幕上滚动的时候,离开屏幕的cell应该放到缓存池中去,询问即将(已经)进入到屏幕的cell,对于还没有进入到屏幕的ce

IOS开发学习笔记019-动态创建控件

动态创建控件 一.按钮 二.文本输入框 三.lable标签 注意: 只是简单的拖拽控件会毁了你,所以最好还是手动通过代码创建控件. 如果要通过代码生成按钮的话,可以在系统自带的函数viewDidLoad实现.应为每个控件都对应一个类,所以可以直接通过类创建一个对象,也就是一个控件,然后再逐步设置控件的属性. 下面这些操作基本上都是通用的,在不同的控件下操作基本相同 一.按钮 1.创建对象,这没啥好说的 UIButton *btn = [[UIButton alloc] init]; 2.在显示到

IOS开发--循环引用问题,普通控件为什么用weak,代理为什么用weak,block内用到外面的东

所有的引用计数系统,都存在循环应用的问题. 例如下面的引用关系对象: a创建并引用到了对象b. 对象b创建并引用到了对象c. 对象c创建并引用到了对象b. 这时候b和c的引用计数分别是2和1.当a不再使用b,调用release释放对b的所有权,因为c还引用了b,所以b的引用计数为1,b不会被释放.b不释放,c的引用计数就是1,c也不会被释放.从此,b和c永远留在内存中,造成内存浪费.这种情况,必须打断循环引用,通过其他规则来维护引用关系. 那么普通控件为什么要用weak: 如下图控制器中的Vie