cdts/xdts-ios 3/TreeHole/CYHResetCode/CYH/QMUIKit/QMUIComponents/StaticTableView/UITableView+QMUIStaticCell.m

144 lines
8.3 KiB
Mathematica
Raw Permalink Normal View History

2023-07-27 09:20:00 +08:00
/**
* Tencent is pleased to support the open source community by making QMUI_iOS available.
* Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved.
* Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
//
// UITableView+QMUIStaticCell.m
// qmui
//
// Created by QMUI Team on 2017/6/20.
//
#import "UITableView+QMUIStaticCell.h"
#import "QMUICore.h"
#import "QMUIStaticTableViewCellDataSource.h"
#import "QMUILog.h"
#import "QMUIMultipleDelegates.h"
@interface QMUIStaticTableViewCellDataSource ()
@property(nonatomic, weak, readwrite) UITableView *tableView;
@end
@implementation UITableView (QMUI_StaticCell)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
OverrideImplementation([UITableView class], @selector(setDataSource:), ^id(__unsafe_unretained Class originClass, SEL originCMD, IMP (^originalIMPProvider)(void)) {
return ^(UITableView *selfObject, id<UITableViewDataSource> dataSource) {
if (dataSource && selfObject.qmui_staticCellDataSource) {
void (^addSelectorBlock)(id<UITableViewDataSource>) = ^void(id<UITableViewDataSource> aDataSource) {
// addMethod setDataSource tableView method
// addMethod App
[selfObject addSelector:@selector(numberOfSectionsInTableView:) withImplementation:(IMP)staticCell_numberOfSections types:"l@:@" forObject:aDataSource];
[selfObject addSelector:@selector(tableView:numberOfRowsInSection:) withImplementation:(IMP)staticCell_numberOfRows types:"l@:@l" forObject:aDataSource];
[selfObject addSelector:@selector(tableView:cellForRowAtIndexPath:) withImplementation:(IMP)staticCell_cellForRow types:"@@:@@" forObject:aDataSource];
};
if ([dataSource isKindOfClass:[QMUIMultipleDelegates class]]) {
NSPointerArray *delegates = [((QMUIMultipleDelegates *)dataSource).delegates copy];
for (id delegate in delegates) {
if ([delegate conformsToProtocol:@protocol(UITableViewDataSource)]) {
addSelectorBlock((id<UITableViewDataSource>)delegate);
}
}
} else {
addSelectorBlock((id<UITableViewDataSource>)dataSource);
}
}
// call super
void (*originSelectorIMP)(id, SEL, id<UITableViewDataSource>);
originSelectorIMP = (void (*)(id, SEL, id<UITableViewDataSource>))originalIMPProvider();
originSelectorIMP(selfObject, originCMD, dataSource);
};
});
OverrideImplementation([UITableView class], @selector(setDelegate:), ^id(__unsafe_unretained Class originClass, SEL originCMD, IMP (^originalIMPProvider)(void)) {
return ^(UITableView *selfObject, id<UITableViewDelegate> delegate) {
if (delegate && selfObject.qmui_staticCellDataSource) {
void (^addSelectorBlock)(id<UITableViewDelegate>) = ^void(id<UITableViewDelegate> aDelegate) {
// addMethod setDelegate tableView method
// addMethod App
[selfObject addSelector:@selector(tableView:heightForRowAtIndexPath:) withImplementation:(IMP)staticCell_heightForRow types:"d@:@@" forObject:aDelegate];
[selfObject addSelector:@selector(tableView:didSelectRowAtIndexPath:) withImplementation:(IMP)staticCell_didSelectRow types:"v@:@@" forObject:aDelegate];
[selfObject addSelector:@selector(tableView:accessoryButtonTappedForRowWithIndexPath:) withImplementation:(IMP)staticCell_accessoryButtonTapped types:"v@:@@" forObject:aDelegate];
};
if ([delegate isKindOfClass:[QMUIMultipleDelegates class]]) {
NSPointerArray *delegates = [((QMUIMultipleDelegates *)delegate).delegates copy];
for (id d in delegates) {
if ([d conformsToProtocol:@protocol(UITableViewDelegate)]) {
addSelectorBlock((id<UITableViewDelegate>)d);
}
}
} else {
addSelectorBlock((id<UITableViewDelegate>)delegate);
}
}
// call super
void (*originSelectorIMP)(id, SEL, id<UITableViewDelegate>);
originSelectorIMP = (void (*)(id, SEL, id<UITableViewDelegate>))originalIMPProvider();
originSelectorIMP(selfObject, originCMD, delegate);
};
});
});
}
static char kAssociatedObjectKey_staticCellDataSource;
- (void)setQmui_staticCellDataSource:(QMUIStaticTableViewCellDataSource *)qmui_staticCellDataSource {
objc_setAssociatedObject(self, &kAssociatedObjectKey_staticCellDataSource, qmui_staticCellDataSource, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
qmui_staticCellDataSource.tableView = self;
[self reloadData];
}
- (QMUIStaticTableViewCellDataSource *)qmui_staticCellDataSource {
return (QMUIStaticTableViewCellDataSource *)objc_getAssociatedObject(self, &kAssociatedObjectKey_staticCellDataSource);
}
- (void)addSelector:(SEL)selector withImplementation:(IMP)implementation types:(const char *)types forObject:(NSObject *)object {
if (!class_addMethod(object.class, selector, implementation, types)) {
// addMethod class log
[QMUIHelper executeBlock:^{
QMUILog(NSStringFromClass(self.class), @"尝试为 %@ 添加方法 %@ 失败,可能该类里已经实现了这个方法", NSStringFromClass(object.class), NSStringFromSelector(selector));
} oncePerIdentifier:[NSString stringWithFormat:@"addedlog %@-%@", NSStringFromClass(object.class), NSStringFromSelector(selector)]];
}
}
#pragma mark - DataSource
NSInteger staticCell_numberOfSections (id current_self, SEL current_cmd, UITableView *tableView) {
return tableView.qmui_staticCellDataSource.cellDataSections.count;
}
NSInteger staticCell_numberOfRows (id current_self, SEL current_cmd, UITableView *tableView, NSInteger section) {
return tableView.qmui_staticCellDataSource.cellDataSections[section].count;
}
id staticCell_cellForRow (id current_self, SEL current_cmd, UITableView *tableView, NSIndexPath *indexPath) {
QMUITableViewCell *cell = [tableView.qmui_staticCellDataSource cellForRowAtIndexPath:indexPath];
return cell;
}
#pragma mark - Delegate
CGFloat staticCell_heightForRow (id current_self, SEL current_cmd, UITableView *tableView, NSIndexPath *indexPath) {
return [tableView.qmui_staticCellDataSource heightForRowAtIndexPath:indexPath];
}
void staticCell_didSelectRow (id current_self, SEL current_cmd, UITableView *tableView, NSIndexPath *indexPath) {
[tableView.qmui_staticCellDataSource didSelectRowAtIndexPath:indexPath];
}
void staticCell_accessoryButtonTapped (id current_self, SEL current_cmd, UITableView *tableView, NSIndexPath *indexPath) {
[tableView.qmui_staticCellDataSource accessoryButtonTappedForRowWithIndexPath:indexPath];
}
@end