關(guān)于block(5)

標(biāo)簽: iOS 技術(shù)


接上篇,繼續(xù)block研究,這一篇講解實(shí)戰(zhàn)中的block反向傳值,一個(gè)非常實(shí)用的技術(shù)。

block反向傳值

  • 前面我們已經(jīng)得知,block可以作為參數(shù)而進(jìn)行傳遞
  • 也知道block是封裝了一段代碼塊,如同函數(shù)一樣,我們可以調(diào)用它,并用來(lái)傳遞一些信息,比如某個(gè)我們需要的參數(shù)值!
  • 但block的經(jīng)典使用,還是其反向傳值的簡(jiǎn)單明了

先看代碼

#import "TCHomeViewController.h"
#import "TCHomeCell.h"

static NSString *const kTCHomeCellIdentifier = @"TCHomeCell";

@interface TCHomeViewController () <UITableViewDelegate, UITableViewDataSource>

@property (nonatomic, strong) UITableView *tableView;

@property (nonatomic, strong) NSMutableArray<NSString *> *titles;

@end

@implementation TCHomeViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor whiteColor];
    self.titles = @[].mutableCopy;
    
    [self setupUI];
    [self setupData];
}

#pragma mark - UI

- (void)setupUI {
    [self.view addSubview:self.tableView];
    
    self.tableView.frame = self.view.bounds;
    [self.tableView registerClass:[TCHomeCell class] forCellReuseIdentifier:kTCHomeCellIdentifier];
}

- (void)setupData {
    NSArray *arr = @[@"我是誰(shuí)!",
                     @"我是人!??",
                     @"我是詩(shī)人!??",
                     @"我是大詩(shī)人!??",
                     @"我是偉大詩(shī)人!??"];
    self.titles = [NSMutableArray arrayWithArray:arr];
}

#pragma mark - UITableViewDataSource

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.titles.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    TCHomeCell *cell = [tableView dequeueReusableCellWithIdentifier:kTCHomeCellIdentifier forIndexPath:indexPath];
    cell.title = self.titles[indexPath.row];
    cell.homeCellBtnClickBlock = ^(BOOL isSelected) {
    // 拿到isSelected值,作進(jìn)一步操作
        if (isSelected) {
            NSLog(@"下載中");
        }
    };
    
    return cell;
}

#pragma mark - getter

- (UITableView *)tableView {
    if (!_tableView) {
        _tableView = [[UITableView alloc] init];
        _tableView.delegate = self;
        _tableView.dataSource = self;
        _tableView.rowHeight = 60.0f;
    }
    return _tableView;
}
@end

#import <UIKit/UIKit.h>

typedef void(^TCHomeCellBtnClickBlock)(BOOL isSeleted);

@interface TCHomeCell : UITableViewCell

@property (nonatomic, copy) TCHomeCellBtnClickBlock homeCellBtnClickBlock;

@property (nonatomic, strong) NSString *title;

@end
#import "TCHomeCell.h"

@interface TCHomeCell ()

/// 標(biāo)題標(biāo)簽
@property (nonatomic, strong) UILabel *titleLabel;

/// 下載按鈕
@property (nonatomic, strong) UIButton *downloadBtn;

@end

@implementation TCHomeCell

- (void)awakeFromNib {
    [super awakeFromNib];
    // Initialization code
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        [self setupUI];
    }
    return self;
}

#pragma mark - UI

- (void)setupUI {
    [self.contentView addSubview:self.titleLabel];
    [self.contentView addSubview:self.downloadBtn];
    
    CGFloat width = self.frame.size.width;
    CGFloat height = self.frame.size.height;
    
    self.titleLabel.frame = CGRectMake(10, 10, width * 0.5, height * 0.8);
    self.downloadBtn.frame = CGRectMake(width, 10, 80, height * 0.8);
}

#pragma mark - action

- (void)clickDownloadBtn:(UIButton *)btn {
    BOOL selected = !btn.selected;
    if (self.homeCellBtnClickBlock) {
        self.homeCellBtnClickBlock(selected);
    }
}

#pragma mark - setter

- (void)setTitle:(NSString *)title {
    if ([_title isEqualToString:title]) {
        return;
    }
    _title = title;
    self.titleLabel.text = _title;
}

