iOS中的傳值方式

在日常開發(fā)過程中机断,我們經常會遇到值傳遞畸颅。這里盟猖,介紹幾種iOS開發(fā)中常見的傳值方式讨衣。

1.屬性傳值

屬性傳值是iOS中最為常見的正向傳值方式,假定我們現在有這樣一個需求式镐,在A控制器點擊按鈕反镇,將按鈕的標題顯示在B控制器的label上。首先娘汞,我們創(chuàng)建兩個控制器CCFirstViewController和CCSecondViewController,在CCSecondViewController.h中聲明一個屬性

@interface CCSecondViewController : UIViewController
@property (nonatomic, strong) NSString *buttonTitleString;
@end
@interface CCSecondViewController
 
@end

@implementation CCSecondViewController
- (void)viewDidLoad {
    
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor whiteColor];
    
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 30)];
    
    label.center = self.view.center;
    
    label.text = self.buttonTitleString;
    
    [self.view addSubview:label];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    [self dismissViewControllerAnimated:YES completion:nil];
    
}
@end

現在歹茶,在第二個控制器中已經有了接收按鈕標題的屬性,接下來,在第一個控制器中添加一個按鈕惊豺,點擊按鈕讓第一個控制器將按鈕標題傳遞給第二個控制器燎孟。

@interface CCFirstViewController ()

@end

@implementation CCFirstViewController

- (void)viewDidLoad {
    
    [super viewDidLoad];
    
    UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
    
    button.frame = CGRectMake(0, 0, 100, 30);
    
    button.center = self.view.center;
    
    [button setTitle:@"浪漫戀星空" forState:UIControlStateNormal];
    
    [button addTarget:self action:@selector(handleButtonEvent:) forControlEvents:UIControlEventTouchDragInside];
    
    [self.view addSubview:button];
}

- (void)handleButtonEvent:(UIButton *)sender {
    
    CCSecondViewController *vc  = [[CCSecondViewController alloc] init];
    
    vc.buttonTitleString = sender.currentTitle;
    
    [self presentViewController:vc animated:YES completion:nil];
}

@end

運行程序,點擊第一個控制器的按鈕跳轉到第二個控制器尸昧,我們會發(fā)現第二個控制器的label已經有值了揩页。這就是屬性傳值的簡單應用。

屬性傳值的基本步驟就是在需要接收值的控制器公開一個屬性烹俗,在前一個控制器跳轉的事件中初始化接收值的控制器爆侣,將需要傳遞的值賦值給接收值的控制器公開的屬性,接下來做控制器的跳轉幢妄。

2.代理傳值

在日常的開發(fā)中兔仰,我們遇到的值傳遞不可能只是簡單的正向傳遞,很多時候我們也需要將第二個控制器中的值傳遞給前一個控制器蕉鸳,這就是常見的反向傳值乎赴。屬性傳值已經不能滿足我們的需求了,就需要用到第二種常見的傳值方式置吓,代理傳值和二。同樣假定一個需求他爸,在B控制器點擊按鈕涨醋,將按鈕的標題顯示在A控制器的label上功蜓。還是用上述兩個創(chuàng)建好的控制器完成。
簡單的將第一個控制器中的label和第二個控制器中的button創(chuàng)建好戴质,為了方便度宦,這里將第一個控制器的跳轉事件直接寫到touch事件里面(感覺有哪里沒對)。接下來告匠,我們需要做的是點擊第二個控制器中的按鈕戈抄,將按鈕的標題傳回第一個控制器。
首先后专,在需要傳值出去的控制器划鸽,也就是我們的第二個控制器的.h文件中,聲明一個協(xié)議戚哎,并且聲明一個傳值需要的協(xié)議方法裸诽。

// 聲明協(xié)議以及傳值的方法
@protocol CCSecondViewControllerDelegate <NSObject>

- (void)sendButtonTitleToFirst:(NSString *)string;

@end

