iOS編程-------target/action設計模式 / 代理設計模式

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

#import <UIKit/UIKit.h>

@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 <UIKit/UIKit.h>

@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 <UIKit/UIKit.h>
@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<WeiTuoViewDelegate> 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 <UIKit/UIKit.h>
/**
 *  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
發佈了32 篇原創文章 · 獲贊 0 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章