target/Action设计模式
举例:点击view实现点击功能,改变背景颜色(类似button的addtarget方法)
创建ButtonView,遵守协议:
在ButtonView.h中:为了方便调用,声明成属性
@property (nonatomic, retain) id target;
@property (nonatomic, assign) SEL action;
// 初始化方法
- (instancetype)initWithFrame:(CGRect)frame target:(id)target action:(SEL)action;
在ButtonView.m中:
- (void)dealloc
{
[self.target release];
[super dealloc];
}
- (instancetype)initWithFrame:(CGRect)frame target:(id)target action:(SEL)action
{
self = [super initWithFrame:frame];
if (self) {
// 初始化时,对属性进行赋值
self.target = target;
self.action = action;
}
return self;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
// 使用self.target对象调用 action方法
// 让一个对象 去调用这个对象类里的方法
// Object 可携带的参数
[self.target performSelector:self.action withObject:self];
}
创建RootViewController作为根控制器
- (void)viewDidLoad {
[super viewDidLoad];
ButtonView *buttonView = [[ButtonView alloc]initWithFrame:CGRectMake(100, 100, 100, 100) target:self action:@selector(buttonClick:)];
buttonView.backgroundColor = [UIColor redColor];
[self.view addSubview:buttonView];
[buttonView release];
}
- (void)buttonClick:(ButtonView *)buttonView
{
buttonView.backgroundColor = [UIColor blackColor];
NSLog(@"触发了");
}
delegate代理模式
不管是target/Action设计模式,代理设计模式还是 MVC设计模式,中心只有一个,解耦,提高代码的复用性。
举例说明:点击ImageView,实现点击事件,改变背景颜色,并且遵循MVC设计模式
创建 ButtonImageView,并创建协议
在@interface之前声明协议,因为需要类本身作为参数,所以使用@class方法告诉文件,ButtonImageView是一个类:(ButtonImageView.h文件中)
@class ButtonImageView; @protocol ButtonImageViewDElegate <NSObject> - (void)ButtonImageViewClick:(ButtonImageView *)imageView; @end
设置代理
需要调用ButtonImageView的代理方法,所以将delegate设置为属性:(ButtonImageView.h文件中)
@property (nonatomic, assign) id<ButtonImageViewDElegate> delegate;
代理属性为什么要声明成assign?
防止循环引用从而造成的内存泄露。解释:
假如 A是B的代理,B也是A的代理,如果是 retain [[A alloc]init]; A:1 [[B alloc]init]; B:1 A.delegate = B; B:2 B.delegate = A; A:2 [A release]; A:1 [B release]; B:1 A和B的引用计数都是1,无法释放,造成内存泄露。
实现 touchesEnded 方法:(ButtonImageView.m文件中)
注:声明delegate属性,需要重写dealloc方法- (void)dealloc { [self.delegate release]; [super dealloc]; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { // 判断保护,判断delegateshif响应点击方法 if ([_delegate respondsToSelector:@selector(ButtonImageViewClick:)]) { // 调用代理方法 [_delegate ButtonImageViewClick:self]; } }
创建MyView , 调用ButtonImageView
为了外部可以直接调用imageView,将imageView声明称属性:(在MyView.h中)
// 引入头文件 #import "ButtonImageView.h" // 声明属性 @property (nonatomic, retain) ButtonImageView *imageView;
在MyView中重写initWithFrame方法
- (void)dealloc { [self.imageView release]; [super dealloc]; } - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { self.imageView = [[ButtonImageView alloc]initWithFrame:[UIScreen mainScreen].bounds]; [self addSubview:self.imageView]; [self.imageView release]; } return self; }
创建 RootViewController ,作为根控制器。遵循协议(在RootViewController.h文件中)
// 引入头文件 #import "ButtonImageView.h" @interface RootViewController : UIViewController <ButtonImageViewDElegate>
实现协议中的方法
- (void)viewDidLoad { [super viewDidLoad]; MyView *myView = [[MyView alloc]initWithFrame:[UIScreen mainScreen].bounds]; // 设置代理 myView.imageView.delegate = self; self.view = myView; [myView release]; } // 实现协议中的方法 - (void)ButtonImageViewClick:(ButtonImageView *)imageView { imageView.backgroundColor = [UIColor yellowColor]; }
手势识别
手势类 UIGestureRecognizer,这个类是个抽象类,其具体功能交给子类去实现。
创建ImageView,添加手势:
UIImageView *imageView = [[UIImageView alloc]initWithFrame:[UIScreen mainScreen].bounds];
[self.view addSubview:imageView];
imageView.image = [UIImage imageNamed:@"C8"];
// 打开交互
imageView.userInteractionEnabled = YES;
[imageView release];
- 轻拍
viewDidLoad方法中:
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapAction:)];
// 添加手势到视图上
[imageView addGestureRecognizer:tap];
[tap release];
实现轻拍方法
- (void)tapAction:(UITapGestureRecognizer *)tap
{
UIImageView *imageView = (UIImageView *)tap.view;
imageView.image = [UIImage imageNamed:@"C1"];
NSLog(@"你拍我了");
}
- 长按
viewDidLoad方法中:
UILongPressGestureRecognizer *longPress= [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPressAction:)];
// 设置长按时间
longPress.minimumPressDuration = 2.0;
// 添加到视图上
[imageView addGestureRecognizer:longPress];
[longPress release];
实现长按方法
- (void)longPressAction:(UILongPressGestureRecognizer *)longPress
{
// 判断一下手势状态,长按,只需要触发一次
if (longPress.state == UIGestureRecognizerStateBegan) {
NSLog(@"长按触发了多少次?");
UIImageView *imageView = (UIImageView *)longPress.view;
imageView.image = [UIImage imageNamed:@"image.jpg"];
NSLog(@"你按我了");
}
}
- 旋转
viewDidLoad方法中:
UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc]initWithTarget:self action:@selector(rotationAction:)];
[imageView addGestureRecognizer:rotation];
[rotation release];
实现旋转方法
- (void)rotationAction:(UIRotationGestureRecognizer *)rotation
{
// 形变属性 transform
// 参数1:改变形变属性的视图
// 参数2:根据弧度去创建
rotation.view.transform = CGAffineTransformRotate(rotation.view.transform, rotation.rotation);
// 每次转需要把旋转的角度重置为0
// 因为要接替上一次的角度 开始旋转
rotation.rotation = 0;
NSLog(@"旋转了");
}
- 捏合
viewDidLoad方法中:
UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(pinchAction:)];
[imageView addGestureRecognizer:pinch];
[pinch release];
实现捏合方法
- (void)pinchAction:(UIPinchGestureRecognizer *)pinch
{
// 根据缩放的刻度(比例)改变形变属性
// 根据捏合的比较,去改变形变属性
pinch.view.transform = CGAffineTransformScale(pinch.view.transform, pinch.scale , pinch.scale);
// 重置捏合的比例
pinch.scale = 1;
NSLog(@"捏合");
}
- 平移
viewDidLoad方法中:
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panAction:)];
[imageView addGestureRecognizer:pan];
[pan release];
实现平移方法
- (void)panAction:(UIPanGestureRecognizer *)pan
{
// 获取平移的点(相对于要平移的视图)
CGPoint p = [pan translationInView:pan.view];
// 根据这个点改变形变属性
pan.view.transform = CGAffineTransformTranslate(pan.view.transform, p.x, p.y);
// 重置这个点
[pan setTranslation:CGPointMake(0, 0) inView:pan.view];
NSLog(@"平移");
}
- 轻扫
viewDidLoad方法中:
UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeAction:)];
// 设置左右扫的方向
swipe.direction = UISwipeGestureRecognizerDirectionLeft;
[imageView addGestureRecognizer:swipe];
[swipe release];
实现轻扫方法
- (void)swipeAction:(UISwipeGestureRecognizer *)swipe
{
NSLog(@"左扫");
}
- 边缘扫
viewDidLoad方法中:
UIScreenEdgePanGestureRecognizer *screenEdgePan = [[UIScreenEdgePanGestureRecognizer alloc]initWithTarget:self action:@selector(screenEdgePanAction:)];
// 设置从哪个边缘开始扫
screenEdgePan.edges = UIRectEdgeRight;
[imageView addGestureRecognizer:screenEdgePan];
[screenEdgePan release];
实现边缘扫方法
- (void)screenEdgePanAction:(UIScreenEdgePanGestureRecognizer *)screenEdgePan
{
NSLog(@"边缘扫一定要靠近屏幕边缘开始扫");
}