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);
}}