diff --git a/keyBoard.xcodeproj/project.pbxproj b/keyBoard.xcodeproj/project.pbxproj index f2b0638..748fc23 100644 --- a/keyBoard.xcodeproj/project.pbxproj +++ b/keyBoard.xcodeproj/project.pbxproj @@ -68,6 +68,8 @@ 048908E92EBF843000FABA60 /* KBSkinDetailHeaderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 048908E82EBF843000FABA60 /* KBSkinDetailHeaderCell.m */; }; 048908EC2EBF849300FABA60 /* KBSkinTagsContainerCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 048908EB2EBF849300FABA60 /* KBSkinTagsContainerCell.m */; }; 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 */; }; 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 */; }; @@ -242,6 +244,10 @@ 048908EB2EBF849300FABA60 /* KBSkinTagsContainerCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSkinTagsContainerCell.m; sourceTree = ""; }; 048908ED2EBF861800FABA60 /* KBSkinSectionTitleCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBSkinSectionTitleCell.h; sourceTree = ""; }; 048908EE2EBF861800FABA60 /* KBSkinSectionTitleCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSkinSectionTitleCell.m; sourceTree = ""; }; + 048908F02EC047FD00FABA60 /* KBShopHeadView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBShopHeadView.h; sourceTree = ""; }; + 048908F12EC047FD00FABA60 /* KBShopHeadView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBShopHeadView.m; sourceTree = ""; }; + 048908F32EC0496400FABA60 /* KBShopItemVC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBShopItemVC.h; sourceTree = ""; }; + 048908F42EC0496400FABA60 /* KBShopItemVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBShopItemVC.m; sourceTree = ""; }; 04A9A67D2EB9E1690023B8F4 /* KBResponderUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBResponderUtils.h; sourceTree = ""; }; 04A9FE102EB4D0D20020DB6D /* KBFullAccessManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBFullAccessManager.h; sourceTree = ""; }; 04A9FE112EB4D0D20020DB6D /* KBFullAccessManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBFullAccessManager.m; sourceTree = ""; }; @@ -482,6 +488,8 @@ 047C654B2EBCBA880035E841 /* V */ = { isa = PBXGroup; children = ( + 048908F02EC047FD00FABA60 /* KBShopHeadView.h */, + 048908F12EC047FD00FABA60 /* KBShopHeadView.m */, ); path = V; sourceTree = ""; @@ -491,6 +499,8 @@ children = ( 047C654E2EBCBA9E0035E841 /* KBShopVC.h */, 047C654F2EBCBA9E0035E841 /* KBShopVC.m */, + 048908F32EC0496400FABA60 /* KBShopItemVC.h */, + 048908F42EC0496400FABA60 /* KBShopItemVC.m */, ); path = VC; sourceTree = ""; @@ -1317,6 +1327,7 @@ 04FC95DD2EB202A3007BD342 /* KBGuideVC.m in Sources */, 04FC95E52EB220B5007BD342 /* UIColor+Extension.m in Sources */, 048908E02EBF73DC00FABA60 /* MySkinVC.m in Sources */, + 048908F22EC047FD00FABA60 /* KBShopHeadView.m in Sources */, 048908EC2EBF849300FABA60 /* KBSkinTagsContainerCell.m in Sources */, 0477BDF02EBB76E30055D639 /* HomeSheetVC.m in Sources */, 048908E62EBF841B00FABA60 /* KBSkinDetailTagCell.m in Sources */, @@ -1343,6 +1354,7 @@ A1B2E1012EBC7AAA00000001 /* KBTopThreeView.m in Sources */, A1B2E1022EBC7AAA00000001 /* HomeHotCell.m in Sources */, 0459D1B72EBA287900F2D189 /* KBSkinManager.m in Sources */, + 048908F52EC0496400FABA60 /* KBShopItemVC.m in Sources */, 04FC95F42EB339C1007BD342 /* AppleSignInManager.m in Sources */, 04C6EAC12EAF86530089C901 /* ViewController.m in Sources */, A1B2C4002EB4A0A100000004 /* KBAuthManager.m in Sources */, diff --git a/keyBoard/Class/Me/VC/MyVC.m b/keyBoard/Class/Me/VC/MyVC.m index 44fba6c..a422724 100644 --- a/keyBoard/Class/Me/VC/MyVC.m +++ b/keyBoard/Class/Me/VC/MyVC.m @@ -32,7 +32,7 @@ // MySkinVC *vc = [[MySkinVC alloc] init]; KBSkinDetailVC *vc = [[KBSkinDetailVC alloc] init]; - [self.navigationController pushViewController:vc animated:true]; +// [self.navigationController pushViewController:vc animated:true]; } /* diff --git a/keyBoard/Class/Shop/V/KBShopHeadView.h b/keyBoard/Class/Shop/V/KBShopHeadView.h new file mode 100644 index 0000000..d6d1276 --- /dev/null +++ b/keyBoard/Class/Shop/V/KBShopHeadView.h @@ -0,0 +1,16 @@ +// +// KBShopHeadView.h +// keyBoard +// +// Created by Mac on 2025/11/9. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface KBShopHeadView : UIView + +@end + +NS_ASSUME_NONNULL_END diff --git a/keyBoard/Class/Shop/V/KBShopHeadView.m b/keyBoard/Class/Shop/V/KBShopHeadView.m new file mode 100644 index 0000000..95e0909 --- /dev/null +++ b/keyBoard/Class/Shop/V/KBShopHeadView.m @@ -0,0 +1,20 @@ +// +// KBShopHeadView.m +// keyBoard +// +// Created by Mac on 2025/11/9. +// + +#import "KBShopHeadView.h" + +@implementation KBShopHeadView + +/* +// Only override drawRect: if you perform custom drawing. +// An empty implementation adversely affects performance during animation. +- (void)drawRect:(CGRect)rect { + // Drawing code +} +*/ + +@end diff --git a/keyBoard/Class/Shop/VC/KBShopItemVC.h b/keyBoard/Class/Shop/VC/KBShopItemVC.h new file mode 100644 index 0000000..a32b6b2 --- /dev/null +++ b/keyBoard/Class/Shop/VC/KBShopItemVC.h @@ -0,0 +1,21 @@ +// +// KBShopItemVC.h +// keyBoard +// +// Created by Mac on 2025/11/9. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface KBShopItemVC : UIViewController +@property (nonatomic, strong) UITableView *tableView; +@property (nonatomic, strong) NSMutableArray *dataSource; +@property (nonatomic, assign) BOOL isNeedFooter; +@property (nonatomic, assign) BOOL isNeedHeader; +@property (nonatomic, assign) BOOL isHeaderRefreshed; //默认为YES +@end + +NS_ASSUME_NONNULL_END diff --git a/keyBoard/Class/Shop/VC/KBShopItemVC.m b/keyBoard/Class/Shop/VC/KBShopItemVC.m new file mode 100644 index 0000000..2cd9d90 --- /dev/null +++ b/keyBoard/Class/Shop/VC/KBShopItemVC.m @@ -0,0 +1,141 @@ +// +// KBShopItemVC.m +// keyBoard +// +// Created by Mac on 2025/11/9. +// + +#import "KBShopItemVC.h" +#import +@interface KBShopItemVC () + +@property (nonatomic, copy) void(^scrollCallback)(UIScrollView *scrollView); + +@end + +@implementation KBShopItemVC + +- (void)viewDidLoad { + [super viewDidLoad]; + + _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; + self.tableView.backgroundColor = [UIColor whiteColor]; + self.tableView.tableFooterView = [UIView new]; + self.tableView.dataSource = self; + self.tableView.delegate = self; + [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"]; + + [self.view addSubview:self.tableView]; + + __weak typeof(self)weakSelf = self; + if (self.isNeedHeader) { + self.tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{ + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [weakSelf.tableView.mj_header endRefreshing]; + }); + }]; + } + if (self.isNeedFooter) { + self.tableView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{ + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [weakSelf.dataSource addObject:@"加载更多成功"]; + [weakSelf.tableView reloadData]; + [weakSelf.tableView.mj_footer endRefreshing]; + }); + }]; + if (@available(iOS 11.0, *)) { + self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; + } + } else { + //列表的contentInsetAdjustmentBehavior失效,需要自己设置底部inset +// self.tableView.contentInset = UIEdgeInsetsMake(0, 0, UIApplication.sharedApplication.keyWindow.jx_layoutInsets.bottom, 0); + } + + [self beginFirstRefresh]; +} + +- (void)viewDidLayoutSubviews { + [super viewDidLayoutSubviews]; + + self.tableView.frame = self.view.bounds; +} + +- (void)beginFirstRefresh { + if (!self.isHeaderRefreshed) { + [self beginRefreshImmediately]; + } +} + +- (void)beginRefreshImmediately { + if (self.isNeedHeader) { + [self.tableView.mj_header beginRefreshing]; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + self.isHeaderRefreshed = YES; + [self.tableView reloadData]; + [self.tableView.mj_header endRefreshing]; + }); + }else { + self.isHeaderRefreshed = YES; + [self.tableView reloadData]; + } +} + +#pragma mark - UITableViewDataSource, UITableViewDelegate + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + if (!self.isHeaderRefreshed) { + return 0; + } + return self.dataSource.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath]; + cell.textLabel.text = self.dataSource[indexPath.row]; + return cell; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { + return 50; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { +// DetailViewController *detailVC = [[DetailViewController alloc] init]; +// detailVC.infoString = self.dataSource[indexPath.row]; +// [self.navigationController pushViewController:detailVC animated:YES]; +} + +- (void)scrollViewDidScroll:(UIScrollView *)scrollView { + !self.scrollCallback ?: self.scrollCallback(scrollView); +} + +#pragma mark - JXPagingViewListViewDelegate + +- (UIView *)listView { + return self.view; +} + +- (UIScrollView *)listScrollView { + return self.tableView; +} + +- (void)listViewDidScrollCallback:(void (^)(UIScrollView *))callback { + self.scrollCallback = callback; +} + +- (void)listWillAppear { + NSLog(@"%@:%@", self.title, NSStringFromSelector(_cmd)); +} + +- (void)listDidAppear { + NSLog(@"%@:%@", self.title, NSStringFromSelector(_cmd)); +} + +- (void)listWillDisappear { + NSLog(@"%@:%@", self.title, NSStringFromSelector(_cmd)); +} + +- (void)listDidDisappear { + NSLog(@"%@:%@", self.title, NSStringFromSelector(_cmd)); +} +@end diff --git a/keyBoard/Class/Shop/VC/KBShopVC.m b/keyBoard/Class/Shop/VC/KBShopVC.m index cacd540..f1a4e77 100644 --- a/keyBoard/Class/Shop/VC/KBShopVC.m +++ b/keyBoard/Class/Shop/VC/KBShopVC.m @@ -6,26 +6,176 @@ // #import "KBShopVC.h" +#import "JXPagerView.h" +#import "KBShopHeadView.h" +#import +#import +#import +#import "KBShopItemVC.h" -@interface KBShopVC () +static const CGFloat JXTableHeaderViewHeight = (323); +static const CGFloat JXheightForHeaderInSection = 50; +@interface KBShopVC () +@property (nonatomic, strong) UIView *naviBGView; + +@property (nonatomic, strong) JXPagerView *pagerView; +@property (nonatomic, strong) KBShopHeadView *userHeaderView; +@property (nonatomic, assign) BOOL isNeedFooter; +@property (nonatomic, assign) BOOL isNeedHeader; +- (JXPagerView *)preferredPagingView; + +@property (nonatomic, strong) JXCategoryTitleView *categoryView; +@property (nonatomic, strong) NSArray *titles; @end @implementation KBShopVC - (void)viewDidLoad { [super viewDidLoad]; - // Do any additional setup after loading the view. + + self.automaticallyAdjustsScrollViewInsets = NO; + self.view.backgroundColor = [UIColor whiteColor]; + self.navigationController.navigationBar.translucent = false; + self.edgesForExtendedLayout = UIRectEdgeNone; + _titles = @[@"能力", @"爱好", @"队友",@"能力2", @"爱好2", @"队友2"]; + + _userHeaderView = [[KBShopHeadView alloc] init]; + + _categoryView = [[JXCategoryTitleView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, JXheightForHeaderInSection)]; + self.categoryView.titles = self.titles; + self.categoryView.backgroundColor = [UIColor whiteColor]; + self.categoryView.delegate = self; + self.categoryView.titleSelectedColor = [UIColor colorWithHex:0x1B1F1A]; + self.categoryView.titleColor = [UIColor colorWithHex:0x9F9F9F]; + self.categoryView.titleColorGradientEnabled = YES; + self.categoryView.titleLabelZoomEnabled = YES; + self.categoryView.contentScrollViewClickTransitionAnimationEnabled = NO; + + JXCategoryIndicatorBackgroundView *backgroundView = [[JXCategoryIndicatorBackgroundView alloc] init]; + backgroundView.indicatorHeight = 20; + backgroundView.indicatorCornerRadius = JXCategoryViewAutomaticDimension; + backgroundView.layer.borderColor = [UIColor colorWithHex:0x02BEAC].CGColor; + backgroundView.layer.borderWidth = 1; + self.categoryView.indicators = @[backgroundView]; + + _pagerView = [self preferredPagingView]; + self.pagerView.mainTableView.gestureDelegate = self; + [self.view addSubview:self.pagerView]; + + self.categoryView.listContainer = (id)self.pagerView.listContainerView; + + //导航栏隐藏的情况,处理扣边返回,下面的代码要加上 +// [self.pagerView.listContainerView.scrollView.panGestureRecognizer requireGestureRecognizerToFail:self.navigationController.interactivePopGestureRecognizer]; +// [self.pagerView.mainTableView.panGestureRecognizer requireGestureRecognizerToFail:self.navigationController.interactivePopGestureRecognizer]; + + __weak typeof(self)weakSelf = self; + self.pagerView.mainTableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{ + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + self.categoryView.titles = @[@"高级能力", @"高级爱好", @"高级队友"]; + self.categoryView.defaultSelectedIndex = 0; + [self.categoryView reloadData]; + [self.pagerView reloadData]; + [weakSelf.pagerView.mainTableView.mj_header endRefreshing]; + }); + }]; + + self.pagerView.pinSectionHeaderVerticalOffset = KB_NAV_TOTAL_HEIGHT; + + self.naviBGView = [[UIView alloc] init]; + self.naviBGView.alpha = 0; + self.naviBGView.backgroundColor = [UIColor whiteColor]; + self.naviBGView.frame = CGRectMake(0, 0, KB_SCREEN_WIDTH, KB_NAV_TOTAL_HEIGHT); + [self.view addSubview:self.naviBGView]; + UILabel *naviTitleLabel = [[UILabel alloc] init]; + naviTitleLabel.text = @"导航栏隐藏"; + naviTitleLabel.textAlignment = NSTextAlignmentCenter; + naviTitleLabel.frame = CGRectMake(0, KB_STATUSBAR_HEIGHT, self.view.bounds.size.width, 44); + [self.naviBGView addSubview:naviTitleLabel]; } -/* -#pragma mark - Navigation +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; -// In a storyboard-based application, you will often want to do a little preparation before navigation -- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { - // Get the new view controller using [segue destinationViewController]. - // Pass the selected object to the new view controller. + [self.navigationController setNavigationBarHidden:YES animated:YES]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + + [self.navigationController setNavigationBarHidden:NO animated:NO]; +} + +- (JXPagerView *)preferredPagingView { + return [[JXPagerView alloc] initWithDelegate:self]; +} + +- (void)viewDidLayoutSubviews { + [super viewDidLayoutSubviews]; + + self.pagerView.frame = self.view.bounds; +} + +#pragma mark - JXPagerViewDelegate + +- (UIView *)tableHeaderViewInPagerView:(JXPagerView *)pagerView { + return self.userHeaderView; +} + +- (NSUInteger)tableHeaderViewHeightInPagerView:(JXPagerView *)pagerView { + return KBFit(JXTableHeaderViewHeight); +} + +- (NSUInteger)heightForPinSectionHeaderInPagerView:(JXPagerView *)pagerView { + return JXheightForHeaderInSection; +} + +- (UIView *)viewForPinSectionHeaderInPagerView:(JXPagerView *)pagerView { + return self.categoryView; +} + +- (NSInteger)numberOfListsInPagerView:(JXPagerView *)pagerView { + //和categoryView的item数量一致 + return self.categoryView.titles.count; +} + +- (id)pagerView:(JXPagerView *)pagerView initListAtIndex:(NSInteger)index { + KBShopItemVC *list = [[KBShopItemVC alloc] init]; + list.title = self.titles[index]; + list.isNeedHeader = self.isNeedHeader; + list.isNeedFooter = self.isNeedFooter; + if (index == 0) { + list.dataSource = @[@"橡胶火箭", @"橡胶火箭炮", @"橡胶机关枪", @"橡胶子弹", @"橡胶攻城炮", @"橡胶象枪", @"橡胶象枪乱打", @"橡胶灰熊铳", @"橡胶雷神象枪", @"橡胶猿王枪", @"橡胶犀·榴弹炮", @"橡胶大蛇炮", @"橡胶火箭", @"橡胶火箭炮", @"橡胶机关枪", @"橡胶子弹", @"橡胶攻城炮", @"橡胶象枪", @"橡胶象枪乱打", @"橡胶灰熊铳", @"橡胶雷神象枪", @"橡胶猿王枪", @"橡胶犀·榴弹炮", @"橡胶大蛇炮"].mutableCopy; + }else if (index == 1) { + list.dataSource = @[@"吃烤肉", @"吃鸡腿肉", @"吃牛肉", @"各种肉"].mutableCopy; + }else { + list.dataSource = @[@"【剑士】罗罗诺亚·索隆", @"【航海士】娜美", @"【狙击手】乌索普", @"【厨师】香吉士", @"【船医】托尼托尼·乔巴", @"【船匠】 弗兰奇", @"【音乐家】布鲁克", @"【考古学家】妮可·罗宾"].mutableCopy; + } + return list; +} + +#pragma mark - JXCategoryViewDelegate + +- (void)categoryView:(JXCategoryBaseView *)categoryView didSelectedItemAtIndex:(NSInteger)index { + self.navigationController.interactivePopGestureRecognizer.enabled = (index == 0); +} + +#pragma mark - JXPagerMainTableViewGestureDelegate + +- (BOOL)mainTableViewGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { + //禁止categoryView左右滑动的时候,上下和左右都可以滚动 + if (otherGestureRecognizer == self.categoryView.collectionView.panGestureRecognizer) { + return NO; + } + return [gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] && [otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]; +} + + +- (void)pagerView:(JXPagerView *)pagerView mainTableViewDidScroll:(UIScrollView *)scrollView { + CGFloat thresholdDistance = JXTableHeaderViewHeight; + CGFloat percent = scrollView.contentOffset.y/thresholdDistance; + percent = MAX(0, MIN(1, percent)); + self.naviBGView.alpha = percent; } -*/ @end