关闭

IOS--UI--LessonTarget/Action /Delegate

149人阅读 评论(0) 收藏 举报
分类:

Target/action
1.定义:Target/action模式是为了方便开发者管理同一类的不同对象的,定义一个ActionView类,继承自UIView
例子:假设使用ActionView创建不同的视图,redView、greenView、blueView三个对象,分别让三个视图响应不同的事件,redView改变自身背景颜色,greenView改变父视图背景颜色,blueView改变自身位置。
解决方案:
方法1. 我们可以在设定的时候给redView、greenView、blueView 设定 tag 值 然后再用 switch 调用

// 1.创建根视图控制器:ActionViewController 继承 UIViewController
// 2.修改 AppDelegate 里的根视图控制器
 ActionViewController *actionVC = [[ActionViewController alloc]init];
  self.window.rootViewController = actionVC;
  [actionVC release];
//  3.在根视图的控制器中创建三个视图:
  // 红色
    ActionView *redView = [[ActionView alloc]initWithFrame:CGRectMake(20, 20, 280, 100)];
    redView.backgroundColor = [UIColor redColor];
    [self.view addSubview:redView];
   redView.tag = 100;
    [redView release];
    //绿色
    ActionView *greenView = [[ActionView alloc]initWithFrame:CGRectMake(20, 130, 280, 100)];
    greenView .backgroundColor = [UIColor greenColor];
    greenView.tag = 101;
    [self.view addSubview:greenView];
    [greenView release];
    //蓝色
    ActionView *blueView = [[ActionView alloc]initWithFrame:CGRectMake(20, 250, 280, 100)];
    blueView.backgroundColor = [UIColor blueColor];
    [self.view addSubview:blueView];
    [blueView release];
  // 4. cmd+n 创建 ActionView 继承 UIView
   .m 中
   - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    switch (self.tag) {
        case 100:
            self.backgroundColor = [UIColor randomColor];
            break;
        case 101:
            self.superview.backgroundColor = [UIColor randomColor];
            break;
        case 102:
            self .center = CGPointMake(arc4random()%101+100, arc4random()%301+100);

        default:
            break;
    }
}
注意:笨重的 ActionView 的处理  不够灵活 每次创建一个新视图及对应的响应的处理事件 都要造成 ActionView 里的源代码 给视图添加不同的处理事件

思考:如何像 button一样灵活 ??
方法2,使用target/action模式开发。具体思想,让ActionView的对象调用一个方法,能够根据不同的对象执行不同的方法。

// ① 在ActionView类的.h文件中声明一个方法(因为外面需要使用这个方法,所以需要声明)

- (void)addTarget:(id)target action:(SEL)action;

//②,在ActionView类的.m文件中实现这个方法,实现这个方法前我们要明白这个方法的两个参数的含义,
//target指的是谁来完成这个方法,
//action指的是具体什么方法,
//所以我们需要在.m文件中定义两个变量来存放这两个参数。

@interface ActionView()
{
    id _target;// 存储响应目标(对象)
    SEL _action;//存储响应事件(方法)
}
//注意:@interface ActionView() 是在.m中实现的,所以这两个变量是私有变量,外界无法访问

实现声明的方法

- (void)addTarget:(id)target action:(SEL)action
{
     _target = target;
     _action = action;
}

③,我们要实现的就是在点击某个视图的时候响应某个方法,所以我们需要在ActionView的.m文件中的方法里实现方法

- (void)touches:(NSSet *)touches withEvent:(UIEvent*)event{
 [_target performSelector:_action withObject:self];
}
//注: _target、_action中存放的是外面调用- (void)addTarget:(id)target action:(SEL)action;方法时传进来的值,
//self指的是ActionView的一个对象。
//可以解释为:_target 帮 self 做一件事_action

