iOS開発:応答チェーン法を用いて価値伝達とイベント伝達を実現

10218 ワード

引用:
カスタムcellにbuttonがある場合、buttonのクリックイベントがカスタムcellの属性値をコントローラに渡すにはどうすればいいですか?
もちろんエージェント、通知、blockコールバックを利用することができますが、それ以外に方法はありませんか?あります!それは今日お話しするルーティング応答チェーンの方法であり,重複コードやコードの美観性を回避することである.

ダイレクトコード


UIresponderのクラス:


@interface UIResponder (YJRouter)

- (void)routerWithEventName:(NSString *)eventName modelInfo:(NSDictionary *)modelInfo;

@end

 

#import "UIResponder+Router.h" @implementation UIResponder (Router) - (void)routerWithEventName:(NSString *)eventName userInfo:(NSDictionary *)userInfo { if (self.nextResponder) { [[self nextResponder] routerWithEventName:eventName userInfo:userInfo]; } } @end


Cellクラス:

#import 
#import "YJButtonModel.h"

static NSString *const TransferNameEvent = @"TransferNameEvent";
static NSString *const ButtonTag = @"ButtonTag";
static NSString *const ModelInfo = @"ModelInfo";

@interface YJButtonTableViewCell : UITableViewCell

@property (strong, nonatomic) YJButtonModel *model;

@end#import "YJButtonTableViewCell.h"

@interface YJButtonTableViewCell ()

@property (strong, nonatomic) UIButton *sureButton;
@property (strong, nonatomic) UIButton *deleteButton;

@property (strong, nonatomic) YJButtonModel *modelInfo;

@end

@implementation YJButtonTableViewCell

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if ([super initWithStyle:style reuseIdentifier:reuseIdentifier]) {

        [self setupViews];
    }
    return self;
}

- (void)setupViews
{
    self.sureButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [self.sureButton setTitle:@" " forState:UIControlStateNormal];
    self.sureButton.backgroundColor = [UIColor greenColor];
    [self.sureButton addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
    [self.contentView addSubview:self.sureButton];

    self.deleteButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [self.deleteButton setTitle:@" " forState:UIControlStateNormal];
    self.deleteButton.backgroundColor = [UIColor redColor];
    [self.deleteButton addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];

    [self.contentView addSubview:self.deleteButton];

    [self.sureButton mas_makeConstraints:^(MASConstraintMaker *make) {

        make.centerY.equalTo(self.contentView.mas_centerY);
        make.right.equalTo(self.contentView.mas_right).offset(-20);

    }];

    [self.deleteButton mas_makeConstraints:^(MASConstraintMaker *make) {

        make.centerY.equalTo(self.contentView.mas_centerY);
        make.right.equalTo(self.sureButton.mas_left).offset(-20);


    }];
}

// 
- (void)setModel:(YJButtonModel *)model
{
    self.modelInfo = model;
    self.textLabel.text = model.title;
}

// 
- (void)buttonAction:(UIButton *)sender
{
    [sender routerWithEventName:TransferNameEvent modelInfo:@{ButtonTag:sender.titleLabel.text, ModelInfo:self.modelInfo}];
}

Controllerの主な方法:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    YJButtonTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ButtonCell forIndexPath:indexPath];

    cell.model = self.dataArray[indexPath.row];
    // Configure the cell...

    return cell;
}

// 
- (void)routerWithEventName:(NSString *)eventName modelInfo:(NSDictionary *)modelInfo
{
    if ([eventName isEqualToString:TransferNameEvent]) {

        if ([modelInfo[ButtonTag] isEqualToString:@" "]) {

            NSLog(@" :%@", [modelInfo[ModelInfo] title]);

        } else {

            NSLog(@" :%@", [modelInfo[ModelInfo] title]);

            // model 
            [self.dataArray removeObject:modelInfo[ModelInfo]];
            // 
            [self.baseTableView reloadData];

        }
    }
}