// // UIView+YMEmpty.m // MSYOUPAI // // Created by YoMi on 2023/11/6. // #import "YMEmptyView.h" #import "UIView+YMEmpty.h" #import #pragma mark - ------------------ UIView ------------------ @implementation UIView (YMEmpty) + (void)exchangeInstanceMethod1:(SEL)method1 method2:(SEL)method2 { method_exchangeImplementations(class_getInstanceMethod(self, method1), class_getInstanceMethod(self, method2)); } #pragma mark - Setter/Getter static char kEmptyViewKey; - (void)setYm_emptyView:(YMEmptyView *)ym_emptyView{ if (ym_emptyView != self.ym_emptyView) { objc_setAssociatedObject(self, &kEmptyViewKey, ym_emptyView, OBJC_ASSOCIATION_RETAIN_NONATOMIC); for (UIView *view in self.subviews) { if ([view isKindOfClass:[YMEmptyView class]]) { [view removeFromSuperview]; } } [self addSubview:self.ym_emptyView]; if ([self isKindOfClass:[UITableView class]] || [self isKindOfClass:[UICollectionView class]]) { [self getDataAndSet]; // 添加时根据DataSource去决定显隐 } else { self.ym_emptyView.hidden = YES;// 添加时默认隐藏 } } } - (YMEmptyView *)ym_emptyView{ return objc_getAssociatedObject(self, &kEmptyViewKey); } #pragma mark - Private Method (UITableView、UICollectionView有效) - (NSInteger)totalDataCount { NSInteger totalCount = 0; if ([self isKindOfClass:[UITableView class]]) { UITableView *tableView = (UITableView *)self; for (NSInteger section = 0; section < tableView.numberOfSections; section++) { totalCount += [tableView numberOfRowsInSection:section]; } } else if ([self isKindOfClass:[UICollectionView class]]) { UICollectionView *collectionView = (UICollectionView *)self; for (NSInteger section = 0; section < collectionView.numberOfSections; section++) { totalCount += [collectionView numberOfItemsInSection:section]; } } return totalCount; } - (void)getDataAndSet{ //没有设置emptyView的,直接返回 if (!self.ym_emptyView) { return; } if ([self totalDataCount] == 0) { [self show]; }else{ [self hide]; } } - (void)show{ //当不自动显隐时,内部自动调用show方法时也不要去显示,要显示的话只有手动去调用 ym_showEmptyView if (!self.ym_emptyView.autoShowEmptyView) { return; } [self ym_showEmptyView]; } - (void)hide{ //当不自动显隐时,内部自动调用hide方法时也不要去隐藏,要隐藏的话只有手动去调用 ym_hideEmptyView if (!self.ym_emptyView.autoShowEmptyView) { return; } [self ym_hideEmptyView]; } #pragma mark - Public Method - (void)ym_showEmptyView{ NSAssert(![self isKindOfClass:[YMEmptyView class]], @"YMEmptyView及其子类不能调用ym_showEmptyView方法"); self.ym_emptyView.hidden = NO; //让 emptyBGView 始终保持在最上层 [self bringSubviewToFront:self.ym_emptyView]; } - (void)ym_hideEmptyView{ NSAssert(![self isKindOfClass:[YMEmptyView class]], @"YMEmptyView及其子类不能调用ym_hideEmptyView方法"); self.ym_emptyView.hidden = YES; } - (void)ym_startLoading{ NSAssert(![self isKindOfClass:[YMEmptyView class]], @"YMEmptyView及其子类不能调用ym_startLoading方法"); self.ym_emptyView.hidden = YES; } - (void)ym_endLoading{ NSAssert(![self isKindOfClass:[YMEmptyView class]], @"YMEmptyView及其子类不能调用ym_endLoading方法"); self.ym_emptyView.hidden = [self totalDataCount]; } @end #pragma mark - ------------------ UITableView ------------------ @implementation UITableView (YMEmpty) + (void)load{ [self exchangeInstanceMethod1:@selector(reloadData) method2:@selector(ym_reloadData)]; ///section [self exchangeInstanceMethod1:@selector(insertSections:withRowAnimation:) method2:@selector(ym_insertSections:withRowAnimation:)]; [self exchangeInstanceMethod1:@selector(deleteSections:withRowAnimation:) method2:@selector(ym_deleteSections:withRowAnimation:)]; [self exchangeInstanceMethod1:@selector(reloadSections:withRowAnimation:) method2:@selector(ym_reloadSections:withRowAnimation:)]; ///row [self exchangeInstanceMethod1:@selector(insertRowsAtIndexPaths:withRowAnimation:) method2:@selector(ym_insertRowsAtIndexPaths:withRowAnimation:)]; [self exchangeInstanceMethod1:@selector(deleteRowsAtIndexPaths:withRowAnimation:) method2:@selector(ym_deleteRowsAtIndexPaths:withRowAnimation:)]; [self exchangeInstanceMethod1:@selector(reloadRowsAtIndexPaths:withRowAnimation:) method2:@selector(ym_reloadRowsAtIndexPaths:withRowAnimation:)]; } - (void)ym_reloadData{ [self ym_reloadData]; [self getDataAndSet]; } ///section - (void)ym_insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation{ [self ym_insertSections:sections withRowAnimation:animation]; [self getDataAndSet]; } - (void)ym_deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation{ [self ym_deleteSections:sections withRowAnimation:animation]; [self getDataAndSet]; } - (void)ym_reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation{ [self ym_reloadSections:sections withRowAnimation:animation]; [self getDataAndSet]; } ///row - (void)ym_insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation{ [self ym_insertRowsAtIndexPaths:indexPaths withRowAnimation:animation]; [self getDataAndSet]; } - (void)ym_deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation{ [self ym_deleteRowsAtIndexPaths:indexPaths withRowAnimation:animation]; [self getDataAndSet]; } - (void)ym_reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation{ [self ym_reloadRowsAtIndexPaths:indexPaths withRowAnimation:animation]; [self getDataAndSet]; } @end #pragma mark - ------------------ UICollectionView ------------------ @implementation UICollectionView (YMEmpty) + (void)load{ [self exchangeInstanceMethod1:@selector(reloadData) method2:@selector(ym_reloadData)]; ///section [self exchangeInstanceMethod1:@selector(insertSections:) method2:@selector(ym_insertSections:)]; [self exchangeInstanceMethod1:@selector(deleteSections:) method2:@selector(ym_deleteSections:)]; [self exchangeInstanceMethod1:@selector(reloadSections:) method2:@selector(ym_reloadSections:)]; ///item [self exchangeInstanceMethod1:@selector(insertItemsAtIndexPaths:) method2:@selector(ym_insertItemsAtIndexPaths:)]; [self exchangeInstanceMethod1:@selector(deleteItemsAtIndexPaths:) method2:@selector(ym_deleteItemsAtIndexPaths:)]; [self exchangeInstanceMethod1:@selector(reloadItemsAtIndexPaths:) method2:@selector(ym_reloadItemsAtIndexPaths:)]; } - (void)ym_reloadData{ [self ym_reloadData]; [self getDataAndSet]; } ///section - (void)ym_insertSections:(NSIndexSet *)sections{ [self ym_insertSections:sections]; [self getDataAndSet]; } - (void)ym_deleteSections:(NSIndexSet *)sections{ [self ym_deleteSections:sections]; [self getDataAndSet]; } - (void)ym_reloadSections:(NSIndexSet *)sections{ [self ym_reloadSections:sections]; [self getDataAndSet]; } ///item - (void)ym_insertItemsAtIndexPaths:(NSArray *)indexPaths{ [self ym_insertItemsAtIndexPaths:indexPaths]; [self getDataAndSet]; } - (void)ym_deleteItemsAtIndexPaths:(NSArray *)indexPaths{ [self ym_deleteItemsAtIndexPaths:indexPaths]; [self getDataAndSet]; } - (void)ym_reloadItemsAtIndexPaths:(NSArray *)indexPaths{ [self ym_reloadItemsAtIndexPaths:indexPaths]; [self getDataAndSet]; } @end