Objective-C的页面传值

第一篇Objective的文章,第一次使用Markdown来写。


页面传值的方法有很多,也很常用到,Delegate/NSNotification/Block/NSUserDefault/单例,等等。
一项一项增加,先写最常用的委托传值,也就是Delegate,老师讲的方法。(TryAttack,这个无聊的时候玩这个。)


委托传值 Delegate

协议方法是一种非常常用的传值方法,只要在协议中声明一个协议方法,然后两个类一个作为委托方一个作为遵守方来调用和实现方法就可以实现传值。十分高效而且针对性很强。

我们建立完Text Field元件和程式码的关联后,完成页面1UIViewControllerButton 拖拽到 SecndViewController ,並且在Custom Class 的Class中设定第二个ViewController 为 SecndViewController (即客制化所对应的Class)。这样就产生了 Storyboard Segue 的方法,选者Model作为连接,Storyboard Segue 就会自动连接到UIViewController
如果想要使用不同的换页效果,可以在 Storyboard Segue 中的 Transition 属性做修改。
接下来我们就来实作委托传值的方法,首先来考虑如何往 SecndViewController 进行传值。

  1. 透过 Storyboard Segue 传值,在页面 2SecndViewController 的 UIViewController class 里设置一个 NSString 的变数,它用来接收由页面 1 透过 Storyboard Segue 所传过来的值,程式码如下。
     @property (strong) NSString* strAttackPower;

之后在SecndViewController.hviewDidLoad函式里我们将 string 的值指定给 pAttackResult,此时页面 2 加载时就会把 pAttackResult的内容设成 Storyboard Segue 所传送过来的值。

     - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        int iDefensValue = rand()%10;
        iScore = [strAttackPower intValue] - iDefensValue;
        if ( iScore > 0 ){
            pAttackResult.text = [NSString stringWithFormat: @"攻击造成%d伤害,得分%d", iScore, iScore];
        }else {
            pAttackResult.text = @"攻击被防御";
            iScore = 0;
        }
     }

接着回到页面 1 的 UIViewController class 里,新增一个内建的函式 prepareForSegue,至此我们完成透过 Storyboard Segue 传值的方法。

     -(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
        id pNextPage = segue.destinationViewController;
        [pNextPage setValue:[NSString stringWithFormat: @"%d", 1+rand()%10 ] forKey: @"strAttackPower"];
        [pNextPage setValue:self forKey:@"delegate"];
     }

ViewController 切换(Segue)之前会呼叫上面的方法,至此我们完成了向下一层的传值。

  • 关键点在 setValue: forKey: 下面看一下定义:
    setValue: forKey:

setValue: forKey:中value能够为nil,但是当value为nil的时候,会自动调用 removeObject: forKey:方法,key的参数只能够是NSString类型,而对应的 setObject: forKey: 的可以是任何类型

2.返回先前页面的方法
使用 dismissModalViewControllerAnimated: 方法,或是 dismissViewControllerAnimated:completion: 方法来解散SecndViewController,并返回先前的页面。

     - (IBAction)goBack:(id)sender {
        if ([self.delegate respondsToSelector:@selector(incrementScore:from:)]) {
            [self.delegate incrementScore:iScore from:self];
        }
        [self dismissViewControllerAnimated:YES completion: ^{}];
     }

3.由上面的两步我们已经建立两个可以互相切换的 UIViewController,一个是透过 Storyboard Segue 来切换并且向下传值,另一个则是使用 dismissViewControllerAnimated: 的方法来返回先前的 UIViewController。
接下来就是要解决的就是 SecndViewController 向上传值的部分,也就是通过代理委托delegate,建立一个协定 @protocol 的方式。

将此分为两个角色五个步骤。
委托者:
1.声明delegate属性。2.调用协议方法。
被委托者:
1.遵守协议。2.设定为被委托者。3.覆写协议方法。

委托者 SecndViewController
1.声明delegate属性:首先在页面 2 的 UIViewController class,建立一个协定 incrementScoreDelegate,并且定义其内部的方法 goBack:,接着宣告一个采用此协定的物件 delegate,其程式码如下。

     
     //建立一个协定
     @protocol incrementScoreDelegate;
     @interface SecndViewController : UIViewController
     @property (strong, nonatomic) IBOutlet UITextField *pAttackResult;
     @property (strong) NSString* strAttackPower;
     //协定中的方法
     @property (weak) id<incrementScoreDelegate> delegate;
      - (IBAction)goBack:(id)sender;
     @end
     //宣告一个採用incrementScoreDelegate 协定的物件 
     @protocol incrementScoreDelegate <NSObject>
      - (void) incrementScore: (int) score from:(SecndViewController* ) page;
     @end

2.调用协议方法: 也就是上面第二點2.返回先前页面的方法,要呼叫协定必须写在按钮事件中。当我们按下页面2的按钮的时候,就会呼叫采用incrementScoreDelegate的Class,因此Class必须实作协定内的方法。

被委托者 UIViewController
1.遵守协议:採用协定的方式是在 @interface 区段的地方加上 <协定名称> 的程式码,由于此协定是写在其他的 class 中,所以在採用协定之前要先引用它,以下是页面1的 UIViewController class.h 档。

     //引用持有incrementScoreDelegate协定的class 
     #import "SecndViewController.h"
     //採用协定 
     @interface ViewController : UIViewController <incrementScoreDelegate>

2.设定为被委托者:在 .m 档中实作协定内的 incrementScore: 方法函式。

     - (void) incrementScore:(int)score from:(SecndViewController *)page {
         iTotalScore = iTotalScore + score;
         pScoreBoardLable.text = [NSString stringWithFormat:@"Score: %d", iTotalScore];
     }

3.覆写协议方法: 如果忽略此步骤,页面2里的 delegate 参数在呼叫 goBack 方法时,并不会知道是哪个 class实作了它的方法,因此参数也无法由页面2SecndViewController传递至页面1UIViewController

     - (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
        //将 pNextPage 设定成Storyboard Segue的目标UIViewController
            id pNextPage = segue.destinationViewController;
        //将值透过Storyboard Segue带给页面2 `pNextPage` 的string变数  
            [pNextPage setValue:[NSString stringWithFormat: @"%d", 1+rand()%10 ] forKey: @"strAttackPower"];
        //将delegate设成自己(指定自己为代理)  
            [pNextPage setValue:self forKey:@"delegate"];
       }

协议传值的五步,最重要的是思考清楚,谁作为委托者,谁遵守协议,然后用这五个步骤来进行实作。


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容