④,调用- (void)addTarget:(id)target action:(SEL)action;方法
我们在试图控制器中创建了一个ActionView类的redView对象,使用redView对象调用我们设置的方法

 ActionView *redView = [[ActionView alloc]initWithFrame:CGRectMake(20, 20, 280, 100)];
    redView.backgroundColor = [UIColor redColor];
    [self.view addSubview:redView];
    [redView addTarget:self action:@selector(changeMyselfColor:)];//方法
    [redView release];
注:其实和方法1的创建视图一样  多了一个方法
// [redView addTarget:self action:@selector(changeMyselfColor: )];
//这句话的意思是,让一个对象self(视图控制器对象)调用一个方法 (changeMyselfColor:)就是我们的方法 
#pragma mark ----实现方法------

-(void)changeMyselfColor:(ActionView *)view{
    view.backgroundColor = [UIColor randomColor];
}

总结,执行顺序:④ -> ① -> ② ->③ -> ⑤,这种方式只能实现一个让target对一个action,耦合性较高,如果要实现一对多需要使用代理

下面将代理
1.重新创建了一个UIView的子类DelegateView
①,要使用代理我们首先要有一个协议,所以第一步制订协议。
制订协议有两种方法,如果这个协议是为了让多个类遵循的话,就创建一个协议文件protocol,如果只是一个类让别人帮自己做事情那么就在这个类的.h中制订协议。
在DelegateView类的.h文件中制订协议,

@class DelegateView;//告诉系统 使用了这个类
@protocol DelegateViewDelegate <NSObject>
//1.制定协议(为了写一些方法)
@optional//可选实现
//delegateView 类里的 view 如果是其他类 就会换成其他类的名字
- (void)changeMyselfColor:(DelegateView *)view;
-(void) changeSuperviewColor:(DelegateView *)view;
-(void) changeMyselfLocation:(DelegateView *)view;

@end

@interface DelegateView : UIView
//2.指定代理
@property (nonatomic,assign) id<DelegateViewDelegate>delegate;
//?为什么用 dalegate 命名 这么是命名方法 当有在 controller 使用 delegate的时候 就会变成引入的那个参数 比如我们现在的 redView.delegate = self 里 self;  如果你这个地方不是 delegate 那么你在 controller 里面要用的时候 就点 你在这里设的名字 

③ 问题来了 什么时候使用代理?
╮(╯▽╰)╭ 当然是我们需要的时候了 比如点击视图的时候 所以要在DelegateView类的.m文件中实现方法

- (void)touches:(NSSet *)touches withEvent:(UIEvent*)event{//    但是要先判断 判断代理有没有执行协议中对应的方法
    BOOL isResponder = [_delegate respondsToSelector:@selector(changeMyselfColor:)];
    //    代理执行协议方法的时机 但是要先判断
    if (isResponder) {
       [_delegate changeMyselfColor:self];
 //这里的self指的是DelegateView类的一个对象    
  }   
}

④,协议指定完毕,我们需要找个人来遵循这个协议,
我们让视图控制器遵循这个协议 DelegateUIViewController

 1.创建一个DelegateUIViewController类
 在DelegateUIViewController. h 中
@interface DelegateUIViewController : UIViewController <DelegateViewDelegate>//需要引入协议所在类的头文件
@end  
在. m 中 指定代理对象
  DelegateView *redView = [[DelegateView alloc]initWithFrame:CGRectMake(20, 30, 280, 100)];
    redView.backgroundColor = [UIColor redColor];
    //指定代理对象
    redView.delegate = self;
    [self .view addSubview:redView];
    [redView release];
     #pragma mark-----代理方法------
-(void)changeMyselfColor:(DelegateView *)view{
    view.backgroundColor = [UIColor randomColor];
     view.superview .backgroundColor=[UIColor randomColor];
}
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:14110次
    • 积分:766
    • 等级:
    • 排名:千里之外
    • 原创:65篇
    • 转载:0篇
    • 译文:0篇
    • 评论:6条
    文章分类
    最新评论