iOS编程-------target/action设计模式 / 代理设计模式

//
//  AppDelegate.h
//  UI05_Target_action-delegate
//
//  Created by l on 15/9/7.
//  Copyright (c) 2015年 . All rights reserved.
//

#import 

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;


@end



//
//  AppDelegate.m
//  UI05_Target_action-delegate
//
//  Created by l on 15/9/7.
//  Copyright (c) 2015年 . All rights reserved.
//

#import "AppDelegate.h"
#import "RootViewController.h"
@interface AppDelegate ()

@end

@implementation AppDelegate
- (void)dealloc{
    [_window release];
    [super dealloc];
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];

    RootViewController *rootVC = [[[RootViewController alloc] init] autorelease];
    self.window.rootViewController = rootVC;


    return YES;
}

@end



/



//
//  RootViewController.h
//  UI05_Target_action-delegate
//
//  Created by l on 15/9/7.
//  Copyright (c) 2015年 . All rights reserved.
//

#import 

@interface RootViewController : UIViewController

@end


//
//  RootViewController.m
//  UI05_Target_action-delegate
//
//  Created by l on 15/9/7.
//  Copyright (c) 2015年 . All rights reserved.
//

#import "RootViewController.h"
#import "TapView.h"//导入tapView 头文件
#import "WeiTuoView.h" // 导入weituoView 头文件
//遵守协议weituoViewDelegate
@interface RootViewController ()<WeiTuoViewDelegate>

@end

@implementation RootViewController

//实现协议里面的方法,更改视图的位置

- (void)weiTuoViewChangePositionDidTouchBegin:(WeiTuoView *)weiTuoView
{
    weiTuoView.center = [self randomPoint:weiTuoView];

}

//随机位置
- (CGPoint)randomPoint:(UIView *)view{
    CGFloat width = view.frame.size.width;
    CGFloat height = view.frame.size.height;

    CGFloat minX = width / 2;
    CGFloat minY = height / 2;
    CGFloat maxX = self.view.frame.size.width - minX;
    CGFloat maxY = self.view.frame.size.height - minY;

    return CGPointMake(arc4random() % (int)(maxX - minX + 1) + minX, arc4random() % (int)(maxY - minY + 1) + minY);
}




- (void)viewDidLoad {
    [super viewDidLoad];

    //target / action 和 delegate 的异同点
    //相同点:
    //1. 自身都不执行操作,控制target或者delegate 执行相关的方法
    //不同点:
    //1. target / action 目标 和 目标方法都不确定,delegate 方法确定,协议里面的方法
    //2. target / action 的 target可以为任意id类型,delegate 为遵守了协议的id类型





    //delegate
    WeiTuoView *weituoView = [[WeiTuoView alloc] initWithFrame:(CGRectMake(50, 50, 150, 150))];
    weituoView.backgroundColor = [UIColor magentaColor];
    //给weituoView设置代理
    weituoView.delegate = self;
    [self.view addSubview:weituoView];
    [weituoView release];






    //1. 创建点击后改变颜色colorView对象
    TapView *colorView = [[TapView alloc] initWithFrame:(CGRectMake(50, 50, 200, 200))];
    colorView.backgroundColor = [UIColor yellowColor];
    //设置target action
    [colorView addTarget:self action:@selector(changeColor:)];

//    [self.view addSubview:colorView];
    [colorView release];


    //2. 创建点击后改变大小的sizeView对象

    TapView *sizeView = [[TapView alloc] initWithFrame:(CGRectMake(50, 300, 200, 200))];
    sizeView.backgroundColor = [UIColor redColor];

    //设置 target action 改变大小方法
    [sizeView addTarget:self action:@selector(changeSize:)];

//    [self.view addSubview:sizeView];
    [sizeView release];


    // Do any additional setup after loading the view.
}

#pragma mark -- 改变颜色
- (void)changeColor:(TapView *)tapView{
    tapView.backgroundColor = [self randomColor];

}
//随机颜色
- (UIColor *)randomColor{
    return [UIColor colorWithRed:arc4random() % 256 / 255.0 green:arc4random() % 256 / 255.0 blue:arc4random() % 256 / 255.0 alpha:1];
}
#pragma mark -- 改变大小
- (void)changeSize:(TapView *)tapView{
    CGRect rec1 = tapView.frame;
    rec1.size = [self randomSize];
    tapView.frame = rec1;
}
//随机大小
- (CGSize)randomSize{
    //最大300, 最小50
    return CGSizeMake(arc4random() % (300 - 50 + 1) + 50, arc4random() % (300 - 50 + 1) + 50);

}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end









