美文网首页扯淡技能iOS开发程序员
iOS 视图控制器传值方式总结

iOS 视图控制器传值方式总结

作者: 2897275c8a00 | 来源:发表于2017-06-02 14:55 被阅读58次

Copyright © 2017年ZaneWangWang. All rights reserved.

如果你看到的不是原文请到原文查看

一. 视图控制器之间传值

1. vc_A push或者模态到vc_B

分析: 这种情况能够在vc_A中直接得到vc_B的对象,可以直接将要赋的值给vc_B的一个可访问属性即采用属性传值

例如:在vc_A的tableview的点击选中方法中赋值

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

          UIViewController *vc_B = ....

          vc_B.dataModel = vc_A.dataSource[indexPatch.row];

          [vc_A push或者present到vc_B];

}

2. vc_B pop或者 dismiss到vc_A

分析: 反向传值应用非常广泛可以用到代理或者是block传值,当然也可以使用通知(不怎么常用通知,这里就不在介绍通知),如果是通过导航完成的跳转或者模态又或者vc_A是在storyboard文件中的也可以直接获取对象给对象的可访问属性赋值

例如:

1>.代理传值(这里是非正式代理)

vc_B中需要写一个传值的代理方法,一个代理的属性

#import <UIKit/UIKit.h>

@protocol vc_BDelegate<NSObject>

@required(必须)/@optional(可选)

- (void)sendBackValue: (id) aValue;

@end

@interface vc_B : UIViewController

@property (nonatomic, weak(这里防止循环引用)) id<vc_ADelegate> delegate;

@end

跳转到vc_B的时候需要给vc_B的代理属性赋值,并且vc_A需要遵守vc_B的代理,vc_A还要实现vc_B的代理方法

#import "vc_A.h"

@interface vc_A:UIViewController()<vc_BDelegate>

@end

UIViewController *vc_B = ....

vc_B.delegate = self(这里的self表示的vc_A对象);

[vc_A push或者present到vc_B];

- (void)sendBackValue: (id) aValue{

//这里处理回调的任何操作

}

以上是代理的准备工作,接着搞定反向传值的传值时机,即在什么时候触发代理方法

假如vc_B中有如下的点击事件

- (void)btnClick:(UIButton *)sender{

//触发代理对象调用代理方法并传值

[_delegate  sendBackValue:(想要传的值)];

}

2>.block传值

vc_B中需要写一个block属性如下

@interface vc_B : UIViewController

@property (nonatomic, copy) void(^sendBackBlock)(id value);

@end

vc_A跳转到vc_B的时候实现block

UIViewController *vc_B = ....

vc_B.sendBackBlock = ^(id value){

//这里来处理回调,你可以在这里在规则之内为所欲为

};

[vc_A push或者present到vc_B];

以上是block的准备工作,接着搞定反向传值的传值时机,即在什么时候触发block方法

假如vc_B中有如下的点击事件

- (void)btnClick:(UIButton *)sender{

//触发block反向传值

if(_sendBackBlock){

_sendBackBlock(这里是你要传的参数);

}}

二. 视图控制器与其view上自定义子控件的传值

分析:这里拿tableView的cell举例说明,一般有两种情况:一个是从视图控制器给cell赋值另一个是从cell传事件和值到视图控制器

1>.从视图控制器给cell赋值

自定义cell要添加一个相对应的model属性

#import <UIKit/UIKit.h>

@class RapairRecordModel;

@interface MyMessageDetaileTableViewCell : UITableViewCell

@property (nonatomic, weak) RapairRecordModel *model;

@end

配置cell的时候给cell的model赋值

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

MyMessageDetaileTableViewCell(这个是自定义的cell) *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];

cell.model = _dataSource[indexPath.row];//这里是赋值的关键

return cell;

}

给cell的model赋值的时候会触发cell的model属性set方法,那我们重写此方法即可

//这是在cell的实现文件里的

- (void)setModel:(RapairRecordModel *)model{

//在这里你可以个cell的任何你想你需要的控件赋值

}

2>.从cell传事件和值到视图控制器

我这里是做了一个点击放大cell上图片的操作,使用的传事件和值的方式是block

首先创建一个block属性

#import <UIKit/UIKit.h>

@class RapairRecordModel;

@interface MyMessageDetaileTableViewCell : UITableViewCell

@property (copy, nonatomic) void(^ClicKImage)(UIView *view,UIImageView *imageView,RapairRecordModel *model);

@end

配置cell的代理方法中实现cell的block处理回调操作

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

MyMessageDetaileTableViewCell(这个是自定义的cell) *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];

cell.ClicKImage = ^(UIView *view, UIImageView *imageView, RapairRecordModel *model){

//这里处理回调操作

[ShowImagesManager shareManagerWithTapImageView:imageView withCurrentImageIndex:imageView.tag withTapImageViewSuperView:view withSourceImageUrls:imageUrls];

};

return cell;

}

cell上点击图片触发block回调

- (void)showDetaileImage:(UITapGestureRecognizer *)tap{

if (_ClicKImage) {

UIImageView *imageView = (UIImageView *)tap.view;

_ClicKImage(_imagesSuperView,imageView,_model);

}}

总结:以上简单的介绍了视图控制器包含的传值方式和实现.方法没有好坏之分,只要逻辑清晰条理分明代码规范保证性能的前提下实现功能,灵活使用才是关键.

相关文章

网友评论

    本文标题:iOS 视图控制器传值方式总结

    本文链接:https://www.haomeiwen.com/subject/wzbmottx.html