diff --git a/keyBoard/Class/Base/V/BaseTableView.h b/keyBoard/Class/Base/V/BaseTableView.h index 4704fff..9395838 100644 --- a/keyBoard/Class/Base/V/BaseTableView.h +++ b/keyBoard/Class/Base/V/BaseTableView.h @@ -2,16 +2,44 @@ // BaseTableView.h // keyBoard // -// A lightweight UITableView subclass for common defaults. +// 通用表格基类: +// - 统一一些默认配置(背景色、分割线、键盘收起等) +// - 可选接入 DZNEmptyDataSet(空数据占位视图),默认开启,按需关闭 +// - 通过 __has_include 判断三方库是否存在;即使工程未集成该库也能正常编译 // #import NS_ASSUME_NONNULL_BEGIN +typedef void(^KBEmptyAction)(void); + @interface BaseTableView : UITableView + +#pragma mark - 空数据占位(DZNEmptyDataSet,可开关) +/// 是否启用空数据占位(默认 YES)。若工程未集成 DZNEmptyDataSet,此开关不生效但不会影响编译。 +@property (nonatomic, assign) BOOL useEmptyDataSet; +/// 标题(默认:"暂无数据") +@property (nonatomic, copy, nullable) NSString *emptyTitleText; +/// 描述(可选) +@property (nonatomic, copy, nullable) NSString *emptyDescriptionText; +/// 占位图(可选) +@property (nonatomic, strong, nullable) UIImage *emptyImage; +/// 按钮标题(可选) +@property (nonatomic, copy, nullable) NSString *emptyButtonTitle; +/// 垂直偏移(默认 0) +@property (nonatomic, assign) CGFloat emptyVerticalOffset; +/// 空视图是否允许滚动(默认 YES) +@property (nonatomic, assign) BOOL emptyShouldAllowScroll; +/// 点击整体视图回调(可选) +@property (nonatomic, copy, nullable) KBEmptyAction emptyDidTapView; +/// 点击按钮回调(可选) +@property (nonatomic, copy, nullable) KBEmptyAction emptyDidTapButton; + +/// 触发刷新空数据视图(若集成了 DZNEmptyDataSet 则调用其 reloadEmptyDataSet) +- (void)kb_reloadEmptyDataSet; + @end NS_ASSUME_NONNULL_END - diff --git a/keyBoard/Class/Base/V/BaseTableView.m b/keyBoard/Class/Base/V/BaseTableView.m index 2d8c519..0d743e3 100644 --- a/keyBoard/Class/Base/V/BaseTableView.m +++ b/keyBoard/Class/Base/V/BaseTableView.m @@ -5,6 +5,20 @@ #import "BaseTableView.h" +// 可选引入:若未集成 DZNEmptyDataSet,此处不会编译进来 +#if __has_include() +#import +#define KB_HAS_DZN 1 +#else +#define KB_HAS_DZN 0 +#endif + +@interface BaseTableView () +#if KB_HAS_DZN + +#endif +@end + @implementation BaseTableView - (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style { @@ -15,16 +29,102 @@ } + - (void)commonInit { + // iOS 15+ 头部默认留白,统一归零(老系统无此属性,不会影响) self.sectionHeaderTopPadding = 0; self.backgroundColor = [UIColor whiteColor]; self.separatorStyle = UITableViewCellSeparatorStyleSingleLine; - // Disable estimates to avoid jumpy updates for simple lists; tweak per-screen if needed self.estimatedRowHeight = 0; self.estimatedSectionHeaderHeight = 0; self.estimatedSectionFooterHeight = 0; self.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag; + + // 空数据占位默认配置(保持“活”的:可开可关) + _useEmptyDataSet = YES; // 默认开启 + _emptyShouldAllowScroll = YES; // 默认允许滚动 + _emptyVerticalOffset = 0; // 默认不偏移 + _emptyTitleText = @"暂无数据"; // 默认标题 + +#if KB_HAS_DZN + self.emptyDataSetSource = self; + self.emptyDataSetDelegate = self; +#endif } -@end +#pragma mark - Public +- (void)kb_reloadEmptyDataSet { +#if KB_HAS_DZN + [self reloadEmptyDataSet]; +#endif +} + +- (void)setUseEmptyDataSet:(BOOL)useEmptyDataSet { + _useEmptyDataSet = useEmptyDataSet; +#if KB_HAS_DZN + // 切换时,动态挂/卸源委托 + self.emptyDataSetSource = useEmptyDataSet ? (id)self : nil; + self.emptyDataSetDelegate = useEmptyDataSet ? (id)self : nil; + [self reloadEmptyDataSet]; +#endif +} + +#pragma mark - DZNEmptyDataSet (仅当库存在时编译) +#if KB_HAS_DZN + +// 是否展示空视图 +- (BOOL)emptyDataSetShouldDisplay:(UIScrollView *)scrollView { + return self.useEmptyDataSet; +} + +// 标题 +- (NSAttributedString *)titleForEmptyDataSet:(UIScrollView *)scrollView { + NSString *title = self.emptyTitleText ?: @""; + NSDictionary *attrs = @{ NSFontAttributeName : [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold], + NSForegroundColorAttributeName : [UIColor colorWithWhite:0.5 alpha:1.0] }; + return [[NSAttributedString alloc] initWithString:title attributes:attrs]; +} + +// 描述 +- (NSAttributedString *)descriptionForEmptyDataSet:(UIScrollView *)scrollView { + if (self.emptyDescriptionText.length == 0) return nil; + NSDictionary *attrs = @{ NSFontAttributeName : [UIFont systemFontOfSize:14], + NSForegroundColorAttributeName : [UIColor colorWithWhite:0.6 alpha:1.0] }; + return [[NSAttributedString alloc] initWithString:self.emptyDescriptionText attributes:attrs]; +} + +// 图片 +- (UIImage *)imageForEmptyDataSet:(UIScrollView *)scrollView { + return self.emptyImage; +} + +// 按钮标题 +- (NSAttributedString *)buttonTitleForEmptyDataSet:(UIScrollView *)scrollView forState:(UIControlState)state { + if (self.emptyButtonTitle.length == 0) return nil; + UIColor *color = (state == UIControlStateHighlighted) ? [UIColor darkTextColor] : [UIColor colorWithRed:0.22 green:0.49 blue:0.96 alpha:1.0]; + NSDictionary *attrs = @{ NSFontAttributeName : [UIFont systemFontOfSize:15 weight:UIFontWeightSemibold], + NSForegroundColorAttributeName : color }; + return [[NSAttributedString alloc] initWithString:self.emptyButtonTitle attributes:attrs]; +} + +// 垂直位置偏移 +- (CGFloat)verticalOffsetForEmptyDataSet:(UIScrollView *)scrollView { + return self.emptyVerticalOffset; +} + +// 行为 +- (BOOL)emptyDataSetShouldAllowScroll:(UIScrollView *)scrollView { return self.emptyShouldAllowScroll; } +- (BOOL)emptyDataSetShouldAllowTouch:(UIScrollView *)scrollView { return YES; } + +- (void)emptyDataSet:(UIScrollView *)scrollView didTapView:(UIView *)view { + if (self.emptyDidTapView) self.emptyDidTapView(); +} + +- (void)emptyDataSet:(UIScrollView *)scrollView didTapButton:(UIButton *)button { + if (self.emptyDidTapButton) self.emptyDidTapButton(); +} + +#endif + +@end