接下來,聲明一個代理屬性型凳。

@interface CCSecondViewController : UIViewController
// 聲明代理屬性(這里要用weakU啥!甘畅!最開始使用代理埂蕊,都會踩的坑往弓。這里先不做過多解釋。)
@property (nonatomic, weak) id<CCSecondViewControllerDelegate> delegate;

@end

然后呢蓄氧,我們在第二個控制器的按鈕點擊事件中函似,讓代理響應傳值的方法。

- (void)handleButtonEvent:(UIButton *)sender {
    
    // 判斷代理是否存在匀们,并且已經響應了傳值方法
    if (self.delegate && [self.delegate respondsToSelector:@selector(sendButtonTitleToFirst:)]) {
        // 傳值
        [self.delegate sendButtonTitleToFirst:sender.currentTitle];
    }
    
    [self dismissViewControllerAnimated:YES completion:nil];
}

需要在第二個控制器中做的事已經做完了缴淋。去到第一個控制器准给,在第二個控制器初始化完成的地方泄朴,將第二個控制器的代理設置為第一個控制器,遵守代理露氮,然后去實現傳值方法祖灰。

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    CCSecondViewController *vc  = [[CCSecondViewController alloc] init];
    // 設置代理屬性
    vc.delegate = self;
    
    [self presentViewController:vc animated:YES completion:nil];
}

// 遵守代理
@interface CCFirstViewController ()<CCSecondViewControllerDelegate>

// 實現傳值的方法
- (void)sendButtonTitleToFirst:(NSString *)string {
    
    self.label.text = string;
}

然后呢,好像就沒有然后了畔规。局扶。。
整理一下現在兩個控制器中的代碼

#import "CCFirstViewController.h"
#import "CCSecondViewController.h"

@interface CCFirstViewController ()<CCSecondViewControllerDelegate>

@property (nonatomic, strong) UILabel *label;

@end

@implementation CCFirstViewController

- (void)viewDidLoad {
    
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor whiteColor];
    
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 30)];
    
    label.center = self.view.center;
    
    [self.view addSubview:label];
    
    self.label = label;
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    CCSecondViewController *vc  = [[CCSecondViewController alloc] init];
    
    vc.delegate = self;
    
    [self presentViewController:vc animated:YES completion:nil];
}

- (void)sendButtonTitleToFirst:(NSString *)string {
    
    self.label.text = string;
}

@end

第二個控制器的.h文件

@protocol CCSecondViewControllerDelegate <NSObject>

- (void)sendButtonTitleToFirst:(NSString *)string;

@end

@interface CCSecondViewController : UIViewController

@property (nonatomic, weak) id<CCSecondViewControllerDelegate> delegate;

@end

.m文件

@interface CCSecondViewController ()


@end

@implementation CCSecondViewController

- (void)viewDidLoad {
    
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor whiteColor];
    
    UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
    
    button.frame = CGRectMake(0, 0, 100, 30);
    
    button.center = self.view.center;
    
    [button setTitle:@"浪漫戀星空" forState:UIControlStateNormal];
    
    [button addTarget:self action:@selector(handleButtonEvent:) forControlEvents:UIControlEventTouchDragInside];
    
    [self.view addSubview:button];
}

- (void)handleButtonEvent:(UIButton *)sender {
    
    if (self.delegate && [self.delegate respondsToSelector:@selector(sendButtonTitleToFirst:)]) {
        [self.delegate sendButtonTitleToFirst:sender.currentTitle];
    }
    
    [self dismissViewControllerAnimated:YES completion:nil];
}

@end

代理傳值的基本使用就是這樣了叁扫∪瑁總結一下基本的步驟。

  • 1.擬定一個代理協(xié)議莫绣,聲明協(xié)議方法畴蒲。
  • 2.聲明代理屬性。
  • 3.使用代理对室。
  • 4.設置代理屬性模燥。
  • 5.遵守代理,實現代理方法掩宜。

