- XJHomeWatchDataView 新增 heightChangeBlock,无数据/未登录高度 104,有数据高度 200 - XJHomePageV2HeardView 初始高度改为 104,绑定回调动态更新约束带动画 - BindWatchPopView 姓名工号同行布局,工号固定右侧优先显示,姓名占满剩余空间
723 lines
27 KiB
Objective-C
723 lines
27 KiB
Objective-C
//
|
||
// XJHomeWatchDataView.m
|
||
// XinjiangProject
|
||
//
|
||
// Created by Apple on 2026/3/2.
|
||
//
|
||
|
||
#import "XJHomeWatchDataView.h"
|
||
#import "XJHomeWatchCollectionViewCell.h"
|
||
#import <Masonry/Masonry.h>
|
||
|
||
// ── 布局常量 ──────────────────────────────────────────────
|
||
static CGFloat const kHeaderHeight = 92.0; // 头部保留高度(外部自行填充)
|
||
static CGFloat const kTabScrollH = 52.0; // Tab ScrollView 高度
|
||
static CGFloat const kButtonH = 30.0; // 按钮高度
|
||
static CGFloat const kButtonPadX = 10.0; // 按钮左右内边距
|
||
static CGFloat const kButtonGap = 10.0; // 按钮间距
|
||
|
||
|
||
// ── Private ───────────────────────────────────────────────
|
||
@interface XJHomeWatchDataView ()<UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
|
||
|
||
@property (nonatomic, strong) YYLabel *watchNumberLabel; //
|
||
|
||
|
||
//@property (nonatomic, strong) UIScrollView *tabScrollView;
|
||
@property (nonatomic, strong) UIView *tabContentView;
|
||
@property (nonatomic, strong) NSMutableArray<UIButton *> *tabButtons;
|
||
@property (nonatomic, strong) UICollectionView *collectionView;
|
||
@property (nonatomic, strong) UILabel *emptyLabel; // 无数据占位
|
||
@property (nonatomic, strong) UIView *emptyView; // 空状态占位整体容器
|
||
@property (nonatomic, strong) UIView *devView; // 紧急开发中占位
|
||
@property (nonatomic, assign) NSInteger selectedIndex; // 当前选中的 Tab 下标
|
||
@property (nonatomic, assign) NSInteger carouselPage; // collectionView 当前轮播页码(与 Tab 无关)
|
||
@property (nonatomic, strong) NSTimer *autoScrollTimer; // 轮播定时器
|
||
|
||
@property (nonatomic, strong) UIView *
|
||
timeView;
|
||
|
||
@property (nonatomic, strong) UIButton *
|
||
preBtn;
|
||
|
||
|
||
@property (nonatomic, strong) UIButton *
|
||
nextBtn;
|
||
|
||
@property (nonatomic, strong) UILabel *
|
||
weekLabel;
|
||
|
||
@property (nonatomic, strong) NSDate * currentDayDate; // 当前选中的日
|
||
|
||
@end
|
||
|
||
// ─────────────────────────────────────────────────────────
|
||
@implementation XJHomeWatchDataView
|
||
|
||
#pragma mark - Init
|
||
|
||
- (instancetype)initWithFrame:(CGRect)frame {
|
||
self = [super initWithFrame:frame];
|
||
self.backgroundColor = KWhiteColor;
|
||
self.layer.cornerRadius = 12;
|
||
self.layer.masksToBounds = true;
|
||
if (self) [self p_setupUI];
|
||
return self;
|
||
}
|
||
|
||
#pragma mark - UI Setup
|
||
|
||
- (void)p_setupUI {
|
||
_selectedIndex = 0;
|
||
_tabButtons = [NSMutableArray array];
|
||
self.currentDayDate = [NSDate date];
|
||
UIImageView * heaedImg = [[UIImageView alloc] init];
|
||
heaedImg.image = [UIImage imageNamed:@"heaedTitleBackImg"];
|
||
heaedImg.userInteractionEnabled = true;
|
||
[self addSubview:heaedImg];
|
||
|
||
[heaedImg mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.left.right.top.mas_offset(0);
|
||
make.height.mas_offset(40);
|
||
}];
|
||
|
||
|
||
UILabel * todayLabel = [[UILabel alloc] init];
|
||
|
||
todayLabel.text = @"健康监测";
|
||
|
||
todayLabel.textAlignment = NSTextAlignmentLeft;
|
||
|
||
todayLabel.textColor = CFontColor1;
|
||
|
||
todayLabel.font = BOLDSYSTEMFONT(16);
|
||
|
||
[heaedImg addSubview:todayLabel];
|
||
|
||
[todayLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.left.mas_offset(13);
|
||
make.top.bottom.mas_offset(0);
|
||
}];
|
||
|
||
|
||
UIButton * moreBtn = [[UIButton alloc] init];
|
||
[moreBtn setImage:[UIImage imageNamed:@"wacthRightAccow"] forState:UIControlStateNormal];
|
||
[moreBtn addTarget:self action:@selector(moreClick) forControlEvents:UIControlEventTouchUpInside];
|
||
[heaedImg addSubview:moreBtn];
|
||
[moreBtn mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.right.mas_offset(-8);
|
||
make.centerY.mas_equalTo(heaedImg);
|
||
make.width.height.mas_offset(30);
|
||
}];
|
||
|
||
// YYLabel * morelabel = [[YYLabel alloc] init];
|
||
// morelabel.text = @">";
|
||
// morelabel.textAlignment = NSTextAlignmentRight;
|
||
// morelabel.textColor = UIColorHex(#999999);
|
||
// morelabel.font = SYSTEMFONT(14);
|
||
// MJWeakSelf
|
||
// [morelabel setTextTapAction:^(UIView * _Nonnull containerView, NSAttributedString * _Nonnull text, NSRange range, CGRect rect) {
|
||
// if (self.watchMoreBlock) {
|
||
// self.watchMoreBlock();
|
||
// }
|
||
// }];
|
||
// [heaedImg addSubview:morelabel];
|
||
//
|
||
// [morelabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
// make.right.mas_offset(-13);
|
||
// make.centerY.mas_equalTo(heaedImg);
|
||
// make.width.height.mas_offset(20);
|
||
// }];
|
||
//
|
||
self.watchNumberLabel = [[YYLabel alloc] init];
|
||
|
||
self.watchNumberLabel.text = @"";
|
||
|
||
self.watchNumberLabel.textAlignment = NSTextAlignmentLeft;
|
||
|
||
self.watchNumberLabel.textColor = UIColorHex(#14BEBE);
|
||
|
||
self.watchNumberLabel.font = MEDIUMFONT(13);
|
||
|
||
[heaedImg addSubview:self.watchNumberLabel];
|
||
|
||
[self.watchNumberLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.right.mas_equalTo(moreBtn.mas_left);
|
||
make.top.mas_offset(0);
|
||
make.height.mas_offset(40);
|
||
}];
|
||
MJWeakSelf
|
||
[self.watchNumberLabel setTextTapAction:^(UIView * _Nonnull containerView, NSAttributedString * _Nonnull text, NSRange range, CGRect rect) {
|
||
|
||
if (weakSelf.bindDeviceBlock) {
|
||
weakSelf.bindDeviceBlock(weakSelf.watchModel.watchNo);
|
||
}
|
||
}];
|
||
|
||
//日期切换
|
||
// self.timeView = [[UIView alloc] init];
|
||
// self.timeView.backgroundColor = KWhiteColor;
|
||
// [self addSubview:self.timeView];
|
||
//
|
||
// [self.timeView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
// make.left.right.mas_offset(0);
|
||
// make.top.mas_equalTo(heaedImg.mas_bottom);
|
||
// make.height.mas_offset(52);
|
||
// }];
|
||
//
|
||
// UIButton *preBtn = [[UIButton alloc] init];
|
||
// [preBtn setTitle:@"上一天" forState:UIControlStateNormal];
|
||
// [preBtn setImage:[UIImage imageNamed:@"blackLeftAccow"] forState:UIControlStateNormal];
|
||
// [preBtn setTitleColor:UIColorHex(#333333) forState:UIControlStateNormal];
|
||
// preBtn.titleLabel.font = MEDIUMFONT(12);
|
||
// preBtn.titleEdgeInsets = UIEdgeInsetsMake(0, -8, 0, 8); // 左边多 4px 间距
|
||
// self.preBtn = preBtn;
|
||
// [preBtn addTarget:self action:@selector(previousWeekAction) forControlEvents:UIControlEventTouchUpInside];
|
||
// [self.timeView addSubview:preBtn];
|
||
//
|
||
// [preBtn mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
// make.left.mas_equalTo(@46);
|
||
// make.width.mas_offset(60); // 注意宽度要能容纳文字+图片
|
||
// make.centerY.mas_equalTo(self.timeView);
|
||
// }];
|
||
// preBtn.semanticContentAttribute = UISemanticContentAttributeForceRightToLeft;
|
||
//
|
||
//
|
||
// UIButton *rightBtn = [[UIButton alloc] init];
|
||
// [rightBtn setImage:[UIImage imageNamed:@"blackRightAccow"] forState:UIControlStateNormal];
|
||
// [rightBtn setTitle:@"下一天" forState:UIControlStateNormal];
|
||
// [rightBtn setTitleColor:UIColorHex(#333333) forState:UIControlStateNormal];
|
||
// rightBtn.titleLabel.font = MEDIUMFONT(12);
|
||
// rightBtn.titleEdgeInsets = UIEdgeInsetsMake(0, 8, 0, 0); // 左边多 4px 间距
|
||
// self.nextBtn = rightBtn;
|
||
// [rightBtn addTarget:self action:@selector(nextWeekAction) forControlEvents:UIControlEventTouchUpInside];
|
||
// [self.timeView addSubview:rightBtn];
|
||
// [rightBtn mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
// make.right.mas_equalTo(@-46);
|
||
// make.width.mas_offset(60); // 记得宽度要能容下文字+图片
|
||
// make.centerY.mas_equalTo(self.timeView);
|
||
// }];
|
||
//
|
||
// self.weekLabel = [[UILabel alloc] init];
|
||
// self.weekLabel.textAlignment = NSTextAlignmentCenter;
|
||
// self.weekLabel.textColor = UIColorHex(#333333);
|
||
// self.weekLabel.font = MEDIUMFONT(12);
|
||
// [self.timeView addSubview: self.weekLabel];
|
||
//
|
||
// [self.weekLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
// make.right.mas_equalTo(rightBtn.mas_left);
|
||
// make.left.mas_equalTo(preBtn.mas_right);
|
||
// make.centerY.mas_equalTo(self.timeView);
|
||
// make.top.mas_offset(0);
|
||
// }];
|
||
//
|
||
// [self updateWeekLabelWithType];
|
||
//
|
||
// ── Tab ScrollView ───────────────────────────────────
|
||
// _tabScrollView = [[UIScrollView alloc] init];
|
||
// _tabScrollView.showsHorizontalScrollIndicator = NO;
|
||
// _tabScrollView.showsVerticalScrollIndicator = NO;
|
||
// [self addSubview:_tabScrollView];
|
||
//
|
||
// [_tabScrollView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
// make.top.equalTo(heaedImg.mas_bottom);
|
||
// make.left.right.equalTo(self);
|
||
// make.height.mas_equalTo(kTabScrollH);
|
||
// }];
|
||
|
||
// scrollView 内的容器 view(Masonry 驱动 contentSize)
|
||
// _tabContentView = [[UIView alloc] init];
|
||
// [_tabScrollView addSubview:_tabContentView];
|
||
//
|
||
// [_tabContentView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
// make.edges.equalTo(_tabScrollView); // 四边贴 scrollView
|
||
// make.height.equalTo(_tabScrollView); // 固定高度 = scrollView,只横向滚动
|
||
// }];
|
||
|
||
// ── 底部 CollectionView ──────────────────────────────
|
||
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
|
||
layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
|
||
layout.minimumLineSpacing = 0;
|
||
layout.minimumInteritemSpacing = 0;
|
||
|
||
_collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero
|
||
collectionViewLayout:layout];
|
||
_collectionView.backgroundColor = UIColor.clearColor;
|
||
_collectionView.showsHorizontalScrollIndicator = NO;
|
||
_collectionView.pagingEnabled = YES;
|
||
_collectionView.delegate = self;
|
||
_collectionView.dataSource = self;
|
||
[_collectionView registerClass:[XJHomeWatchCollectionViewCell class]
|
||
forCellWithReuseIdentifier:NSStringFromClass([XJHomeWatchCollectionViewCell class])];
|
||
[self addSubview:_collectionView];
|
||
|
||
[_collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.top.equalTo(@40);
|
||
make.left.right.bottom.equalTo(self);
|
||
}];
|
||
|
||
|
||
// ── 未登录占位 Label ─────────────────────────────────────────
|
||
_emptyLabel = [[UILabel alloc] init];
|
||
_emptyLabel.text = @" 暂未登录 ";
|
||
_emptyLabel.textAlignment = NSTextAlignmentCenter;
|
||
_emptyLabel.textColor = [UIColor colorWithRed:0.6 green:0.6 blue:0.6 alpha:1.0];
|
||
_emptyLabel.font = [UIFont systemFontOfSize:15.0];
|
||
_emptyLabel.hidden = YES;
|
||
[self.collectionView addSubview:_emptyLabel];
|
||
|
||
[_emptyLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.center.equalTo(self.collectionView);
|
||
}];
|
||
|
||
// ── 无设备占位 View(已登录但未绑定设备时显示)────────────────
|
||
_emptyView = [[UIView alloc] init];
|
||
_emptyView.backgroundColor = KWhiteColor;
|
||
_emptyView.hidden = YES;
|
||
[self addSubview:_emptyView];
|
||
|
||
[_emptyView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.top.equalTo(@40);
|
||
make.left.right.bottom.equalTo(self);
|
||
}];
|
||
|
||
// // 空状态图标,宽高 59,居中,距 Tab 切换 View 底部 16
|
||
// UIImageView *emptyImageView = [[UIImageView alloc] init];
|
||
// emptyImageView.image = [UIImage imageNamed:@"ic_watch_empty"];
|
||
// emptyImageView.contentMode = UIViewContentModeScaleAspectFit;
|
||
// [_emptyView addSubview:emptyImageView];
|
||
//
|
||
// [emptyImageView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
// make.top.mas_offset(16);
|
||
// make.centerX.equalTo(_emptyView);
|
||
// make.width.height.mas_offset(59);
|
||
// }];
|
||
//
|
||
// // 提示文字:~ 暂无数据 ~,字号 11 regular,颜色 #B6B6B6
|
||
// UILabel *emptyHintLabel = [[UILabel alloc] init];
|
||
// emptyHintLabel.text = @"~ 暂无数据 ~";
|
||
// emptyHintLabel.textAlignment = NSTextAlignmentCenter;
|
||
// emptyHintLabel.textColor = UIColorHex(#B6B6B6);
|
||
// emptyHintLabel.font = [UIFont systemFontOfSize:11];
|
||
// [_emptyView addSubview:emptyHintLabel];
|
||
//
|
||
// [emptyHintLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
// make.top.equalTo(emptyImageView.mas_bottom).offset(8);
|
||
// make.centerX.equalTo(_emptyView);
|
||
// }];
|
||
|
||
// 去绑定按钮:宽 80 高 24,medium 13,颜色 #21BEBD,圆角 12,白底边框 1
|
||
UIButton *bindBtn = [UIButton buttonWithType:UIButtonTypeCustom];
|
||
[bindBtn setTitle:@"去绑定" forState:UIControlStateNormal];
|
||
[bindBtn setTitleColor:UIColorHex(#21BEBD) forState:UIControlStateNormal];
|
||
bindBtn.titleLabel.font = MEDIUMFONT(13);
|
||
bindBtn.backgroundColor = KWhiteColor;
|
||
bindBtn.layer.cornerRadius = 12;
|
||
bindBtn.layer.borderWidth = 1;
|
||
bindBtn.layer.borderColor = UIColorHex(#21BEBD).CGColor;
|
||
bindBtn.layer.masksToBounds = YES;
|
||
[bindBtn addTarget:self action:@selector(bindButtonClick) forControlEvents:UIControlEventTouchUpInside];
|
||
[_emptyView addSubview:bindBtn];
|
||
|
||
[bindBtn mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.top.mas_offset(20);
|
||
make.centerX.equalTo(_emptyView);
|
||
make.width.mas_offset(82);
|
||
make.height.mas_offset(24);
|
||
}];
|
||
|
||
if ([HQCommonUtils isLogin]) {
|
||
// 已登录,等待数据回调
|
||
} else {
|
||
// 未登录:显示"暂未登录"文字,emptyView 保持隐藏
|
||
_emptyLabel.hidden = NO;
|
||
_collectionView.hidden = NO;
|
||
}
|
||
}
|
||
|
||
- (void)bindButtonClick {
|
||
if (self.bindDeviceBlock) {
|
||
self.bindDeviceBlock(@"");
|
||
}
|
||
}
|
||
|
||
- (void)moreClick {
|
||
|
||
if (![HQCommonUtils isLogin]) {
|
||
|
||
KPostNotification(KNotificationLoginStateChange, @NO);
|
||
|
||
return;
|
||
}
|
||
|
||
if (self.watchModel.hasWatch == true) {
|
||
if (self.watchMoreBlock) {
|
||
self.watchMoreBlock();
|
||
}
|
||
}else {
|
||
|
||
if (self.bindDeviceBlock) {
|
||
self.bindDeviceBlock(@"");
|
||
}
|
||
}
|
||
|
||
}
|
||
- (void)setWatchModel:(XJHomeWatchModel *)watchModel {
|
||
|
||
_watchModel = watchModel;
|
||
|
||
if (_watchModel.hasWatch == true) {
|
||
//有手表
|
||
self.watchNumberLabel.text = [NSString stringWithFormat:@"监测工具编码:%@",_watchModel.watchNo];
|
||
self.watchNumberLabel.textColor = UIColorHex(#14BEBE);
|
||
|
||
|
||
}else
|
||
{
|
||
self.watchNumberLabel.text = @"监测工具编码:暂无信息";
|
||
self.watchNumberLabel.textColor = UIColorHex(#808080);
|
||
self.dataList = @[];
|
||
}
|
||
|
||
}
|
||
|
||
#pragma mark - Tab Titles Setter
|
||
|
||
- (void)setTabTitles:(NSArray<NSString *> *)tabTitles {
|
||
_tabTitles = [tabTitles copy];
|
||
_selectedIndex = 0;
|
||
|
||
// 清除旧按钮
|
||
for (UIButton *btn in _tabButtons) [btn removeFromSuperview];
|
||
[_tabButtons removeAllObjects];
|
||
|
||
UIFont *font = [UIFont systemFontOfSize:14 weight:UIFontWeightBold];
|
||
UIButton *prevBtn = nil;
|
||
|
||
for (NSInteger i = 0; i < (NSInteger)tabTitles.count; i++) {
|
||
NSString *title = tabTitles[i];
|
||
BOOL isSelected = (i == 0);
|
||
|
||
// 计算文字宽度,得到按钮宽度
|
||
CGFloat textW = ceil([title boundingRectWithSize:CGSizeMake(MAXFLOAT, kButtonH)
|
||
options:NSStringDrawingUsesLineFragmentOrigin
|
||
attributes:@{NSFontAttributeName: font}
|
||
context:nil].size.width);
|
||
CGFloat btnW = textW + kRealValue(kButtonPadX) * 2;
|
||
|
||
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
|
||
btn.tag = i;
|
||
btn.titleLabel.font = font;
|
||
btn.layer.cornerRadius = kButtonH / 2.0;
|
||
btn.clipsToBounds = YES;
|
||
btn.backgroundColor = isSelected ? UIColorHex(#14BEBE) : UIColorHex(#F6F7FB);
|
||
[btn setTitle:title forState:UIControlStateNormal];
|
||
btn.titleLabel.font = isSelected ? BOLDSYSTEMFONT(15) : [UIFont systemFontOfSize:14 weight:UIFontWeightRegular];
|
||
[btn setTitleColor:isSelected ? KWhiteColor : UIColorHex(#808080)
|
||
forState:UIControlStateNormal];
|
||
[btn addTarget:self
|
||
action:@selector(p_tabButtonTapped:)
|
||
forControlEvents:UIControlEventTouchUpInside];
|
||
|
||
[_tabContentView addSubview:btn];
|
||
|
||
[btn mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.centerY.equalTo(_tabContentView);
|
||
make.height.mas_equalTo(kButtonH);
|
||
make.width.mas_equalTo(btnW);
|
||
|
||
if (prevBtn) {
|
||
make.left.equalTo(prevBtn.mas_right).offset(kButtonGap);
|
||
} else {
|
||
make.left.equalTo(_tabContentView).offset(kButtonGap);
|
||
}
|
||
|
||
// 最后一个按钮右边贴 contentView(撑开 scrollView contentSize)
|
||
if (i == (NSInteger)tabTitles.count - 1) {
|
||
make.right.equalTo(_tabContentView).offset(-kButtonGap);
|
||
}
|
||
}];
|
||
|
||
[_tabButtons addObject:btn];
|
||
prevBtn = btn;
|
||
}
|
||
}
|
||
|
||
#pragma mark - Button Tap
|
||
|
||
- (void)p_tabButtonTapped:(UIButton *)sender {
|
||
NSInteger index = sender.tag;
|
||
[self selectTabAtIndex:index];
|
||
// 用户主动点击,重置轮播计时器
|
||
[self p_restartAutoScroll];
|
||
}
|
||
|
||
#pragma mark - Public: Select Tab
|
||
|
||
//- (void)selectTabAtIndex:(NSInteger)index {
|
||
// if (index < 0 || index >= (NSInteger)_tabButtons.count) return;
|
||
// if (![HQCommonUtils isLogin]) {
|
||
// KPostNotification(KNotificationLoginStateChange, @NO);
|
||
// return;
|
||
// }
|
||
//
|
||
// // 恢复旧 Tab 样式
|
||
// UIButton *oldBtn = _tabButtons[_selectedIndex];
|
||
// oldBtn.backgroundColor = UIColorHex(#F6F7FB);
|
||
// oldBtn.titleLabel.font = [UIFont systemFontOfSize:14 weight:UIFontWeightRegular];
|
||
// [oldBtn setTitleColor:UIColorHex(#808080) forState:UIControlStateNormal];
|
||
//
|
||
// // 设置新 Tab 样式
|
||
// _selectedIndex = index;
|
||
// UIButton *newBtn = _tabButtons[index];
|
||
// newBtn.backgroundColor = UIColorHex(#14BEBE);
|
||
// newBtn.titleLabel.font = BOLDSYSTEMFONT(14);
|
||
// [newBtn setTitleColor:KWhiteColor forState:UIControlStateNormal];
|
||
//
|
||
// [self p_scrollToButton:newBtn];
|
||
//
|
||
// // tab 0:显示 CollectionView 并恢复轮播;其他:显示"紧急开发中"并暂停轮播
|
||
// BOOL isFirst = (index == 0);
|
||
// _collectionView.hidden = !isFirst;
|
||
// _devView.hidden = isFirst;
|
||
//
|
||
// if (isFirst) {
|
||
// // 切换回第一个 Tab,重新根据数据状态显示 emptyView
|
||
// BOOL isEmpty = (_dataList.count == 0);
|
||
// _emptyView.hidden = !isEmpty;
|
||
// [self p_restartAutoScroll];
|
||
// } else {
|
||
// // 切换到其他 Tab,隐藏 emptyView
|
||
// _emptyView.hidden = YES;
|
||
// [self p_stopAutoScroll];
|
||
// }
|
||
//
|
||
// // 通知外部高度变化
|
||
// if (self.tabSelectBlock) {
|
||
// self.tabSelectBlock(index, _tabTitles[index]);
|
||
// }
|
||
//}
|
||
|
||
///// 若按钮中心超过可视区一半,则滚动将其居中
|
||
//- (void)p_scrollToButton:(UIButton *)btn {
|
||
// // layoutIfNeeded 保证 frame 已计算
|
||
// [_tabScrollView layoutIfNeeded];
|
||
//
|
||
// CGFloat scrollW = _tabScrollView.bounds.size.width;
|
||
// CGFloat contentW = _tabScrollView.contentSize.width;
|
||
// CGFloat btnCenterX = CGRectGetMidX(btn.frame);
|
||
//
|
||
// CGFloat offsetX = 0;
|
||
// if (btnCenterX > scrollW / 2.0) {
|
||
// offsetX = btnCenterX - scrollW / 2.0;
|
||
// offsetX = MIN(offsetX, MAX(contentW - scrollW, 0));
|
||
// }
|
||
//
|
||
// [_tabScrollView setContentOffset:CGPointMake(offsetX, 0) animated:YES];
|
||
//}
|
||
|
||
#pragma mark - DataList Setter
|
||
|
||
- (void)setDataList:(NSArray *)dataList {
|
||
_dataList = [dataList copy];
|
||
|
||
// 未登录:显示 emptyLabel,隐藏 emptyView 及内容区
|
||
if (![HQCommonUtils isLogin]) {
|
||
_emptyLabel.text = @" 暂未登录 ";
|
||
_emptyLabel.hidden = NO;
|
||
_emptyView.hidden = YES;
|
||
_collectionView.hidden = YES;
|
||
return;
|
||
}
|
||
|
||
// 已登录:隐藏 emptyLabel,显示内容区
|
||
_emptyLabel.hidden = YES;
|
||
_collectionView.hidden = NO;
|
||
|
||
// 无设备数据:显示 emptyView(图标 + 提示 + 去绑定按钮)
|
||
BOOL isEmpty = (_dataList.count == 0);
|
||
_emptyView.hidden = !isEmpty;
|
||
|
||
[_collectionView reloadData];
|
||
|
||
// 有多条数据才启动轮播
|
||
if (_dataList.count > 1) {
|
||
[self p_startAutoScroll];
|
||
} else {
|
||
[self p_stopAutoScroll];
|
||
}
|
||
|
||
// 通知外部更新高度:无数据/未登录 104,有数据 205
|
||
BOOL needSmall = (isEmpty || ![HQCommonUtils isLogin]);
|
||
CGFloat newHeight = needSmall ? 104.0 : 200.0;
|
||
if (self.heightChangeBlock) {
|
||
self.heightChangeBlock(newHeight);
|
||
}
|
||
}
|
||
|
||
#pragma mark - UICollectionViewDataSource
|
||
|
||
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
|
||
return self.dataList.count;
|
||
}
|
||
|
||
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
|
||
cellForItemAtIndexPath:(NSIndexPath *)indexPath {
|
||
XJHomeWatchCollectionViewCell *cell =
|
||
[collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([XJHomeWatchCollectionViewCell class])
|
||
forIndexPath:indexPath];
|
||
// 用 dataList 里对应位置的 model 填充
|
||
if (indexPath.item < (NSInteger)_dataList.count) {
|
||
[cell configureWithData:_dataList[indexPath.item]];
|
||
}
|
||
// // item 下标即数据类型:0=心率 1=血氧 2=压力 3=体温
|
||
// [cell updateTabIndex:indexPath.item];
|
||
return cell;
|
||
}
|
||
|
||
#pragma mark - UICollectionViewDelegateFlowLayout
|
||
|
||
- (CGSize)collectionView:(UICollectionView *)collectionView
|
||
layout:(UICollectionViewLayout *)collectionViewLayout
|
||
sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
|
||
// cell 宽 = 整个 view 宽;cell 高 = collectionView 自身高度
|
||
return CGSizeMake(self.bounds.size.width, collectionView.bounds.size.height);
|
||
}
|
||
|
||
#pragma mark - UICollectionViewDelegate
|
||
|
||
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
|
||
// 预留:外部如需监听 cell 点击可在此通过 block 回调
|
||
}
|
||
|
||
#pragma mark - UIScrollViewDelegate(手动滑动同步 Tab)
|
||
|
||
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
|
||
if (scrollView != _collectionView) return;
|
||
// 更新轮播页码(与 Tab selectedIndex 无关)
|
||
_carouselPage = (NSInteger)(scrollView.contentOffset.x / MAX(scrollView.bounds.size.width, 1));
|
||
[self p_restartAutoScroll];
|
||
}
|
||
|
||
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
|
||
if (scrollView != _collectionView) return;
|
||
// 手指触碰时暂停自动轮播,避免与手势冲突
|
||
[self p_stopAutoScroll];
|
||
}
|
||
|
||
#pragma mark - 轮播
|
||
|
||
/// 启动自动轮播(3 秒一次)
|
||
- (void)p_startAutoScroll {
|
||
[self p_stopAutoScroll];
|
||
if (_dataList.count <= 1) return;
|
||
_autoScrollTimer = [NSTimer scheduledTimerWithTimeInterval:5.0
|
||
target:self
|
||
selector:@selector(p_autoScrollToNext)
|
||
userInfo:nil
|
||
repeats:YES];
|
||
// 加入 NSRunLoopCommonModes,防止父 ScrollView 滚动时定时器暂停
|
||
[[NSRunLoop mainRunLoop] addTimer:_autoScrollTimer forMode:NSRunLoopCommonModes];
|
||
}
|
||
|
||
/// 停止自动轮播
|
||
- (void)p_stopAutoScroll {
|
||
[_autoScrollTimer invalidate];
|
||
_autoScrollTimer = nil;
|
||
}
|
||
|
||
/// 重置定时器(用户交互后调用)
|
||
- (void)p_restartAutoScroll {
|
||
if (_dataList.count > 1) [self p_startAutoScroll];
|
||
}
|
||
|
||
/// 滚到下一页,最后一页→第一页不用动画,避免明显跳动
|
||
- (void)p_autoScrollToNext {
|
||
if (_dataList.count == 0) return;
|
||
NSInteger next = (_carouselPage + 1) % _dataList.count;
|
||
BOOL animated = (next != 0);
|
||
[self p_scrollCollectionToIndex:next animated:animated];
|
||
}
|
||
|
||
/// 滚动 collectionView 到指定页,只更新 carouselPage,不影响 Tab
|
||
- (void)p_scrollCollectionToIndex:(NSInteger)index animated:(BOOL)animated {
|
||
if (index < 0 || index >= (NSInteger)_dataList.count) return;
|
||
_carouselPage = index;
|
||
NSIndexPath *ip = [NSIndexPath indexPathForItem:index inSection:0];
|
||
[_collectionView scrollToItemAtIndexPath:ip
|
||
atScrollPosition:UICollectionViewScrollPositionLeft
|
||
animated:animated];
|
||
}
|
||
|
||
/// 离开父视图时停止轮播,防止 timer 持有 self 造成内存泄漏
|
||
- (void)willMoveToSuperview:(UIView *)newSuperview {
|
||
[super willMoveToSuperview:newSuperview];
|
||
if (!newSuperview) [self p_stopAutoScroll];
|
||
}
|
||
|
||
#pragma mark - 上一日/上一周、下一日/下一周
|
||
|
||
// 上一日/上一周
|
||
- (void)previousWeekAction {
|
||
|
||
self.currentDayDate = [self dateByAddingDays:-1 toDate:self.currentDayDate];
|
||
[self updateWeekLabelWithType];
|
||
[self checkNextButtonState];
|
||
}
|
||
|
||
// 下一日/下一周
|
||
- (void)nextWeekAction {
|
||
self.currentDayDate = [self dateByAddingDays:1 toDate:self.currentDayDate];
|
||
[self updateWeekLabelWithType];
|
||
[self checkNextButtonState];
|
||
}
|
||
|
||
- (void)updateWeekLabelWithType {
|
||
|
||
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
|
||
formatter.dateFormat = @"yyyy-MM-dd";
|
||
self.weekLabel.text = [formatter stringFromDate:self.currentDayDate];
|
||
|
||
if (self.changeTimeClickBlock) {
|
||
NSString *dayYMD = [self formatDateToYMDString:self.currentDayDate];
|
||
self.changeTimeClickBlock(dayYMD); //
|
||
}
|
||
|
||
}
|
||
|
||
// 日期加减
|
||
- (NSDate *)dateByAddingDays:(NSInteger)days toDate:(NSDate *)date {
|
||
return [date dateByAddingTimeInterval:days*24*60*60];
|
||
}
|
||
|
||
- (NSString *)formatDateToYMDString:(NSDate *)date {
|
||
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
|
||
[formatter setDateFormat:@"yyyy-MM-dd"];
|
||
return [formatter stringFromDate:date];
|
||
}
|
||
|
||
|
||
#pragma mark - 检查下一天/下一周按钮状态
|
||
|
||
- (void)checkNextButtonState {
|
||
NSCalendar *calendar = [NSCalendar currentCalendar];
|
||
[calendar setFirstWeekday:2]; // 周一为第一天
|
||
|
||
NSDate *today = [NSDate date];
|
||
|
||
NSDate *currentOnly = [self dateByRemovingTime:self.currentDayDate];
|
||
NSDate *todayOnly = [self dateByRemovingTime:today];
|
||
self.nextBtn.enabled = ([currentOnly compare:todayOnly] == NSOrderedAscending);
|
||
|
||
}
|
||
|
||
// 去掉时分秒
|
||
- (NSDate *)dateByRemovingTime:(NSDate *)date {
|
||
NSCalendar *calendar = [NSCalendar currentCalendar];
|
||
NSDateComponents *components = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay
|
||
fromDate:date];
|
||
return [calendar dateFromComponents:components];
|
||
}
|
||
|
||
@end
|