UItableViewはデータなしのビット画像を実現
2804 ワード
国際慣例、効果図
1.gif
この効果の実装は主にruntimeのクロスメソッドを用いて実現され,tableViewのreloadDataとカスタムkk_reloadData交換.新しいtableViewのCategory.交換メソッドプライマリコード
reloadDataの交換
kk_reloadDataメソッドは、まずデータがあるかどうかをチェックし、再度kk_reloadDataメソッドがruntimeの交換メソッドを使用している場合、実際にはシステムのreloadDataメソッドが呼び出されます.
kk_checkEmptyメソッド
コードの侵入を低減するために、tableViewにViewプロパティ、すなわちビットマップビューを動的に追加できます.
kk_checkEmptyの
次のように変更
以降はtableViewのplaceHolderViewプロパティを設定するだけで済みます
終了githubアドレス:https://github.com/wuzaozhou/UITableView-placeholder
1.gif
この効果の実装は主にruntimeのクロスメソッドを用いて実現され,tableViewのreloadDataとカスタムkk_reloadData交換.新しいtableViewのCategory.交換メソッドプライマリコード
+ (void)swizzleInstanceSelector:(SEL)originalSel
WithSwizzledSelector:(SEL)swizzledSel {
Method originMethod = class_getInstanceMethod(self, originalSel);
Method swizzedMehtod = class_getInstanceMethod(self, swizzledSel);
BOOL methodAdded = class_addMethod(self, originalSel, method_getImplementation(swizzedMehtod), method_getTypeEncoding(swizzedMehtod));
if (methodAdded) {
class_replaceMethod(self, swizzledSel, method_getImplementation(originMethod), method_getTypeEncoding(originMethod));
}else{
method_exchangeImplementations(originMethod, swizzedMehtod);
}
}
reloadDataの交換
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self swizzleInstanceSelector:@selector(reloadData) WithSwizzledSelector:@selector(kk_reloadData)];
});
}
kk_reloadDataメソッドは、まずデータがあるかどうかをチェックし、再度kk_reloadDataメソッドがruntimeの交換メソッドを使用している場合、実際にはシステムのreloadDataメソッドが呼び出されます.
- (void)kk_reloadData {
[self kk_checkEmpty];
[self kk_reloadData];
}
kk_checkEmptyメソッド
- (void)kk_checkEmpty {
BOOL isEmpty = YES;
id src = self.dataSource;
NSInteger sections = 1;
if ([src respondsToSelector:@selector(numberOfSectionsInTableView:)]) {
sections = [src numberOfSectionsInTableView:self];
}
for (int i = 0; i < sections; i++) {
NSInteger rows = [src tableView:self numberOfRowsInSection:i];
if (rows) {
isEmpty = NO;
}
}
if (isEmpty) {// ,
}else{// ,
}
}
コードの侵入を低減するために、tableViewにViewプロパティ、すなわちビットマップビューを動的に追加できます.
@property (nonatomic, strong) UIView *placeHolderView;
- (void)setPlaceHolderView:(UIView *)placeHolderView {
objc_setAssociatedObject(self, @selector(placeHolderView), placeHolderView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIView *)placeHolderView {
return objc_getAssociatedObject(self, @selector(placeHolderView));
}
kk_checkEmptyの
if (isEmpty) {// ,
}else{// ,
}
次のように変更
if (isEmpty) {
[self.placeHolderView removeFromSuperview];
[self addSubview:self.placeHolderView];
}else{
[self.placeHolderView removeFromSuperview];
}
以降はtableViewのplaceHolderViewプロパティを設定するだけで済みます
_tableView.placeHolderView = [[UIView alloc] init];
終了githubアドレス:https://github.com/wuzaozhou/UITableView-placeholder