随意细解:UI -- 设计模式、手势识别
2015-11-16 21:44
471 查看
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(@"边缘扫一定要靠近屏幕边缘开始扫"); }
相关文章推荐
- 【黑马程序员】GUI
- 《leetCode》:N-Queens II
- UI阶段的 Target/Action设计模式
- MySQL开启慢查询日志log-slow-queries
- Android-UI布局---RecyclerView学习(三)匹配LinearLayoutManager的ItemDecoration
- NSURLRequest详解
- UIViewController的生命周期
- GPUImage API 文档之GPUImageOutput类
- ACM学习历程—UESTC 1219 Ba Gua Zhen(dfs && 独立回路 && xor高斯消元)
- light oj 1012 Guilty Prince(dfs )
- 《leetCode》:N-Queens(奇葩的测试平台,居然不能AC)
- UITableView优化技巧
- UIView 中bounds和frame的差别
- Android-UI布局---RecyclerView学习(二)利用它做的相册集效果
- 16.UISwitch(开/关视图)
- 使用Animations动画改变View的cornerRadius半径
- UI根视图控制器
- Android-UI布局---RecyclerView学习(一)在适配器中自定义长按和点击事件
- iOS开发 粗解UIDynamicAnimator
- bigbluebutton1.0\mconf-web\mconf-mobile安装部署联调