//
//  WeiTuoView.h
//  UI05_Target_action-delegate
//
//  Created by l on 15/9/7.
//  Copyright (c) 2015年 . All rights reserved.
//

#import 
@class WeiTuoView;
/**
 *  代理设计模式 有三部分
 1. 委托 委托决定着 协议里有什么方法 哪些方法,这些方法是委托自身不想实现的,而是让代理去实现
 2. 协议 协议只有头文件 ,只有声明@interface, 没有实现,协议里面的方法由代理实现 ;由 委托控制代理何时执行这些方法
 3. 代理 代理遵守了协议,实现协议里面的方法. 代理, 是委托的代理, 由委托控制 代理何时执行协议里面的方法 .

 在UI中, 我们可以把协议写在控件的头文件.h文件里面
 //协议的命名规则: 类名 + delegate

 */

@protocol WeiTuoViewDelegate <NSObject>
//协议里面的方法命名规则
//(返回值类型) 类名 + 触发时机:(类名 *)参数 其他操作描述字符串xxx

//当视图被点击的时候,改变视图的位置
- (void)weiTuoViewChangePositionDidTouchBegin:(WeiTuoView *)weiTuoView;

@end


@interface WeiTuoView : UIView<UITextFieldDelegate>
// 设置代理实例变量, delegate id 类型, 且遵守了协议.
@property (nonatomic, assign) id delegate;


@end



//
//  WeiTuoView.m
//  UI05_Target_action-delegate
//
//  Created by l on 15/9/7.
//  Copyright (c) 2015年 . All rights reserved.
//

#import "WeiTuoView.h"

@implementation WeiTuoView
//当视图被点击的时候,让delegate 执行协议里面的方法
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

    //因为 .h文件中,已经存在了协议,因此可以执行协议里面的方法,当然perform也不会出错
   // [_delegate performSelector:@selector(weiTuoViewChangePositionDidTouchBegin:) withObject:self];

    //代理不能为空, 且代理里面实现了协议里面的方法
    if (_delegate != nil && [_delegate respondsToSelector:@selector(weiTuoViewChangePositionDidTouchBegin:)]) {
        //让代理执行方法
        [_delegate weiTuoViewChangePositionDidTouchBegin:self];


    }


}



@end




/




//
//  TapView.h
//  UI05_Target_action-delegate
//
//  Created by l on 15/9/7.
//  Copyright (c) 2015年 . All rights reserved.
//

#import 
/**
 *  target action 设计模式
 我们想要该视图被点击的时候触发不同的方法,比如,使用该类创建出三个对象 colorView sizeView positionView
 点击colorView 要换colorView的颜色
 点击sizeView 要改变大小
 点击positionView 改变位置

 这意味着 视图对象被点击的时候,触发的方法不同,如果我们把方法写在类内部,一次只能执行一个方法,这样就写死了.
 为此,我们可以通过聚合 与 耦合 的思想,在类内部留给外界接口,
 1.一个方法接口, 让外部指定被点击执行的操作.
 2. 一个目标对象接口,因为在mvc 框架中,view层不处理业务逻辑,而是让 controller处理,需要把外部对象传递进来.
 */
@interface TapView : UIView

//target 目标对象,语义修饰为assign,为了防止相互持有,为了防止循环引用
@property (nonatomic, assign) id target; //id 泛型,可以为任意一种类型
//action 方法,外部传递的方法,语义为assign, SEL类型, (SEL 表示方法类型,其本质为函数指针) , SEL不是对象类型
@property (nonatomic, assign) SEL action;

//@selector (方法名) ->>  sel类型变量

//写一个方法让外界给定 target 目标对象 和 action 目标执行方法
- (void)addTarget:(id)target action:(SEL)action;


@end



//
//  TapView.m
//  UI05_Target_action-delegate
//
//  Created by l on 15/9/7.
//  Copyright (c) 2015年 . All rights reserved.
//

#import "TapView.h"

@implementation TapView

//给内部变量 target 和 action 赋值
- (void)addTarget:(id)target action:(SEL)action{
    self.target = target;
    self.action = action;
}

//重写touch begin ,当视图被点击的时候,让 target 目标 执行action 方法
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

//    _target 不为空, 且 _ target实现了_action  方法
    if (_target != nil && [_target respondsToSelector:_action]) {
        [_target performSelector:_action withObject:self];
    }



   //[receiver respondsToSelector:(SEL)selector] 该方法是接受者, receiver 执行 selector 方法
    //目标          执行         方法
//    [_target performSelector:_action withObject:self];
    //让target 执行action 方法,并且把self (tapView本身) 作为action方法的参数传递过去
}



@end

你可能感兴趣的:([iOS,UI设计])