2018年初九 上班第一天


今天初九,也是2018年上班第一天,继续 改bug、优化代码、提升用户体验, 真心希望旅图的产品越来越好。

MJRefresh 下拉刷新时触发taptic反馈 第一种方式: 在继承UITableView的子类中重新setMj_header:方法,并hook住mj_header的setState:方法,当state == MJRefreshStatePulling时,触发taptic反馈, 示例代码:

#import <MJRefresh.h>
#import "Aspects.h"

@interface BBTableView ()
#ifdef __IPHONE_10_0
@property (nonatomic, strong) UIImpactFeedbackGenerator *feedbackGenerator;
#endif
@property (nonatomic, strong) NSMutableArray<id<AspectToken>> *aspectArray;
@end

@implementation BBTableView
- (void)setMj_header:(MJRefreshHeader *)mj_header {
    if (self.mj_header != mj_header) {
        [self clearAspects];
        NSError *error = nil;
        __weak typeof(&*self) weakSelf = self;
        id<AspectToken> asp = [mj_header aspect_hookSelector:@selector(setState:) withOptions:AspectPositionAfter usingBlock:^(id instance, MJRefreshState state){
            if (state == MJRefreshStatePulling) {
                __strong typeof(&*weakSelf) self = weakSelf;
                // 触发taptic反馈
#ifdef __IPHONE_10_0
                [self.feedbackGenerator impactOccurred];
#endif
            }

        } error:&error];
        if (asp) {
            [self.aspectArray addObject:asp];
        }
    }
    [super setMj_header:mj_header];
}

- (void)clearAspects {
    [self.aspectArray enumerateObjectsUsingBlock:^(id<AspectToken>  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [obj remove];
    }];
    [self.aspectArray removeAllObjects];
}

@end

第二种方法: 全局添加,直接给MJRefreshHeader添加分类,并交换setState:方法实现 示例代码:

@implementation MJRefreshHeader (BBFeedbackGenerator)

#ifdef __IPHONE_10_0
- (UIImpactFeedbackGenerator *)feedbackGenerator {
    UIImpactFeedbackGenerator *feedbackGenerator = objc_getAssociatedObject(self, _cmd);
    if (feedbackGenerator == nil) {
        feedbackGenerator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleLight];
        objc_setAssociatedObject(self, _cmd, feedbackGenerator, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    return feedbackGenerator;
}
#endif

- (void)bb_setState:(MJRefreshState)state {
    if (self.state != state) {
        if (state == MJRefreshStatePulling) {
            // 触发taptic反馈
#ifdef __IPHONE_10_0
            [self.feedbackGenerator impactOccurred];
#endif
        }
    }

    [self bb_setState:state];

}

+ (void)load {
    [self exchangeInstanceMethod1:@selector(setState:) method2:@selector(bb_setState:)];
}

+ (void)exchangeInstanceMethod1:(SEL)method1 method2:(SEL)method2
{
    method_exchangeImplementations(class_getInstanceMethod(self, method1), class_getInstanceMethod(self, method2));
}
@end

附件: