UIButton实现原理的猜想

#import 
@class TQButton;

typedef void(^TouchUpInsideAction)(TQButton * _Nullable button);

@interface TQButton : UIControl

@property (nullable, nonatomic, readonly, strong) UILabel *titleLabel;

- (nullable instancetype)initWithFrame:(CGRect)frame
          touchUpInsideAction:(nullable TouchUpInsideAction)action;

- (void)setTitle:(nullable NSString *)title
        forState:(UIControlState)state;

@end
#import "TQButton.h"

@interface TQButton ()

@property (nullable, nonatomic, readwrite, strong) UILabel *titleLabel;
@property (nullable, nonatomic, copy) TouchUpInsideAction touchUpInsideAction;
@end

@implementation TQButton {
    
    NSMutableDictionary *_titleDict;
}

- (nullable instancetype)initWithFrame:(CGRect)frame
                   touchUpInsideAction:(nullable TouchUpInsideAction)action {
    
    if (self = [super initWithFrame:frame]) {
        [self setup];
        _touchUpInsideAction = action;
    }
    return self;
}

- (void)setup {
    _titleDict = [@{} mutableCopy];
    [self addSubview:self.titleLabel];
    [self addObserver:self forKeyPath:@"selected" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
    [self addObserver:self forKeyPath:@"highlighted" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
    [self addTarget:self action:@selector(touchUpInsideEvent:) forControlEvents:UIControlEventTouchUpInside];
}

- (void)touchUpInsideEvent:(TQButton *)btn {
    if (self.touchUpInsideAction) {
        self.touchUpInsideAction(btn);
    }
}

- (UILabel *)titleLabel {
    if (!_titleLabel) {
        _titleLabel = ({
            UILabel *label = [[UILabel alloc] initWithFrame:self.bounds];
            label.textColor = [UIColor blackColor];
            label.font = [UIFont systemFontOfSize:17];
            label.textAlignment = NSTextAlignmentCenter;
            label;
        });
    }
    return _titleLabel;
}

- (void)dealloc {
    [self removeObserver:self forKeyPath:@"selected"];
    [self removeObserver:self forKeyPath:@"highlighted"];
}

- (void)setTitle:(nullable NSString *)title forState:(UIControlState)state {
    _titleDict[@(state)] = title;
    self.titleLabel.text = _titleDict[@(self.state)];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    
    if ([keyPath isEqualToString:@"selected"]) {
        BOOL value = [change[@"new"] boolValue];
        self.titleLabel.text = _titleDict[value? @(UIControlStateSelected):@(UIControlStateNormal)];
    }
    else if([keyPath isEqualToString:@"highlighted"]) {
        BOOL value = [change[@"new"] boolValue];
        if (value) {
            self.titleLabel.text = _titleDict[@(UIControlStateHighlighted)];
        }
        else {
            self.titleLabel.text = _titleDict[self.selected? @(UIControlStateSelected):@(UIControlStateNormal)];
        }
    }
}

@end

你可能感兴趣的:(UIButton实现原理的猜想)