Files
keyboard/keyBoard/Class/Base/V/BaseTableView.m
2025-11-17 20:07:39 +08:00

202 lines
7.3 KiB
Objective-C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// BaseTableView.m
// keyBoard
//
#import "BaseTableView.h"
// 可选引入:若未集成 DZNEmptyDataSet此处不会编译进来
#if __has_include(<DZNEmptyDataSet/UIScrollView+EmptyDataSet.h>)
#import <DZNEmptyDataSet/UIScrollView+EmptyDataSet.h>
#define KB_HAS_DZN 1
#else
#define KB_HAS_DZN 0
#endif
// 可选引入LYEmptyView通过 Pod 集成),用于空态视图的“自动显隐+属性配置”方案
#if __has_include(<LYEmptyView/UIView+Empty.h>)
#import <LYEmptyView/UIView+Empty.h>
#import <LYEmptyView/LYEmptyView.h>
#define KB_HAS_LY 1
#else
#define KB_HAS_LY 0
#endif
@interface BaseTableView ()
#if KB_HAS_DZN
<DZNEmptyDataSetSource, DZNEmptyDataSetDelegate>
#endif
@end
@implementation BaseTableView
- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style {
if (self = [super initWithFrame:frame style:style]) {
[self commonInit];
}
return self;
}
- (void)commonInit {
// iOS 15+ 头部默认留白,统一归零(老系统无此属性,不会影响)
self.sectionHeaderTopPadding = 0;
self.backgroundColor = [UIColor whiteColor];
self.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
self.estimatedRowHeight = 0;
self.estimatedSectionHeaderHeight = 0;
self.estimatedSectionFooterHeight = 0;
self.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
// 空数据占位默认配置(保持“活”的:可开可关)
_useEmptyDataSet = YES; // 默认开启
_emptyShouldAllowScroll = YES; // 默认允许滚动
_emptyVerticalOffset = 0; // 默认不偏移
_emptyTitleText = KBLocalized(@"暂无数据"); // 默认标题
#if KB_HAS_DZN
self.emptyDataSetSource = self;
self.emptyDataSetDelegate = self;
#endif
}
#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<DZNEmptyDataSetSource>)self : nil;
self.emptyDataSetDelegate = useEmptyDataSet ? (id<DZNEmptyDataSetDelegate>)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
// MARK: - LYEmptyView 快速挂载(与 DZN 二选一)
- (void)kb_makeDefaultEmptyViewWithImage:(UIImage *)image
title:(NSString *)title
detail:(NSString *)detail
buttonTitle:(NSString *)buttonTitle
tapHandler:(KBEmptyAction)tapHandler
buttonHandler:(KBEmptyAction)buttonHandler {
#if KB_HAS_LY
// 关闭 DZN避免两套空态叠加
self.useEmptyDataSet = NO;
// 默认文案
NSString *t = title ?: KBLocalized(@"暂无数据");
LYEmptyView *ev = nil;
if (buttonTitle.length > 0) {
// 带按钮(优先 block 方式)
__weak typeof(self) weakSelf = self;
ev = [LYEmptyView emptyActionViewWithImage:image
titleStr:t
detailStr:detail ?: @""
btnTitleStr:buttonTitle
btnClickBlock:^{ if (buttonHandler) buttonHandler(); [weakSelf setNeedsLayout]; }];
} else {
// 无按钮
ev = [LYEmptyView emptyViewWithImage:image titleStr:t detailStr:detail ?: @""];
}
// 点击空白区域
if (tapHandler) {
ev.tapEmptyViewBlock = ^{ tapHandler(); };
}
// 统一样式(可按需微调)
ev.emptyViewIsCompleteCoverSuperView = NO; // 不全屏覆盖,按内容大小布局
ev.ignoreContentInset = YES; // 忽略 inset避免导航/安全区影响
ev.contentViewOffset = -10; // 轻微上移
ev.subViewMargin = 14; // 子控件间距
ev.titleLabFont = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold];
ev.titleLabTextColor = [UIColor colorWithWhite:0.45 alpha:1.0];
ev.detailLabFont = [UIFont systemFontOfSize:14];
ev.detailLabTextColor = [UIColor colorWithWhite:0.6 alpha:1.0];
ev.detailLabLineSpacing = 3;
ev.detailLabMaxLines = 2;
ev.actionBtnFont = [UIFont systemFontOfSize:15 weight:UIFontWeightSemibold];
ev.actionBtnCornerRadius = 6;
ev.actionBtnBorderWidth = 1;
ev.actionBtnBorderColor = [UIColor colorWithWhite:0.88 alpha:1.0];
ev.actionBtnTitleColor = [UIColor colorWithRed:0.22 green:0.49 blue:0.96 alpha:1.0];
ev.actionBtnBackGroundColor = [UIColor whiteColor];
ev.actionBtnHorizontalMargin = 20; // 自动宽度:文字 + padding*2
// 自动显隐交由控制层(网络请求)
ev.autoShowEmptyView = NO;
self.ly_emptyView = (LYEmptyView *)ev;
#else
// 未集成 LYEmptyView 时不做任何处理,保持兼容
(void)image; (void)title; (void)detail; (void)buttonTitle; (void)tapHandler; (void)buttonHandler;
#endif
}
@end