#pragma mark - getter

- (UILabel *)titleLabel {
    if (!_titleLabel) {
        _titleLabel = [[UILabel alloc] init];
        _titleLabel.font = [UIFont systemFontOfSize:17.0];
        _titleLabel.textColor = [UIColor blackColor];
        [_titleLabel sizeToFit];
    }
    return _titleLabel;
}

- (UIButton *)downloadBtn {
    if (!_downloadBtn) {
        _downloadBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        _downloadBtn.frame = CGRectMake(0, 0, 100, 40);
        _downloadBtn.backgroundColor = [UIColor darkGrayColor];
        [_downloadBtn setTitle:@"download" forState:UIControlStateNormal];
        [_downloadBtn setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];
        [_downloadBtn addTarget:self action:@selector(clickDownloadBtn:) forControlEvents:UIControlEventTouchUpInside];
    }
    return _downloadBtn;
}
@end

說(shuō)明

  • 第一段代碼是控制器里面的代碼,處理業(yè)務(wù)邏輯
  • 第二段代碼是視圖cell的.h代碼,提供了兩個(gè)API
  • 第三段代碼是視圖cell的.m代碼,是處理視圖和數(shù)據(jù)展示的

解釋

  • 在cell的.h文件中,定義了一個(gè)block屬性,并定義了一個(gè)形參BOOL isSelected,那么這個(gè)形參就是我們需要傳遞的值,即傳給控制器的進(jìn)行業(yè)務(wù)處理的值
  • 在.m文件中,通過(guò)按鈕的點(diǎn)擊事件-clickDownloadBtn:來(lái)進(jìn)行block回調(diào),即self.homeCellBtnClickBlock(selected);
  • 那么我們需要用這個(gè)block來(lái)傳值,即selected,利用這個(gè)BOOL值來(lái)做進(jìn)一步操作,每一個(gè)cell都是不同的,而且我們也只能通過(guò)cell對(duì)象來(lái)訪問block屬性,故而block塊寫在了cell的初始化中,當(dāng)我們點(diǎn)擊cell的按鈕,就會(huì)有相應(yīng)的操作,在代碼中的block塊是NSLog代碼,通過(guò)這些打印我們知道按鈕的變化,而這些邏輯就恰好交由控制器處理,正好也體現(xiàn)了MVC的設(shè)計(jì)思想

程序運(yùn)行展示

界面展示

點(diǎn)擊事件
點(diǎn)擊download按鈕,就會(huì)在控制臺(tái)上看到打印輸出

2016-12-06 11:11:08.177 TCMyBlockDemo[8816:2632787] -[ViewController clickBtn:]
2016-12-06 11:11:16.283 TCMyBlockDemo[8816:2632787] 下載中

由此說(shuō)明,傳值成功!

寫在最后

反向傳值是block最實(shí)用的技術(shù),當(dāng)然也可以用代理來(lái)傳值,但定義代理、實(shí)現(xiàn)代理,是一個(gè)比較繁復(fù)的過(guò)程,而且代碼也不精簡(jiǎn)。
對(duì)代理熟悉的朋友可以試試,相信這樣的實(shí)戰(zhàn)在項(xiàng)目中經(jīng)常用到,如果你用膩了代理,那么不妨試試block
那么,關(guān)于block實(shí)戰(zhàn)的大致內(nèi)容也就差不多結(jié)束了,至于block在堆棧是怎么存在的,有很多文章可以搜到。我個(gè)人的block系列文章,都是在實(shí)戰(zhàn)中用到的,相信可以為一部分迷茫的朋友有所幫助,當(dāng)然如果真幫到了你,那么我這辛苦也就值了。
最后,感謝點(diǎn)贊,歡迎批評(píng)指正,歡迎轉(zhuǎn)載,完結(jié)!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,410評(píng)論 4 61
  • rongfuna閱讀 199評(píng)論 0 1
  • 從那以后“阿那”和“黑勞”就不會(huì)再離開了。這是一部繪本圖書的結(jié)尾。 我沒有想到的是這部小小的繪本和楊惠珊有關(guān)聯(lián),在...
    Andylee閱讀 1,015評(píng)論 0 2

友情鏈接更多精彩內(nèi)容