3.Block傳值

反向傳值除了上面說到的代理傳值蔫骂,還有一種常見的傳值方式,就是Block傳值牺汤。上面的反向傳值需求再用Block的方式實現一遍辽旋。

首先,在第二個控制器中聲明一個Block檐迟,通常情況下补胚,為了代碼的可讀性,我們會為Block取一個別名锅减。

typedef void(^SendButtonTitleToFirsrBlock)(NSString *string);

上面這一行代碼呢糖儡,就是給我們的Block取了一個我們想要的名字。結構大致是這樣的 怔匣。

typedef 返回值類型(^我們想取的Block的別名)(參數);

在第二個控制器中聲明一個Block屬性

// 用我們自定義的Bolck聲明一個block屬性
@property (nonatomic, copy) SendButtonTitleToFirsrBlock block;

在按鈕的點擊事件中使用Block;

- (void)handleButtonEvent:(UIButton *)sender {
    
    if (self.block) {
        
        self.block(sender.currentTitle);
    }
    
    [self dismissViewControllerAnimated:YES completion:nil];
}

接下來只需要在第一個控制器中初始化第二個控制器完成的地方握联,使用Block桦沉。

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    CCSecondViewController *vc  = [[CCSecondViewController alloc] init];
    
    vc.block = ^(NSString *string) {
        
        self.label.text = string;
    };
    
    [self presentViewController:vc animated:YES completion:nil];
}

做完這些,把工程common + R 一下金闽,我們就可以看到和代理實現了一模一樣的需求纯露。看上去也更簡單代芜。

綜上埠褪,這些就是在日常開發(fā)中常用的傳值方式。當然挤庇,代理和Block能做的事多了钞速,這里只是介紹它們傳值的簡單使用。如果你在閱讀過程中發(fā)現有不足和錯誤嫡秕,請留言指出渴语。謝謝大家。如果你覺得這篇文章能給你帶來一點點收獲昆咽,不勝榮幸驾凶!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市掷酗,隨后出現的幾起案子调违,更是在濱河造成了極大的恐慌,老刑警劉巖泻轰,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件技肩,死亡現場離奇詭異,居然都是意外死亡糕殉,警方通過查閱死者的電腦和手機亩鬼,發(fā)現死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來阿蝶,“玉大人雳锋,你說我怎么就攤上這事∠劢啵” “怎么了玷过?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長筑煮。 經常有香客問我辛蚊,道長,這世上最難降的妖魔是什么真仲? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任袋马,我火速辦了婚禮,結果婚禮上秸应,老公的妹妹穿的比我還像新娘虑凛。我一直安慰自己碑宴,他們只是感情好,可當我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布桑谍。 她就那樣靜靜地躺著延柠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪锣披。 梳的紋絲不亂的頭發(fā)上贞间,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天,我揣著相機與錄音雹仿,去河邊找鬼增热。 笑死,一個胖子當著我的面吹牛盅粪,可吹牛的內容都是我干的钓葫。 我是一名探鬼主播悄蕾,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼票顾,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了帆调?” 一聲冷哼從身側響起奠骄,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎番刊,沒想到半個月后含鳞,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡芹务,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年蝉绷,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片枣抱。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡熔吗,死狀恐怖,靈堂內的尸體忽然破棺而出佳晶,到底是詐尸還是另有隱情桅狠,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布轿秧,位于F島的核電站中跌,受9級特大地震影響,放射性物質發(fā)生泄漏菇篡。R本人自食惡果不足惜漩符,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望驱还。 院中可真熱鬧嗜暴,春花似錦津滞、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至狐赡,卻和暖如春撞鹉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背颖侄。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工鸟雏, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人览祖。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓孝鹊,卻偏偏與公主長得像,于是被迫代替她去往敵國和親展蒂。 傳聞我的和親對象是個殘疾皇子又活,可洞房花燭夜當晚...
    茶點故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內容