1
This commit is contained in:
@@ -70,10 +70,11 @@
|
||||
048908EF2EBF861800FABA60 /* KBSkinSectionTitleCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 048908EE2EBF861800FABA60 /* KBSkinSectionTitleCell.m */; };
|
||||
048908F22EC047FD00FABA60 /* KBShopHeadView.m in Sources */ = {isa = PBXBuildFile; fileRef = 048908F12EC047FD00FABA60 /* KBShopHeadView.m */; };
|
||||
048908F52EC0496400FABA60 /* KBShopItemVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 048908F42EC0496400FABA60 /* KBShopItemVC.m */; };
|
||||
048908FE2EC0CC2400FABA60 /* UIScrollView+KBEmptyView.m in Sources */ = {isa = PBXBuildFile; fileRef = 048908FD2EC0CC2400FABA60 /* UIScrollView+KBEmptyView.m */; };
|
||||
048909F62EC0AAAA00FABA60 /* KBCategoryTitleCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 048909F12EC0AAAA00FABA60 /* KBCategoryTitleCell.m */; };
|
||||
048909F72EC0AAAA00FABA60 /* KBCategoryTitleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 048909F32EC0AAAA00FABA60 /* KBCategoryTitleView.m */; };
|
||||
04890A042EC0BBBB00FABA60 /* KBCategoryTitleImageCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 04890A012EC0BBBB00FABA60 /* KBCategoryTitleImageCell.m */; };
|
||||
04890A052EC0BBBB00FABA60 /* KBCategoryTitleImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04890A032EC0BBBB00FABA60 /* KBCategoryTitleImageView.m */; };
|
||||
04890A042EC0BBBB00FABA60 /* KBCategoryTitleImageCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 04890A012EC0BBBB00FABA60 /* KBCategoryTitleImageCell.m */; };
|
||||
04890A052EC0BBBB00FABA60 /* KBCategoryTitleImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04890A032EC0BBBB00FABA60 /* KBCategoryTitleImageView.m */; };
|
||||
04A9FE0F2EB481100020DB6D /* KBHUD.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC97082EB31B14007BD342 /* KBHUD.m */; };
|
||||
04A9FE132EB4D0D20020DB6D /* KBFullAccessManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 04A9FE112EB4D0D20020DB6D /* KBFullAccessManager.m */; };
|
||||
04A9FE162EB873C80020DB6D /* UIViewController+Extension.m in Sources */ = {isa = PBXBuildFile; fileRef = 04A9FE152EB873C80020DB6D /* UIViewController+Extension.m */; };
|
||||
@@ -252,14 +253,16 @@
|
||||
048908F12EC047FD00FABA60 /* KBShopHeadView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBShopHeadView.m; sourceTree = "<group>"; };
|
||||
048908F32EC0496400FABA60 /* KBShopItemVC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBShopItemVC.h; sourceTree = "<group>"; };
|
||||
048908F42EC0496400FABA60 /* KBShopItemVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBShopItemVC.m; sourceTree = "<group>"; };
|
||||
048908FC2EC0CC2400FABA60 /* UIScrollView+KBEmptyView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIScrollView+KBEmptyView.h"; sourceTree = "<group>"; };
|
||||
048908FD2EC0CC2400FABA60 /* UIScrollView+KBEmptyView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIScrollView+KBEmptyView.m"; sourceTree = "<group>"; };
|
||||
048909F02EC0AAAA00FABA60 /* KBCategoryTitleCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBCategoryTitleCell.h; sourceTree = "<group>"; };
|
||||
048909F12EC0AAAA00FABA60 /* KBCategoryTitleCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBCategoryTitleCell.m; sourceTree = "<group>"; };
|
||||
048909F22EC0AAAA00FABA60 /* KBCategoryTitleView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBCategoryTitleView.h; sourceTree = "<group>"; };
|
||||
048909F32EC0AAAA00FABA60 /* KBCategoryTitleView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBCategoryTitleView.m; sourceTree = "<group>"; };
|
||||
04890A002EC0BBBB00FABA60 /* KBCategoryTitleImageCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBCategoryTitleImageCell.h; sourceTree = "<group>"; };
|
||||
04890A012EC0BBBB00FABA60 /* KBCategoryTitleImageCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBCategoryTitleImageCell.m; sourceTree = "<group>"; };
|
||||
04890A022EC0BBBB00FABA60 /* KBCategoryTitleImageView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBCategoryTitleImageView.h; sourceTree = "<group>"; };
|
||||
04890A032EC0BBBB00FABA60 /* KBCategoryTitleImageView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBCategoryTitleImageView.m; sourceTree = "<group>"; };
|
||||
04890A002EC0BBBB00FABA60 /* KBCategoryTitleImageCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBCategoryTitleImageCell.h; sourceTree = "<group>"; };
|
||||
04890A012EC0BBBB00FABA60 /* KBCategoryTitleImageCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBCategoryTitleImageCell.m; sourceTree = "<group>"; };
|
||||
04890A022EC0BBBB00FABA60 /* KBCategoryTitleImageView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBCategoryTitleImageView.h; sourceTree = "<group>"; };
|
||||
04890A032EC0BBBB00FABA60 /* KBCategoryTitleImageView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBCategoryTitleImageView.m; sourceTree = "<group>"; };
|
||||
04A9A67D2EB9E1690023B8F4 /* KBResponderUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBResponderUtils.h; sourceTree = "<group>"; };
|
||||
04A9FE102EB4D0D20020DB6D /* KBFullAccessManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBFullAccessManager.h; sourceTree = "<group>"; };
|
||||
04A9FE112EB4D0D20020DB6D /* KBFullAccessManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBFullAccessManager.m; sourceTree = "<group>"; };
|
||||
@@ -506,10 +509,10 @@
|
||||
048909F12EC0AAAA00FABA60 /* KBCategoryTitleCell.m */,
|
||||
048909F22EC0AAAA00FABA60 /* KBCategoryTitleView.h */,
|
||||
048909F32EC0AAAA00FABA60 /* KBCategoryTitleView.m */,
|
||||
04890A002EC0BBBB00FABA60 /* KBCategoryTitleImageCell.h */,
|
||||
04890A012EC0BBBB00FABA60 /* KBCategoryTitleImageCell.m */,
|
||||
04890A022EC0BBBB00FABA60 /* KBCategoryTitleImageView.h */,
|
||||
04890A032EC0BBBB00FABA60 /* KBCategoryTitleImageView.m */,
|
||||
04890A002EC0BBBB00FABA60 /* KBCategoryTitleImageCell.h */,
|
||||
04890A012EC0BBBB00FABA60 /* KBCategoryTitleImageCell.m */,
|
||||
04890A022EC0BBBB00FABA60 /* KBCategoryTitleImageView.h */,
|
||||
04890A032EC0BBBB00FABA60 /* KBCategoryTitleImageView.m */,
|
||||
);
|
||||
path = V;
|
||||
sourceTree = "<group>";
|
||||
@@ -883,6 +886,8 @@
|
||||
04FC95D42EB1EA16007BD342 /* BaseCell.m */,
|
||||
04FC95D52EB1EA16007BD342 /* BaseTableView.h */,
|
||||
04FC95D62EB1EA16007BD342 /* BaseTableView.m */,
|
||||
048908FC2EC0CC2400FABA60 /* UIScrollView+KBEmptyView.h */,
|
||||
048908FD2EC0CC2400FABA60 /* UIScrollView+KBEmptyView.m */,
|
||||
);
|
||||
path = V;
|
||||
sourceTree = "<group>";
|
||||
@@ -1249,10 +1254,14 @@
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-keyBoard/Pods-keyBoard-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-keyBoard/Pods-keyBoard-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-keyBoard/Pods-keyBoard-frameworks.sh\"\n";
|
||||
@@ -1316,8 +1325,8 @@
|
||||
files = (
|
||||
048909F62EC0AAAA00FABA60 /* KBCategoryTitleCell.m in Sources */,
|
||||
048909F72EC0AAAA00FABA60 /* KBCategoryTitleView.m in Sources */,
|
||||
04890A042EC0BBBB00FABA60 /* KBCategoryTitleImageCell.m in Sources */,
|
||||
04890A052EC0BBBB00FABA60 /* KBCategoryTitleImageView.m in Sources */,
|
||||
04890A042EC0BBBB00FABA60 /* KBCategoryTitleImageCell.m in Sources */,
|
||||
04890A052EC0BBBB00FABA60 /* KBCategoryTitleImageView.m in Sources */,
|
||||
04FC95E92EB23B67007BD342 /* KBNetworkManager.m in Sources */,
|
||||
04FC95D22EB1E7AE007BD342 /* MyVC.m in Sources */,
|
||||
047C65582EBCC06D0035E841 /* HomeRankCardCell.m in Sources */,
|
||||
@@ -1357,6 +1366,7 @@
|
||||
04FC97062EB30A00007BD342 /* KBGuideUserCell.m in Sources */,
|
||||
04FC97092EB31B14007BD342 /* KBHUD.m in Sources */,
|
||||
04FC970E2EB334F8007BD342 /* UIImageView+KBWebImage.m in Sources */,
|
||||
048908FE2EC0CC2400FABA60 /* UIScrollView+KBEmptyView.m in Sources */,
|
||||
04FC970F2EB334F8007BD342 /* KBWebImageManager.m in Sources */,
|
||||
04FC95CF2EB1E7A1007BD342 /* HomeVC.m in Sources */,
|
||||
A1B2D7022EB8C00100000001 /* KBLangTestVC.m in Sources */,
|
||||
|
||||
@@ -40,6 +40,22 @@ typedef void(^KBEmptyAction)(void);
|
||||
/// 触发刷新空数据视图(若集成了 DZNEmptyDataSet 则调用其 reloadEmptyDataSet)
|
||||
- (void)kb_reloadEmptyDataSet;
|
||||
|
||||
/// 使用 LYEmptyView 在表格页快速挂载一套统一样式的空态视图(与 DZNEmptyDataSet 二选一)
|
||||
/// 注意:调用该方法会自动关闭本类内置的 DZNEmptyDataSet(useEmptyDataSet = NO),避免冲突。
|
||||
/// - Parameters:
|
||||
/// - image: 占位图(可空)
|
||||
/// - title: 标题(默认“暂无数据”)
|
||||
/// - detail: 描述(可空)
|
||||
/// - buttonTitle: 按钮标题(可空,传空则不展示按钮)
|
||||
/// - tapHandler: 点击空白区域回调(可空)
|
||||
/// - buttonHandler: 按钮点击回调(可空)
|
||||
- (void)kb_makeDefaultEmptyViewWithImage:(nullable UIImage *)image
|
||||
title:(nullable NSString *)title
|
||||
detail:(nullable NSString *)detail
|
||||
buttonTitle:(nullable NSString *)buttonTitle
|
||||
tapHandler:(nullable KBEmptyAction)tapHandler
|
||||
buttonHandler:(nullable KBEmptyAction)buttonHandler;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@@ -13,6 +13,15 @@
|
||||
#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>
|
||||
@@ -127,4 +136,66 @@
|
||||
|
||||
#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 ?: @"暂无数据";
|
||||
|
||||
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
|
||||
|
||||
40
keyBoard/Class/Base/V/UIScrollView+KBEmptyView.h
Normal file
40
keyBoard/Class/Base/V/UIScrollView+KBEmptyView.h
Normal file
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// UIScrollView+KBEmptyView.h
|
||||
// keyBoard
|
||||
//
|
||||
// 统一封装基于 LYEmptyView 的空态视图挂载方法,适用于 UITableView/UICollectionView。
|
||||
// 注意:仅在对应页面已通过 CocoaPods 集成 LYEmptyView 时生效。
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef void(^KBEmptyAction)(void);
|
||||
|
||||
@interface UIScrollView (KBEmptyView)
|
||||
|
||||
/// 快速挂载一套统一样式的空态视图(LYEmptyView)
|
||||
/// - Parameters:
|
||||
/// - image: 占位图(可空)
|
||||
/// - title: 标题(默认“暂无数据”)
|
||||
/// - detail: 描述(可空)
|
||||
/// - buttonTitle: 按钮标题(可空,传空则不显示按钮)
|
||||
/// - tapHandler: 点击空白区域回调(可空)
|
||||
/// - buttonHandler: 按钮点击回调(可空)
|
||||
- (void)kb_makeDefaultEmptyViewWithImage:(nullable UIImage *)image
|
||||
title:(nullable NSString *)title
|
||||
detail:(nullable NSString *)detail
|
||||
buttonTitle:(nullable NSString *)buttonTitle
|
||||
tapHandler:(nullable KBEmptyAction)tapHandler
|
||||
buttonHandler:(nullable KBEmptyAction)buttonHandler;
|
||||
|
||||
/// 便捷加载态控制:关闭自动显隐后,配合网络请求手动控制显示/隐藏
|
||||
- (void)kb_setLYAutoShowEnabled:(BOOL)enabled; // YES=自动显隐;NO=手动
|
||||
- (void)kb_beginLoadingForEmpty; // 请求开始:临时隐藏 empty
|
||||
- (void)kb_endLoadingForEmpty; // 请求结束:根据数据源显示/隐藏(需确保先 reloadData)
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
90
keyBoard/Class/Base/V/UIScrollView+KBEmptyView.m
Normal file
90
keyBoard/Class/Base/V/UIScrollView+KBEmptyView.m
Normal file
@@ -0,0 +1,90 @@
|
||||
//
|
||||
// UIScrollView+KBEmptyView.m
|
||||
// keyBoard
|
||||
//
|
||||
|
||||
#import "UIScrollView+KBEmptyView.h"
|
||||
|
||||
#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
|
||||
|
||||
@implementation UIScrollView (KBEmptyView)
|
||||
|
||||
- (void)kb_makeDefaultEmptyViewWithImage:(UIImage *)image
|
||||
title:(NSString *)title
|
||||
detail:(NSString *)detail
|
||||
buttonTitle:(NSString *)buttonTitle
|
||||
tapHandler:(KBEmptyAction)tapHandler
|
||||
buttonHandler:(KBEmptyAction)buttonHandler {
|
||||
#if KB_HAS_LY
|
||||
NSString *t = title ?: @"暂无数据";
|
||||
LYEmptyView *ev = nil;
|
||||
|
||||
if (buttonTitle.length > 0) {
|
||||
__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;
|
||||
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;
|
||||
|
||||
// 默认关闭自动显隐,交给调用方用 begin/end 控制
|
||||
ev.autoShowEmptyView = NO;
|
||||
|
||||
self.ly_emptyView = ev;
|
||||
#else
|
||||
(void)image; (void)title; (void)detail; (void)buttonTitle; (void)tapHandler; (void)buttonHandler;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)kb_setLYAutoShowEnabled:(BOOL)enabled {
|
||||
#if KB_HAS_LY
|
||||
self.ly_emptyView.autoShowEmptyView = enabled;
|
||||
#else
|
||||
(void)enabled;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)kb_beginLoadingForEmpty {
|
||||
#if KB_HAS_LY
|
||||
[self ly_startLoading];
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)kb_endLoadingForEmpty {
|
||||
#if KB_HAS_LY
|
||||
[self ly_endLoading];
|
||||
#endif
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,14 +1,6 @@
|
||||
//
|
||||
// KBSkinDetailVC.m
|
||||
// keyBoard
|
||||
//
|
||||
// 皮肤详情页(UICollectionView 实现)
|
||||
// 结构:
|
||||
// - Section0:顶部大卡片(上图,下方左右两段文案)
|
||||
// - Section1:标签容器 cell(内部再嵌套一个 collectionView 以展示 Cute/Fresh 等标签)
|
||||
// - Section2:区块标题 cell(例如 “Recommended Skin”)
|
||||
// - Section3:推荐皮肤 2 列网格(使用已有 KBSkinCardCell)
|
||||
//
|
||||
|
||||
#import "KBSkinDetailVC.h"
|
||||
#import <Masonry/Masonry.h>
|
||||
|
||||
@@ -2,17 +2,12 @@
|
||||
// MySkinVC.m
|
||||
// keyBoard
|
||||
//
|
||||
// 我的皮肤列表页(支持编辑多选删除)。
|
||||
// 需求要点:
|
||||
// - 顶部右侧 Editor/Cancel 切换
|
||||
// - CollectionView Masonry 约束 + 懒加载控件
|
||||
// - 自定义 cell,编辑态显示左上角选择圆点,支持多选
|
||||
// - 底部 bottomView 展示已选择数量与删除按钮,数量>0 时 Delete 变为 #02BEAC 可点
|
||||
//
|
||||
|
||||
#import "MySkinVC.h"
|
||||
#import <Masonry/Masonry.h>
|
||||
#import "UIColor+Extension.h"
|
||||
#import <MJRefresh/MJRefresh.h>
|
||||
#import "UIScrollView+KBEmptyView.h" // 统一空态封装(LYEmptyView)
|
||||
|
||||
#import "MySkinCell.h"
|
||||
|
||||
@@ -25,6 +20,7 @@ static NSString * const kMySkinCellId = @"kMySkinCellId";
|
||||
@property (nonatomic, strong) UIButton *deleteButton; // 删除
|
||||
|
||||
@property (nonatomic, strong) NSMutableArray<NSDictionary *> *data; // 简单数据源
|
||||
@property (nonatomic, assign) NSInteger loadCount; // 刷新计数(用于演示空/有数据切换)
|
||||
@property (nonatomic, assign, getter=isEditingMode) BOOL editingMode; // 是否编辑态
|
||||
@end
|
||||
|
||||
@@ -39,13 +35,8 @@ static NSString * const kMySkinCellId = @"kMySkinCellId";
|
||||
// 右上角 Editor/Cancel
|
||||
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Editor" style:UIBarButtonItemStylePlain target:self action:@selector(onToggleEdit)];
|
||||
|
||||
// 数据源(演示用)
|
||||
self.data = [@[
|
||||
@{ @"title": @"Dopamine" },
|
||||
@{ @"title": @"Dopamine" },
|
||||
@{ @"title": @"Dopamine" },
|
||||
@{ @"title": @"Dopamine" },
|
||||
] mutableCopy];
|
||||
// 数据源初始化为空(演示空态 + 下拉刷新)
|
||||
self.data = [NSMutableArray array];
|
||||
|
||||
// 视图
|
||||
[self.view addSubview:self.collectionView];
|
||||
@@ -63,10 +54,50 @@ static NSString * const kMySkinCellId = @"kMySkinCellId";
|
||||
make.height.mas_equalTo(64);
|
||||
}];
|
||||
|
||||
// 空态视图(LYEmptyView)统一样式 + 重试按钮
|
||||
__weak typeof(self) weakSelf = self;
|
||||
[self.collectionView kb_makeDefaultEmptyViewWithImage:nil
|
||||
title:@"暂无皮肤"
|
||||
detail:@"下拉刷新试试"
|
||||
buttonTitle:@"重试"
|
||||
tapHandler:nil
|
||||
buttonHandler:^{ [weakSelf.collectionView.mj_header beginRefreshing]; }];
|
||||
[self.collectionView kb_setLYAutoShowEnabled:NO]; // 采用手动控制显隐
|
||||
|
||||
// 立即按当前数据源状态显示一次空态(首屏就应展示空视图)
|
||||
[self.collectionView kb_endLoadingForEmpty];
|
||||
|
||||
// 下拉刷新(演示网络加载 + 空态切换)
|
||||
self.collectionView.mj_header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(fetchData)];
|
||||
|
||||
// 首次进入自动刷新
|
||||
[self.collectionView.mj_header beginRefreshing];
|
||||
|
||||
// 初始:非编辑态,隐藏底部
|
||||
self.bottomView.hidden = YES;
|
||||
}
|
||||
|
||||
#pragma mark - Data
|
||||
|
||||
- (void)fetchData {
|
||||
// 模拟网络延迟 1.0s
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
self.loadCount += 1;
|
||||
|
||||
// 交替返回:奇数次空数据,偶数次有数据(演示空态/非空切换)
|
||||
[self.data removeAllObjects];
|
||||
if (self.loadCount % 2 == 0) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
[self.data addObject:@{ @"title": @"Dopamine" }];
|
||||
}
|
||||
}
|
||||
|
||||
[self.collectionView reloadData];
|
||||
[self.collectionView kb_endLoadingForEmpty]; // 根据数据源显示/隐藏 emptyView
|
||||
[self.collectionView.mj_header endRefreshing];
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark - Actions
|
||||
|
||||
- (void)onToggleEdit {
|
||||
@@ -112,6 +143,8 @@ static NSString * const kMySkinCellId = @"kMySkinCellId";
|
||||
[self.collectionView deleteItemsAtIndexPaths:selected];
|
||||
} completion:^(BOOL finished) {
|
||||
[self updateBottomUI];
|
||||
// 根据当前数据源显隐空视图(删除到 0 条时应显示空态)
|
||||
[self.collectionView kb_endLoadingForEmpty];
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
@@ -29,10 +29,10 @@
|
||||
}
|
||||
|
||||
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
|
||||
// MySkinVC *vc = [[MySkinVC alloc] init];
|
||||
KBSkinDetailVC *vc = [[KBSkinDetailVC alloc] init];
|
||||
MySkinVC *vc = [[MySkinVC alloc] init];
|
||||
// KBSkinDetailVC *vc = [[KBSkinDetailVC alloc] init];
|
||||
|
||||
// [self.navigationController pushViewController:vc animated:true];
|
||||
[self.navigationController pushViewController:vc animated:true];
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#import <Masonry/Masonry.h>
|
||||
#import "KBSkinCardCell.h"
|
||||
|
||||
/// 商城列表:使用 UICollectionView,两列网格,复用 KBSkinCardCell
|
||||
@interface KBShopItemVC ()<UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
|
||||
@property (nonatomic, copy) void(^scrollCallback)(UIScrollView *scrollView);
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user