首页投稿(暂停使用,暂停投稿)iOS学习笔记iOS Developer

iOS转场及传值

2016-04-12  本文已影响639人  小鬼的世界

作为初学者, 有错误的地方还请大神们挑出, 本人接受批评, 多谢各位大神了

iOS转场: (RootViewController, SecondViewController)

<#(nonnull UIViewController *)#>: 目标viewController

animated: 是否存在动画

//Show: 选择Show,目的地视图会被压入导航栈顶部. 导航条会提供一个后退按钮,用以返回源视图. 这是最常用的方式.
//Show detail:与Show相似, 但会替换源视图. 将没有导航条和后退按钮.
[self.navigationController pushViewController:delita animated:YES];
[self.navigationController showViewController:delita sender:<#(nullable id)#>

completion: 转场之后做什么, 是一个block函数

//Present Modally: 模态显示内容.目的地视图会从底向上弹出, 通常用于显示跟页面连贯性不强的视图, 比如 添加餐馆, 添加用户(无论在哪个页面,都可能会调用此功能)
self.navigationController presentViewController:<#(nonnull UIViewController *)#> animated:<#(BOOL)#> completion:<#^(void)completion#>

Present as popover:iPad中常用,模态显示一个带箭头指向圆角矩形弹窗. 类似一个弹出菜单.

转场传值:

1. 属性传值

//转场方法
- (void)btnAction:(UIButton *)btn{
    SecondViewController *sec = [[SecondViewController alloc] init];//获取目标场景
    sec.string = self.label.text;//string为目标场景中的属性(NSString)
    [self.navigationController pushViewController:sec animated:YES];//转场
}

2. 代理传值(反向转场)

1. 设置代理

@protocol SecondViewControllerDelegate <NSObject>
@optional
- (void)changeTitle:(NSString *)title;
@end

2. 在SecondViewController.h定义代理

@property (nonatomic, assign) id<SecondViewControllerDelegate>delegate;

3. 在SecondViewController.m使用代理传值

- (void)backAction:(UIButton *)btn{
    if (self.delegate && [self.delegate respondsToSelector:@selector(changeTitle:)]) {//判断是必须的
        [self.delegate changeTitle:self.textField.text];
    }
    [self.navigationController popToRootViewControllerAnimated:YES];
}

4. 在RootViewController.m中遵循代理并且实现代理方法

记得让SecondViewController指定代理人为RootViewController.m

- (void)changeTitle:(NSString *)title{
    self.navigationItem.title = title;
}

3. block 传值

block定义

/**
     *    //定义一个参无返回值的block函数
     *    void 无返回值
     *
     *    @param ^ block名称
     *
     *    @^() 无参数
     */
    void (^voidFunc)() = ^(){
        NSLog(@"我是一个代码块");
    };
    //使用block
    voidFunc();
/**
     *    定义一个实现输出两个整数之和的block函数
     *    void 无返回值
     *    @param (int , int )类型说明
     *    @param a 参数
     *    @param b 参数
     */
    void (^addBlock)(int , int ) = ^(int a, int b){
        NSLog(@"a + b = %d", a + b);
    };
    addBlock(4, 6);
/**
     *    block命别称
     *
     *    @param void (^)(int , int) 函数类型
     *    @param Block 别名
     */
    typedef void (^Block)(int ,int );
    //给一个参数为两个整数, 返回值为整形的block类型命别称
    typedef int (^addTwo)(int ,int );
    //block使用
    addTwo subBlock = ^(int a, int b){
        return a-b;
    };
    //block中没有使用局部变量, block存储在全局区,
    //block中如果有使用全局变量, 则存储在栈区
    subBlock(10, 5);

block传值步骤

1. 在SecondViewController.h给block命别称(一般不省略)
typedef void(^titleBlock)(NSString *title);
2. 在SecondViewController.h中定义一个block属性
@property (nonatomic, copy) titleBlock myBlock;
//注意: block属性必须用copy
//block使用全局变量, 存在栈区, 使用copy是把block复制一份到堆区
3. 在跳转页面方法中给block属性赋值(RootViewController的btnAction:)
    //在block中使用局部变量
    //__block(MRC)/__weak(ARC)
    __weak RootViewController *temp = self;//复制指针(引用计数不变)
    //不使用temp而用self, 在下个界面会持有self, 引用计数会+1
    //使用self容易造成循环引用(MRC下)
    sec.myBlock = ^(NSString *title){
        temp.navigationItem.title = title;
    };
4. 调用block属性传入参数
- (void)backAction:(UIButton *)btn{
    self.myBlock(self.textField.text);
    [self.navigationController popToRootViewControllerAnimated:YES];
}

单例模式传值

1. 新建一个单例模式, 这里新建一个类白包含单例模式(User)

//在User.h中定义一些属性, 这些属性作为存取值的对象
@property (nonatomic, strong) NSString *userName;
@property (nonatomic, strong) NSString *passworld;
//设计一个单例模式初始化
//获取唯一的用户
+ (User *)defaultUser;

2. 实例化初始化

+ (User *)defaultUser{
    //static修饰的对象只会在第一次调用函数时初始化, 之后不再初始化
    static User *user = nil;
   if(user == nil){//判断user是否为空, 空则初始化
       user =[ [User alloc] init];
   }
   return user;
}

2. 在RootViewController.m中导入User.h, 同时在viewWillAppear(界面即将显示)中获取单例模式的值

- (void)viewWillAppear:(BOOL)animated{
    self.textField.text = [User defaultString].string;
}

3. 在转场按钮函数中将值存入User中

- (void)btnAction:(UIButton *)btn{
    SecondViewController *sec = [[SecondViewController alloc] init];
    //获取单例
    User *u = [User defaultString];
    //赋值
    u.string = self.textField.text;
    [self.navigationController pushViewController:sec animated:YES];
}
注: 如果需要让RootViewController一开始就显示, 比如让textField一开始就显示"单例模式"
//在viewDidLoad中直接初始化User并存值
self.textField.text = @"单例模式";
[User defaultString].string = self.textField.text;

4. 在SecondViewController中使用User中的string给self.textField.text赋值

self.textField = [[UITextField alloc] initWithFrame:CGRectMake(50, 200, 200, 50)];
    self.textField.borderStyle = UITextBorderStyleRoundedRect;
    self.textField.text = [User defaultString].string;
    self.textField.delegate = self;
    self.textField.textAlignment = NSTextAlignmentCenter;
    self.textField.clearButtonMode = UITextFieldViewModeAlways;
    [self.view addSubview:self.textField];

5. 在按钮返回函数中存储数据

- (void)btnAction:(UIButton *)btn{
    User *u = [User defaultString];
    u.string = self.textField.text;
    [self.navigationController popViewControllerAnimated:YES];//返回上层界面
}
上一篇下一篇

猜你喜欢

热点阅读