zoukankan      html  css  js  c++  java
  • 【转】iOS 开发之协议protocal-代理传值delegate

    原文网址:http://www.cnblogs.com/wzrong/p/3201938.html

    刚开始做iOS开发的时候,对 protocol、delegate 的理解一直都是晕晕乎乎一知半解的状态,不知道两个UIViewController之间怎么进行传值。

    面试过几个童鞋,问道怎么用 delegate 对 两个 UIViewController 进行传值的时候,回答的都是模棱两可的。今天又有童鞋问我这个问题,所以干脆写个blog说明一下。

    1、协议(protocol),就是使用了这个协议后,必须按照协议规定的内容来处理事情,协议中要求的方法必须实现(@optional的方法除外)。

    protocol是一种语法,它提供了一个很方便的、实现delegate模式的机会。

    定义protocol如下:

    复制代码
    @protocol ClassBDelegate<NSObject>
    
    - (void)methodOne;
    @optional - (void)methodTwo:(NSString *)value; @end
    复制代码

    定义了一个ClassB的协议,这个协议中包含两个方法,其中methodTwo为可选的。

    在ClassA的头文件(ClassA.h)中实现这个协议,如下代码:

    @interface ClassA<ClassBDelegate>
    
    @end

    在ClassA的实现文件(ClassA.m)中实现ClassBDelegate的两个方法,其中methodTwo可以不实现,如下:

    复制代码
    - (void)methodOne{
        // 具体实现内容
        
    }
    
    - (void)methodTwo:(NSString *)value{ 
        // 具体实现内容  
    }
    复制代码

    2、代理(delegate),顾名思义就是委托别人办事,当一件事情发生后,自己不处理,让别人来处理。

    delegate和protocol没有关系。delegate本身是一种设计模式。是把一个类自己需要做的一部分事情,让另一个类(也可以就是自己本身)来完成。

    在ClassB的头文件(ClassB.h)中定义一个代理如下:

    @interface ClassB
    
    @property (nonatomic, unsafe_unretained) id<ClassBDelegate> delegate;
    
    @end

    这样,当我们在ClassB的实现文件(ClassB.m)中遇到想让别的类(如 ClassA)处理的问题时,就可以这样

    [self.delegate methodOne];
    
    [self.delegate methodTwo:@"需要传递的值"];

    3、上边简单的介绍了一下协议与代理,现在开始讲两个UIViewController之间怎么进行传值的事例。

    首先启动Xcode,从菜单选择file-New Project...,弹出如下窗口:

    选择Single View Application,然后点击 Next,弹出如下窗口:

      a、给工程取个名称为 DelegateByValue;

      b、下边的组织名称写自己所在的组织,这里写的是我个人的名称;

      c、公司标识分为两部分,com也就是Company(公司)的意思,iostour写自己所在的公司名称,这里我写的是iOS之旅的iostour;

      d、类前缀,这个可以随便,不过我这里写的是W,因为我姓卫,所以取其首字母,这样公司同事一看到这个类就知道是我写的;

      e、设备选择iPhone;

      f、我们用xib的方式编写,故此处不勾选;

      g、使用ARC机制,勾选;

      h、该事例不做单元测试,不勾选。

    然后单击 Next,弹出如下窗口:

    选择一个存储工程的目录,然后单击 Create创建一个工程,创建完成后的目录结构如下:

    接下来我们需要在两个Controller之间进行传值,由于创建工程的时候已经自动为我们生成了一个WViewController,所以我们只需要在创建一个就Controller就好啦。

    鼠标右键DelegateByValue,点击New File...  如下:

    然后弹出如下窗口

    选择iOS>Cocoa Touch >Objective-C Class,然后单击 Next,弹出如下窗口:

    然后,取名为WTwoViewController,单击 Next,选择存储目录,然后Create。

    接下来为WTowViewController 创建一个.xib文件,步骤以此如下:

      a、鼠标右键DelegateByValue,点击New File...

        

      b、然后弹出如下窗口:

        

        这次我们选择iOS > User Interface > View,单击 Next,取名为WTwoViewController,然后Create。

        创建好WTwoViewController后,我们让WTwoViewController.xib与WTwoViewController.h关联起来,如下图:

      按照上图1、2、3的步骤依次进行,选中1,点击2,设置3 Class为WTwoViewController,然后回车,然后如下图:

    点击4、按住5 view后边的空心圆,拖动到6 view上,然后松手及

    接下来给view上拖一个UITextField和一个UIButton,并给UITextField起名为txtValue,给UIButton设置一个Action,起名为pressChange

    步骤如下:

    1、分屏显示xib与代码,

    2、选择UITextField,并按住control键, 拖动到右侧的代码(WTwoViewController.h)区域,会弹出如下窗口:

    为其设置名称,然后点击Connect;

    3、同样,选择UIButton,并按住control键,拖动到右侧代码(WTwoViewController.h)区域,会弹出如下窗口:

    这次因为是要给UIButton设置点击事件,所以改变1 Connection为Action,然后设置名称,点击Connect。

    至此WTwoViewController的窗口视图以设置完成。

    同样步骤设置WViewController.xib窗口。

    给 view 上拖一个UILabel和一个UIButton,并给UILabel起名为lblValue,给UIButton设置一个Action,起名为pressCasting。

    至此窗口设置部分已经全部完成,效果如下:

    接下来在WTwoViewController.h中定义一个协议,WTwoViewControllerDelegate,并给WTwoViewController定义一个代理,代码如下:

    复制代码
    //
    //  WTwoViewController.h
    //  DelegateByValue
    //
    //  Created by wzrong on 13-7-20.
    //  Copyright (c) 2013年 wzrong. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    /**
     定义协议,用来实现传值代理
     */
    @protocol WTwoViewControllerDelegate <NSObject>
    
    /**
     此方为必须实现的协议方法,用来传值
     */
    - (void)changeValue:(NSString *)value;
    
    @end
    
    /**
     弹出来的Controller,需要从这个页面回传值到调用它的WViewController中
     */
    @interface WTwoViewController : UIViewController
    
    /**
     此处利用协议来定义代理
     */
    @property (nonatomic, unsafe_unretained) id<WTwoViewControllerDelegate> delegate;
    
    /**
     这个文本框中的值可以自己随意改变。
     当点击“我变变变!”按钮后,它里边的值会回传到调用它的WViewController中
     */
    @property (nonatomic, strong) IBOutlet UITextField *txtValue;
    
    /**
     “我变变变!” 按钮点击事件,用来处理按钮点击后的事情。
     此例中用来发送代理,并退出当前窗体
     */
    - (IBAction)pressChange:(id)sender;
    
    @end
    复制代码

    接下来在WTwoViewController.m中的 - (IBAction)pressChange:(id)sender 方法中把代理派发出去,顺便把窗口给销毁,代码如下:

    复制代码
    /**
     “我变变变!” 按钮点击事件,用来处理按钮点击后的事情。
     此例中用来发送代理,并退出当前窗体
     */
    - (IBAction)pressChange:(id)sender {
        // 发送代理,并把文本框中的值传过去
        [self.delegate changeValue:self.txtValue.text];
        
        // 退出当前窗口
        [self dismissViewControllerAnimated:YES completion:nil];
    }
    复制代码

    WTwoViewController中的设置已经完成,接下要在WViewController中调用WTwoViewController,并实现WTwoViewControllerDelegate代码。

    首先在WViewController.h中实现代理,代码如下:

    复制代码
    //
    //  WViewController.h
    //  DelegateByValue
    //
    //  Created by wzrong on 13-7-20.
    //  Copyright (c) 2013年 wzrong. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    #import "WTwoViewController.h"
    
    /**
     主 Controller,通过此 Controller 调用 WTwoViewController,然后把 WTwoViewController 传递过来的值赋给 UILabel
     此 Controller 实现了 WTwoViewControllerDelegate 这个协议
     */
    @interface WViewController : UIViewController<WTwoViewControllerDelegate>
    
    /**
     用来显示 Delegate 传过来的值
     */
    @property (strong, nonatomic) IBOutlet UILabel *lblValue;
    
    /**
     “施法”按钮事件,用来处理点击“施法”按钮后的事情。
     此事例中要来调用弹出 WTwoViewController
     */
    - (IBAction)pressCasting:(id)sender;
    
    @end
    复制代码

    其在WViewController.m的 - (IBAction)pressCasting:(id)sender 方法中调用WTwoViewController,并设置代理的回调方法,代码如下:

    复制代码
    /**
     “施法”按钮事件,用来处理点击“施法”按钮后的事情。
     此事例中要来调用弹出 WTwoViewController
     */
    - (IBAction)pressCasting:(id)sender {
        // 给 WTwoViewController 非配内存,并初始化xib文件
        WTwoViewController *controller = [[WTwoViewController alloc]initWithNibName:@"WTwoViewController" bundle:nil];
        
        // 设置代理到此Controller
        controller.delegate = self;
        
        // 弹出 WTwoViewController
        [self presentViewController:controller animated:YES completion:nil];
    }
    
    /**
     此方为必须实现的协议方法,用来传值
     */
    - (void)changeValue:(NSString *)value{
        // 改变UILabel的值
        self.lblValue.text = value;
    }
    复制代码

    OK,搞定。

    这里只实现了从WTwoViewController到WViewController的传值,大家可以自己做做从WViewController到WTwoViewController的传值。

    工程源码传送门DelegateByValue

    著作权声明:本文由 http://wzrong.cnblogs.com 或者 http://iostour.diandian.com 原创,欢迎转载分享。 请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!


    原创文章,如需转载请注明出处,谢谢!

    欢迎访问本人技术微博 @iOS之旅 相互交流,共同学习,共同进步!

    欢迎访问本人微博 @卫志荣

  • 相关阅读:
    jquery
    gulp 入门
    bower 教程
    webstrom管理git
    修改页面浏览器自动刷新
    兼容IE低版本
    js之触屏事件篇
    js之日期篇
    设置浏览器默认样式
    Listview四种视图VIEW
  • 原文地址:https://www.cnblogs.com/wi100sh/p/5713041.html
Copyright © 2011-2022 走看看