• IOS 控制器的数据传递 (顺传 and 逆传)


    ● 控制器之间的数据传递主要有2种情况:顺传和逆传

    ➢ 顺传

    ●  控制器的跳转方向: A ->C

    ●  数据的传递方向 : A -> C

    ● 数据的传递方式 : 在A的prepareForSegue:sender:方法中根据segue参数取得 destinationViewController,

       也就是控制器C, 直接给控制器C传递数据 (要在C的viewDidLoad方法中取得数据,来赋值给界面上的UI控件) 

    顺传事例代码:

    NJContatcsViewController.m(主控制器)

    #import "NJContatcsViewController.h"
    #import "NJAddViewController.h"
    #import "NJContatc.h"
    #import "NJEditViewController.h"
    
    @interface NJContatcsViewController ()<UIActionSheetDelegate, NJAddViewControllerDelegate, NJEditViewControllerDelegate>
    /**
     *  点击注销按钮
     */
    - (IBAction)logout:(UIBarButtonItem *)sender;
    
    /**
     *  保存所有用户数据
     */
    @property (nonatomic, strong) NSMutableArray *contatcs;
    @end
    
    @implementation NJContatcsViewController
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    }
    
    - (IBAction)logout:(UIBarButtonItem *)sender
    {
        UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"确定要注销?" delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:@"确定" otherButtonTitles:nil];
        [sheet showInView:self.view];
        
    }
    #pragma mark - UIActionSheetDelegate
    - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
    {
        if (0 != buttonIndex) return;
        
        // 移除栈顶控制器
        [self.navigationController popViewControllerAnimated:YES];
    }
    
    // 无论是手动类型的segue还是自动类型的segue, 在跳转之前都会执行该方法
    // 控制器跳转之前(执行segue之前)执行
    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
        // 0.判断目标控制器是添加还是编辑
        // 1.取出目标控制器
        UIViewController *vc = segue.destinationViewController;
        if ([vc isKindOfClass:[NJAddViewController class]]) {
            NJAddViewController *addVc = (NJAddViewController *)vc;
            // 2.设置代理
            addVc.delegate = self;
        }else if ([vc isKindOfClass:[NJEditViewController class]]){
            // 传递数据
            NJEditViewController *editVc = (NJEditViewController *)vc;
            
            // 通过tableview获取被点击的行号
            NSIndexPath *path = [self.tableView indexPathForSelectedRow];
            // 取出被点击行的模型
            NJContatc *c = self.contatcs[path.row];
            NSLog(@"联系人列表 %p" , c);
            // 赋值模型
            editVc.contatc = c;
            // 设置代理
            editVc.delegate = self;
        }
    }
    
    #pragma mark - NJEditViewControllerDelegate
    - (void)editViewControllerDidClickSavBtn:(NJEditViewController *)editViewController contatc:(NJContatc *)cpmtatc
    {
        // 1.修改模型
    //    NSIndexPath *path = [self.tableView indexPathForSelectedRow];
    //    self.contatcs[path.row] = cpmtatc;
        
        // 2.刷新表格
        [self.tableView reloadData];
    }
    
    #pragma mark - NJAddViewControllerDelegate
    - (void)addViewControllerDidAddBtn:(NJAddViewController *)editViewController contatc:(NJContatc *)contatc
    {
        NSLog(@"添加了新联系人 %@ %@ %@", contatc.name, contatc.phoneNumber, contatc.email);
        // 1.保存数据到数组中
        [self.contatcs addObject:contatc];
        // 2.刷新表格
        [self.tableView reloadData];
    }
    - (NSMutableArray *)contatcs
    {
        if (_contatcs == nil) {
            _contatcs = [NSMutableArray array];
        }
        return _contatcs;
    }
    
    #pragma mark - 数据源方法
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return self.contatcs.count;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *identifier = @"contatcs";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    //    if (cell == nil) {
    //        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identifier];
    //    }re
        
        // 设置数据
        NJContatc *c = self.contatcs[indexPath.row];//0
        NSLog(@"cellForRowAtIndexPath %p", c);
        cell.textLabel.text = c.name;
        cell.detailTextLabel.text = c.phoneNumber;
        // 返回cell
        return cell;
        
    }
    View Code

    ➢ 逆传 (使用代理方式)
    ● 控制器的跳转方向: A -> C

    ●  数据的传递方向 : C->A

    ●  数据的传递方式 : 让A成为C的代理, 在C中调用A的代理方法,通过代理方法的参数传递 数据给A 

    逆传事例代码:

    NJEditViewController.h(创建代理)

    #import <UIKit/UIKit.h>
    @class NJContatc, NJEditViewController;
    
    @protocol NJEditViewControllerDelegate <NSObject>
    
    - (void)editViewControllerDidClickSavBtn:(NJEditViewController *)editViewController contatc:(NJContatc *)cpmtatc;
    
    @end
    
    @interface NJEditViewController : UIViewController
    /**
     *  用于接收联系人列表传递过来的数据
     */
    @property (nonatomic, strong) NJContatc *contatc;
    
    @property (nonatomic, weak) id<NJEditViewControllerDelegate> delegate;
    @end
    View Code

    NJEditViewController.m(传递数据)

    #import "NJEditViewController.h"
    #import "NJContatc.h"
    
    @interface NJEditViewController ()
    
    @property (weak, nonatomic) IBOutlet UITextField *nameField;
    @property (weak, nonatomic) IBOutlet UITextField *phoneField;
    @property (weak, nonatomic) IBOutlet UIButton *saveBtn;
    /**
     *  编辑按钮点击事件
     */
    - (IBAction)editBtnOnClick:(UIBarButtonItem *)sender;
    /**
     *  保存按钮点击事件
     *
     *  @param sender <#sender description#>
     */
    - (IBAction)saveBtnOnClick:(UIButton *)sender;
    
    @end
    
    @implementation NJEditViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        // 设置姓名文本输入框
        self.nameField.text = _contatc.name;
        // 设置电话文本输入框
        self.phoneField.text = _contatc.phoneNumber;
        
        
        
        // 1.拿到通知中心
        NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
        // 2.注册监听
        // 注意点: 一定要写上通知的发布者
        [center addObserver:self selector:@selector(textChange) name:UITextFieldTextDidChangeNotification object:self.nameField];
        [center addObserver:self selector:@selector(textChange) name:UITextFieldTextDidChangeNotification object:self.phoneField];
    
    }
    
    - (void)dealloc
    {
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    
    - (void)textChange
    {
        self.saveBtn.enabled = (self.nameField.text.length > 0  &&
                                 self.phoneField.text.length > 0);
    }
    
    /*
     因为控制器的view是懒加载的, 用到的时候再加载
     而设置模型数据是在控制器跳转之前, 此时没有用到控制器的view,
     所以控制器的view还没有创建, 它的子控件也没有创建
     */
    /*
    - (void)setContatc:(NJContatc *)contatc
    {
        _contatc = contatc;
        
        NSLog(@"%p - %p", self.nameField, self.phoneField);
        NSLog(@"%@ - %@", self.nameField, self.phoneField);
        // 设置姓名文本输入框
        self.nameField.text = _contatc.name;
        // 设置电话文本输入框
        self.phoneField.text = _contatc.phoneNumber;
    }
     */
    - (IBAction)editBtnOnClick:(UIBarButtonItem *)sender {
        
        
        if (self.nameField.enabled) {
             // 当前是编辑状态
            // 1.让文本输入框不可以交互
            self.nameField.enabled = NO;
            self.phoneField.enabled = NO;
            // 2.隐藏保存按钮
            self.saveBtn.hidden = YES;
            // 3.让键盘消失
    //        [self.phoneField resignFirstResponder];
            [self.view endEditing:YES];
            // 4.修改按钮标题
            sender.title = @"编辑";
            // 5.还原数据
            // 设置姓名文本输入框
            self.nameField.text = _contatc.name;
            // 设置电话文本输入框
            self.phoneField.text = _contatc.phoneNumber;
            
        }else
        {
            // 当前是不可以编辑状态
            // 1.让文本输入框可以交互
            self.nameField.enabled = YES;
            self.phoneField.enabled = YES;
            // 2.显示保存按钮
            self.saveBtn.hidden = NO;
            // 3.让电话文本输入框召唤出键盘
            [self.phoneField becomeFirstResponder];
            // 4.修改按钮标题
            sender.title = @"取消";
        }
    }
    
    - (IBAction)saveBtnOnClick:(UIButton *)sender {
        
        // 1.移除栈顶控制器
        [self.navigationController popViewControllerAnimated:YES];
        
        // 2.修改模型数据
        NSLog(@"编辑界面 %p" , self.contatc);
        self.contatc.name = self.nameField.text;
        self.contatc.phoneNumber = self.phoneField.text;
        // 3.通知代理
        if ([self.delegate respondsToSelector:@selector(editViewControllerDidClickSavBtn:contatc:)]) {
            [self.delegate editViewControllerDidClickSavBtn:self contatc:self.contatc];
        }
        
    }
    View Code

    NJContatcsViewController.m(主控制器 实现代理方法)

    #pragma mark - NJEditViewControllerDelegate
    - (void)editViewControllerDidClickSavBtn:(NJEditViewController *)editViewController contatc:(NJContatc *)cpmtatc
    {
        // 1.修改模型
    //    NSIndexPath *path = [self.tableView indexPathForSelectedRow];
    //    self.contatcs[path.row] = cpmtatc;
        
        // 2.刷新表格
        [self.tableView reloadData];
    }
    
    #pragma mark - NJAddViewControllerDelegate
    - (void)addViewControllerDidAddBtn:(NJAddViewController *)editViewController contatc:(NJContatc *)contatc
    {
        NSLog(@"添加了新联系人 %@ %@ %@", contatc.name, contatc.phoneNumber, contatc.email);
        // 1.保存数据到数组中
        [self.contatcs addObject:contatc];
        // 2.刷新表格
        [self.tableView reloadData];
    }
    - (NSMutableArray *)contatcs
    {
        if (_contatcs == nil) {
            _contatcs = [NSMutableArray array];
        }
        return _contatcs;
    }
    View Code
  • 相关阅读:
    兴趣遍地都是,专注和持之以恒才是真正稀缺的
    vuecli2和vuecli3项目中添加网页标题图标
    vue+sentry 前端异常日志监控
    从零构建vue项目(三)--vue常用插件
    从零构建vue项目(一)--搭建node环境,拉取项目模板
    dbvisualizer安装
    TS学习笔记----(一)基础类型
    基于weui loading插件封装
    UI组件--element-ui--全部引入和按需引入
    vue_全局注册过滤器
  • 原文地址:https://www.cnblogs.com/liuwj/p/6530854.html
Copyright © 2020-2023  润新知