延时执行:
使用控件的performSelector...方法,例如用于移除,可以写在一行。
[lab performSelector:@selector(removeFromSuperview) withObject:lab afterDelay:4.0];
圆角的实现:
在iOS6中,只需要设定label.layer.cornerRadius即可实现圆角。
但是iOS7+中,需要将label.layer.masksToBounds设定为YES才行。
这牵扯到图层的概念。
在label内部有多个图层(对象),使用layer拿到的是主层,主层一般是用来容纳其他层。设置完主层的圆角后,子层盖在上面,会把主层的圆角盖住,因此要设置masksToBounds = YES,表示子层全部要遵循主层的边界。
还有一种方法是直接操作控件的clipsToBounds属性,表示剪掉超出边界的部分。
做法一:
lab.layer.masksToBounds = YES; lab.layer.cornerRadius = 10;做法二:
lab.clipsToBounds = YES; lab.layer.cornerRadius = 10;技巧:实现圆形label,尺寸为2R*2R,圆角为R即可。
如果要求在底层的View上面实现一个提示框(label),用父子关系来获取是很危险的,因为可能会改变视图的父子关系。因此使用self.superView直接拿到控制器是不稳定的。
方法一:给子View的控制器增加一个成员变量,用来存储底层View的控制器。这个方法的缺点在于会增加代码的耦合性(子View与底层控制器有粘连,不好移植)。
设计原则:一个独立的自定义View不能跟控制器有联系,为了能被多个控制器使用。
方法二:在子View的.h中暴露按钮,在底层View的控制器内给按钮addTarget,使得可以调用底层View的方法。由于暴露了内部内容,那么底层View与子View还是耦合的,去掉了子View后底层View就会受到牵连。
Tip:tag可以用来传递信息。
方法三:用代理处理
因为显示label要在底层View控制器,因此应该在子View中调用,但是在底层View的控制器中执行,因此要将底层View的方法委托出去,让控制器监听触发label显示的按钮(在子View中)。
过程总结:子View点击按钮->通知底层View控制器->执行控制器的label显示代码。
第一步,在子View中定义protocol:
@class AppData, AppView; @protocol AppViewDelegate <NSObject> @optional - (void)appViewClickedDownloadBtn:(AppView *)appView; @endprotocol中的方法一般声明为@option,表示不一定要实现。
第二步,在子View中定义delegate成员变量(定义在.h中确保可以设定):
@property (weak, nonatomic) id<AppViewDelegate> deleage;
第三步,在点击按钮时调用方法通知代理:
注意先用respondsToSelector来判断是否有此方法(@option造成可能没有实现这个方法)
if ([self.deleage respondsToSelector:@selector(appViewClickedDownloadBtn:)]) { [self.deleage appViewClickedDownloadBtn:self]; }第四步,底层控制器遵循protocol,并且实现相应的方法。
@interface ViewController () <AppViewDelegate>控制器作为代理:
appView.deleage = self;实现方法:
- (void)appViewClickedDownloadBtn:(AppView *)appView{ NSLog(@"Click"); }