代理传值-不同类之间参数传递

来源:互联网 发布:crash撞车影评知乎 编辑:程序博客网 时间:2024/06/06 14:00

概要

很多时候,不同的类之间需要有数值交流传递,但是这些类之间并没有直接的关系,比如当一个界面向子页面传递某个参数,而子页面修改某些值之后而再返回主页面的时候,主页面的UI需要根据子页面的状态做一定的UI更新,这时,就需要考虑参数传递的问题了。这里使用IOS的代理的特点,以担当参数传递的职责。


主要技术点

  • 本例子的实验效果如下所示

    其中主页面输入的用户ID是通过代理(用户信息代理)的方式传递给子页面(用户信息页面)的,因此用户信息界面根据传递的用户ID查找用户头像,并生成一些信息,同时在用户信息里面通过代理(用户信息代理)设置主页面的用户头像,具体效果上图的动画已有演示。
  • 用户信息代理协议如下
    @protocol UserInfoDelegate <NSObject>@required/** *  获取用户Id * *  @return 用户ID */- (NSString*)userId;@optional/** *  默认头像 */- (void) setPortraitPath:(NSString*)portrait;@end
    该协议有两个方法,方法userId是用于传进参数,方法setPortraitPath:用于传出参数,这两个方法都是由使用了该协议(不是实现了该协议)的类调用,调用的大致方法如下:
    - (void)viewDidLoad{    [super viewDidLoad];        self.view.backgroundColor = [UIColor whiteColor];        UILabel* userLabel = [[UILabel alloc] init];    userLabel.frame = CGRectMake(40, 200, 200, 30);    // 设置了代理    if ([_delegate respondsToSelector:@selector(userId)])    {        userLabel.text = [_delegate userId];    }    else    {        userLabel.text = @"Delegate not set";    }        /** 中间代码略 */        // 更新对应代理的头像    if ([_delegate respondsToSelector:@selector(userId)])    {        [_delegate setPortraitPath:imagePath];    }}
    上述代码中使用方法respondsToSelector是查看是否实现了该方法,需要注意的是,这里调用的两个方法都是在实现了代理协议的类里面实现的,而不是当前类实现。需要注意用户信息类要有属性或者变量类型为id<UserInfoDelegate>的,如下所示:
    @interface UserInfo : UIViewController@property (nonatomic, strong) id<UserInfoDelegate> delegate;@end

  • 实现代理协议的类是主页面,实现协议就好了
    #pragma 实现协议UserInfoDelegate// 当前视图的值传值给对方- (NSString*)userId{    return _userText.text;}// 对方视图的值传值到本类- (void) setPortraitPath:(NSString*)portrait{    if (portrait == nil)    {        portrait = [[NSBundle mainBundle] pathForResource:@"boy0" ofType:@"png"];    }    // 设置头像    _portraitView.image = [UIImage imageWithData:[NSData dataWithContentsOfFile:portrait]];}
    然后在转入子页面的时候,设置子页面的代理为当前实例,如此完成了整个部分的参数传值过程。
    - (void)goUser{    UserInfo* user = [[UserInfo alloc] init];    // 设置代理    user.delegate = self;    [self.navigationController pushViewController:user animated:YES];}
  • 这样当主页面输入完用户ID后,转到子页面的viewDidLoad方法,由于该方法所在的类拥有设置了用户信息代理(UserInfoDelegate)方,所以可直接使用协议的方法。于是先是通过调用协议的方法userId拿到当前的用户id值,然后根据id查找获取用户id对应的信息,同时在最后通过代理的setPortraitPath:方法向实现代理的对象返回头像路径值。

主要代码

用户信息视图控制类头文件

//  Copyright (c) 2015年 arbboter. All rights reserved.//#import <UIKit/UIKit.h>@protocol UserInfoDelegate <NSObject>@required/** *  获取用户Id * *  @return 用户ID */- (NSString*)userId;@optional/** *  默认头像 */- (void) setPortraitPath:(NSString*)portrait;@end@interface UserInfo : UIViewController@property (nonatomic, strong) id<UserInfoDelegate> delegate;@end

用户信息视图控制类实现文件

//  Copyright (c) 2015年 arbboter. All rights reserved.//#import "UserInfo.h"@implementation UserInfo- (void)viewDidLoad{    [super viewDidLoad];        self.view.backgroundColor = [UIColor whiteColor];        UILabel* userLabel = [[UILabel alloc] init];    userLabel.frame = CGRectMake(40, 200, 200, 30);    // 设置了代理    if ([_delegate respondsToSelector:@selector(userId)])    {        userLabel.text = [_delegate userId];    }    else    {        userLabel.text = @"Delegate not set";    }    userLabel.layer.borderWidth = 1;    userLabel.textAlignment = NSTextAlignmentCenter;    [self.view addSubview:userLabel];        UILabel* nameLabel = [[UILabel alloc] init];    nameLabel.frame = CGRectMake(40, 240, 200, 30);    nameLabel.layer.borderWidth = 1;    nameLabel.textAlignment = NSTextAlignmentCenter;    nameLabel.text = [NSString stringWithFormat:@"name_%d", arc4random()];    [self.view addSubview:nameLabel];        UILabel* stateLabel = [[UILabel alloc] init];    stateLabel.frame = CGRectMake(40, 280, 200, 30);    stateLabel.layer.borderWidth = 1;    stateLabel.text = @"该家伙太懒了,什么都没有留下。请邀请ta更新....";    // 高度自适应    stateLabel.numberOfLines = 0;    [stateLabel sizeToFit];    [self.view addSubview:stateLabel];        UIImageView* portrait = [[UIImageView alloc] init];    portrait.frame = CGRectMake(100, 80, 100, 100);    portrait.layer.borderWidth = 1;    NSString* imagePath = [[NSBundle mainBundle] pathForResource:userLabel.text ofType:@"png"];    if(imagePath == nil)    {        imagePath = [[NSBundle mainBundle] pathForResource:@"boy3" ofType:@"png"];        userLabel.text = @"user not exist";    }    portrait.image = [UIImage imageWithData:[NSData dataWithContentsOfFile:imagePath]];    portrait.contentMode = UIViewContentModeScaleAspectFit;    [self.view addSubview:portrait];        // 更新对应代理的头像    if ([_delegate respondsToSelector:@selector(userId)])    {        [_delegate setPortraitPath:imagePath];    }    }@end

主页面视图控制类

//  Copyright (c) 2015年 arbboter. All rights reserved.//#import "ViewController.h"@interface ViewController ()@property (nonatomic, strong) UIImageView* portraitView;@property (nonatomic, strong) UITextField* userText;@end@implementation ViewController- (void)viewDidLoad{    [super viewDidLoad];        self.view.backgroundColor = [UIColor whiteColor];    [super.navigationController setNavigationBarHidden:YES animated:TRUE];    //[super.navigationController setToolbarHidden:YES animated:TRUE];        _portraitView = [[UIImageView alloc] init];    _portraitView.frame = CGRectMake(100, 40, 150, 150);    [self.view addSubview:_portraitView];        UILabel* userLabel = [[UILabel alloc] init];    userLabel.frame = CGRectMake(40, 200, 60, 30);    userLabel.text = @"用户ID";    [self.view addSubview:userLabel];        _userText = [[UITextField alloc] init];    _userText.frame = CGRectMake(100, 200, 200, 30);    _userText.placeholder = @"请输入用户ID";    _userText.returnKeyType = UIReturnKeyGo;    _userText.layer.borderWidth = 1;    [_userText addTarget:self action:@selector(goUser) forControlEvents:UIControlEventEditingDidEndOnExit];    [self.view addSubview:_userText];        _portraitView = [[UIImageView alloc] init];    _portraitView.frame = CGRectMake(100, 80, 100, 100);    _portraitView.contentMode = UIViewContentModeScaleAspectFit;    [self.view addSubview:_portraitView];        [self setPortraitPath:nil];}- (void)goUser{    UserInfo* user = [[UserInfo alloc] init];    // 设置代理    user.delegate = self;    [self.navigationController pushViewController:user animated:YES];}- (void)didReceiveMemoryWarning{    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}- (void) viewWillAppear:(BOOL)animated{    //  隐藏导航栏    [super.navigationController setNavigationBarHidden:YES animated:animated];}- (void) viewWillDisappear:(BOOL)animated{    //  显示导航栏    [super.navigationController setNavigationBarHidden:NO animated:animated];}#pragma 实现协议UserInfoDelegate// 当前视图的值传值给对方- (NSString*)userId{    return _userText.text;}// 对方视图的值传值到本类- (void) setPortraitPath:(NSString*)portrait{    if (portrait == nil)    {        portrait = [[NSBundle mainBundle] pathForResource:@"boy0" ofType:@"png"];    }    // 设置头像    _portraitView.image = [UIImage imageWithData:[NSData dataWithContentsOfFile:portrait]];}@end


项目地址



1 0
原创粉丝点击