375 lines
14 KiB
Objective-C
375 lines
14 KiB
Objective-C
#import "CreateEventPickerContainerView.h"
|
||
#import "EventConfigModel.h"
|
||
@interface CreateEventPickerContainerView () <UIGestureRecognizerDelegate, UIPickerViewDataSource, UIPickerViewDelegate>
|
||
@property (nonatomic, strong) EventConfigModel *configModel;
|
||
@property (nonatomic, strong) UIPickerView *pickerView;
|
||
@property (nonatomic, strong) NSDate *minDate;
|
||
@property (nonatomic, strong) NSDate *maxDate;
|
||
@property (nonatomic, strong) NSArray<NSDate *> *dateArray;
|
||
@property (nonatomic, strong) NSArray<NSString *> *monthArray;
|
||
@property (nonatomic, strong) NSArray<NSString *> *dayArray;
|
||
@property (nonatomic, strong) NSArray<NSString *> *hourArray;
|
||
@property (nonatomic, strong) NSDate *selectedDate;
|
||
// StartTime 相关
|
||
@property (nonatomic, strong) NSArray<NSDictionary *> *durationsOptions;
|
||
@end
|
||
|
||
@implementation CreateEventPickerContainerView {
|
||
UIView *_pickerBg;
|
||
UILabel *_titleLabel;
|
||
UIButton *_okButton;
|
||
}
|
||
|
||
- (instancetype)init {
|
||
self = [super init];
|
||
if (self) {
|
||
[self setupUI];
|
||
}
|
||
return self;
|
||
}
|
||
|
||
- (void)setupUI {
|
||
self.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.3];
|
||
|
||
// 底部白色背景
|
||
_pickerBg = [[UIView alloc] init];
|
||
_pickerBg.backgroundColor = [UIColor whiteColor];
|
||
_pickerBg.layer.cornerRadius = 16;
|
||
_pickerBg.clipsToBounds = YES;
|
||
[self addSubview:_pickerBg];
|
||
|
||
// 标题
|
||
_titleLabel = [[UILabel alloc] init];
|
||
_titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium];
|
||
_titleLabel.textColor = [UIColor blackColor];
|
||
_titleLabel.textAlignment = NSTextAlignmentCenter;
|
||
[_pickerBg addSubview:_titleLabel];
|
||
|
||
// OK 按钮
|
||
_okButton = [UIButton buttonWithType:UIButtonTypeSystem];
|
||
[_okButton setTitle:@"OK" forState:UIControlStateNormal];
|
||
[_okButton setTitleColor:UIColorFromRGB(0xff8c03) forState:UIControlStateNormal];
|
||
_okButton.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium];
|
||
[_okButton addTarget:self action:@selector(okTapped) forControlEvents:UIControlEventTouchUpInside];
|
||
[_pickerBg addSubview:_okButton];
|
||
|
||
// Picker View
|
||
self.pickerView = [[UIPickerView alloc] init];
|
||
self.pickerView.dataSource = self;
|
||
self.pickerView.delegate = self;
|
||
[_pickerBg addSubview:self.pickerView];
|
||
|
||
// 点击背景关闭
|
||
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismiss)];
|
||
[self addGestureRecognizer:tap];
|
||
tap.delegate = self;
|
||
|
||
// 布局
|
||
[_pickerBg mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.left.right.bottom.equalTo(self);
|
||
make.height.mas_equalTo(320);
|
||
}];
|
||
|
||
[_titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.top.equalTo(_pickerBg).offset(8);
|
||
make.centerX.equalTo(_pickerBg);
|
||
make.height.mas_equalTo(26);
|
||
}];
|
||
|
||
[_okButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.centerY.equalTo(_titleLabel);
|
||
make.right.equalTo(_pickerBg).offset(-16);
|
||
}];
|
||
|
||
[self.pickerView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.top.equalTo(_titleLabel.mas_bottom).offset(8);
|
||
make.left.right.equalTo(_pickerBg);
|
||
}];
|
||
}
|
||
|
||
#pragma mark - UIGestureRecognizerDelegate
|
||
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
|
||
if ([touch.view isDescendantOfView:_pickerBg]) {
|
||
return NO;
|
||
}
|
||
return YES;
|
||
}
|
||
|
||
#pragma mark - Public Methods
|
||
- (NSDictionary *)formatTimeWithString:(NSString *)minutesString {
|
||
// 将字符串转换为整数
|
||
NSInteger minutes = [minutesString integerValue];
|
||
|
||
NSMutableDictionary *result = [NSMutableDictionary dictionary];
|
||
result[@"minutes"] = minutesString;
|
||
|
||
if (minutes < 60) {
|
||
// 小于60分钟,直接显示分钟
|
||
result[@"title"] = [NSString stringWithFormat:@"%@%@", minutesString, YMLocalizedString(@"XPFreeGiftsObtainView4")];
|
||
} else if (minutes < 1440) {
|
||
// 大于等于60分钟且小于24小时(1440分钟)
|
||
NSInteger hours = minutes / 60;
|
||
NSInteger remainingMinutes = minutes % 60;
|
||
|
||
if (remainingMinutes == 0) {
|
||
// 没有剩余分钟
|
||
result[@"title"] = [NSString stringWithFormat:@"%ld%@", (long)hours, YMLocalizedString(@"XPFreeGiftsObtainView5")];
|
||
} else {
|
||
// 有剩余分钟
|
||
result[@"title"] = [NSString stringWithFormat:@"%ld%@ %ld%@", (long)hours, YMLocalizedString(@"XPFreeGiftsObtainView5"), (long)remainingMinutes, YMLocalizedString(@"XPFreeGiftsObtainView4")];
|
||
}
|
||
} else {
|
||
// 大于等于24小时
|
||
NSInteger days = minutes / 1440;
|
||
NSInteger remainingMinutes = minutes % 1440;
|
||
NSInteger hours = remainingMinutes / 60;
|
||
NSInteger mins = remainingMinutes % 60;
|
||
|
||
if (hours == 0 && mins == 0) {
|
||
// 无小时和分钟
|
||
result[@"title"] = [NSString stringWithFormat:@"%ld%@",
|
||
(long)days,
|
||
YMLocalizedString(@"App_Commont_Day")];
|
||
} else if (mins == 0) {
|
||
// 有小时无分钟
|
||
result[@"title"] = [NSString stringWithFormat:@"%ld%@ %ld%@",
|
||
(long)days,
|
||
YMLocalizedString(@"App_Commont_Day"),
|
||
(long)hours,
|
||
YMLocalizedString(@"XPFreeGiftsObtainView5")];
|
||
} else if (hours == 0) {
|
||
// 无小时有分钟
|
||
result[@"title"] = [NSString stringWithFormat:@"%ld%@ %ld%@",
|
||
(long)days,
|
||
YMLocalizedString(@"App_Commont_Day"),
|
||
(long)mins,
|
||
YMLocalizedString(@"XPFreeGiftsObtainView4")];
|
||
} else {
|
||
// 有小时和分钟
|
||
result[@"title"] = [NSString stringWithFormat:@"%ld%@ %ld%@ %ld%@",
|
||
(long)days,
|
||
YMLocalizedString(@"App_Commont_Day"),
|
||
(long)hours,
|
||
YMLocalizedString(@"XPFreeGiftsObtainView5"),
|
||
(long)mins,
|
||
YMLocalizedString(@"XPFreeGiftsObtainView4")];
|
||
}
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
- (void)buildDurationDataSource {
|
||
NSMutableArray *arr = [NSMutableArray array];
|
||
for (NSString *duration in self.configModel.durations) {
|
||
[arr addObject:[self formatTimeWithString:duration]];
|
||
}
|
||
self.durationsOptions = arr.copy;
|
||
}
|
||
|
||
- (void)buildStartTimeSourceWithInitialDate:(NSDate *)date {
|
||
NSCalendar *calendar = [NSCalendar currentCalendar];
|
||
NSDate *now = [NSDate date];
|
||
|
||
// 最早:当前时间+24小时
|
||
NSDate *start = [calendar dateByAddingUnit:NSCalendarUnitHour
|
||
value:24
|
||
toDate:now
|
||
options:0];
|
||
|
||
// 最晚:当前时间+1个月
|
||
NSDateComponents *comp = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:now];
|
||
comp.month += 1;
|
||
NSDate *end = [calendar dateFromComponents:comp];
|
||
|
||
self.minDate = start;
|
||
self.maxDate = end;
|
||
|
||
NSMutableArray *months = [NSMutableArray array];
|
||
NSMutableArray *days = [NSMutableArray array];
|
||
NSMutableArray *hours = [NSMutableArray array];
|
||
|
||
NSDate *iter = start;
|
||
while ([iter compare:end] != NSOrderedDescending) {
|
||
NSDateComponents *c = [calendar components:NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour fromDate:iter];
|
||
|
||
NSString *monthStr = [NSString stringWithFormat:@"%02ld", (long)c.month];
|
||
NSString *dayStr = [NSString stringWithFormat:@"%02ld", (long)c.day];
|
||
NSString *hourStr = [NSString stringWithFormat:@"%02ld:00", (long)c.hour];
|
||
|
||
if (![months containsObject:monthStr]) [months addObject:monthStr];
|
||
if (![days containsObject:dayStr]) [days addObject:dayStr];
|
||
if (![hours containsObject:hourStr]) [hours addObject:hourStr];
|
||
|
||
iter = [calendar dateByAddingUnit:NSCalendarUnitHour value:1 toDate:iter options:0];
|
||
}
|
||
|
||
self.monthArray = months;
|
||
self.dayArray = days;
|
||
self.hourArray = hours;
|
||
self.selectedDate = start;
|
||
}
|
||
|
||
- (void)showInView:(UIView *)parentView
|
||
initialDate:(NSDate *)date
|
||
config:(EventConfigModel *)config
|
||
pickerType:(CreateEventPickerType)type
|
||
onConfirm:(void (^)(NSDate *date,
|
||
NSString *resultString,
|
||
NSInteger dutationMinutes))onConfirm{
|
||
self.pickerType = type;
|
||
self.configModel = config;
|
||
self.onConfirmDate = onConfirm;
|
||
if (type == CreateEventPickerTypeStartTime) {
|
||
[self buildStartTimeSourceWithInitialDate:date];
|
||
_titleLabel.text = YMLocalizedString(@"20.20.59_text_15");
|
||
} else if (type == CreateEventPickerTypeDuration) {
|
||
[self buildDurationDataSource];
|
||
_titleLabel.text = YMLocalizedString(@"20.20.59_text_16");
|
||
}
|
||
self.frame = parentView.bounds;
|
||
[parentView addSubview:self];
|
||
self.alpha = 0;
|
||
[self.pickerView reloadAllComponents];
|
||
[UIView animateWithDuration:0.25 animations:^{
|
||
self.alpha = 1;
|
||
}];
|
||
}
|
||
|
||
#pragma mark - UIPickerViewDataSource & Delegate
|
||
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
|
||
switch (self.pickerType) {
|
||
case CreateEventPickerTypeStartTime:
|
||
return 3;
|
||
break;
|
||
case CreateEventPickerTypeDuration:
|
||
default:
|
||
return 1;
|
||
break;
|
||
}
|
||
}
|
||
|
||
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
|
||
switch (self.pickerType) {
|
||
case CreateEventPickerTypeStartTime: {
|
||
if (component == 0) return self.monthArray.count;
|
||
if (component == 1) return self.dayArray.count;
|
||
if (component == 2) return self.hourArray.count;
|
||
}
|
||
break;
|
||
case CreateEventPickerTypeDuration:
|
||
default:
|
||
return self.durationsOptions.count;
|
||
break;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
|
||
switch (self.pickerType) {
|
||
case CreateEventPickerTypeStartTime: {
|
||
NSInteger monthIdx = [pickerView selectedRowInComponent:0];
|
||
NSInteger dayIdx = [pickerView selectedRowInComponent:1];
|
||
NSInteger hourIdx = [pickerView selectedRowInComponent:2];
|
||
NSCalendar *calendar = [NSCalendar currentCalendar];
|
||
NSDateComponents *nowComp = [calendar components:NSCalendarUnitYear fromDate:[NSDate date]];
|
||
NSInteger year = nowComp.year;
|
||
NSInteger month = [self.monthArray[monthIdx] integerValue];
|
||
NSInteger day = [self.dayArray[dayIdx] integerValue];
|
||
NSInteger hour = [[self.hourArray[hourIdx] substringToIndex:2] integerValue];
|
||
NSDateComponents *selComp = [[NSDateComponents alloc] init];
|
||
selComp.year = year;
|
||
selComp.month = month;
|
||
selComp.day = day;
|
||
selComp.hour = hour;
|
||
selComp.minute = 0;
|
||
self.selectedDate = [calendar dateFromComponents:selComp];
|
||
}
|
||
break;
|
||
case CreateEventPickerTypeDuration: {
|
||
NSInteger minutes = [self.durationsOptions[row][@"minutes"] integerValue];
|
||
NSCalendar *calendar = [NSCalendar currentCalendar];
|
||
self.selectedDate = [calendar dateByAddingUnit:NSCalendarUnitMinute value:minutes toDate:[NSDate date] options:0];
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||
[pickerView reloadComponent:component];
|
||
});
|
||
}
|
||
|
||
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
|
||
NSInteger selectedRow = [pickerView selectedRowInComponent:component];
|
||
BOOL isSelectedRow = selectedRow == row;
|
||
NSString *content = @"";
|
||
switch (self.pickerType) {
|
||
case CreateEventPickerTypeStartTime: {
|
||
if (component == 0) content = self.monthArray[row];
|
||
if (component == 1) content = self.dayArray[row];
|
||
if (component == 2) content = self.hourArray[row];
|
||
}
|
||
break;
|
||
case CreateEventPickerTypeDuration:
|
||
content = self.durationsOptions[row][@"title"];
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
UILabel *label = (UILabel *)view;
|
||
if (!label) {
|
||
label = [[UILabel alloc] init];
|
||
label.textAlignment = NSTextAlignmentCenter;
|
||
label.backgroundColor = [UIColor clearColor];
|
||
}
|
||
|
||
label.text = content;
|
||
label.font = isSelectedRow ? kFontMedium(15) : kFontRegular(15);
|
||
label.textColor = isSelectedRow ? UIColorFromRGB(0x313131) : UIColorFromRGB(0x7b7b7d);
|
||
|
||
return label;
|
||
}
|
||
|
||
- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component {
|
||
return 30; // 设置行高
|
||
}
|
||
|
||
#pragma mark - Actions
|
||
- (void)okTapped {
|
||
if (self.onConfirmDate) {
|
||
NSString *resultString = @"";
|
||
NSInteger durationMinutes = 0;
|
||
switch (self.pickerType) {
|
||
case CreateEventPickerTypeStartTime: {
|
||
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
|
||
formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
|
||
resultString = [formatter stringFromDate:self.selectedDate];
|
||
}
|
||
break;
|
||
case CreateEventPickerTypeDuration: {
|
||
NSInteger selectedRow = [self.pickerView selectedRowInComponent:0];
|
||
resultString = self.durationsOptions[selectedRow][@"title"];
|
||
durationMinutes = [self.durationsOptions[selectedRow][@"minutes"] integerValue];
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
self.onConfirmDate(self.selectedDate, resultString, durationMinutes);
|
||
}
|
||
[self dismiss];
|
||
}
|
||
|
||
- (void)dismiss {
|
||
[UIView animateWithDuration:0.25 animations:^{
|
||
self.alpha = 0;
|
||
} completion:^(BOOL finished) {
|
||
[self removeFromSuperview];
|
||
}];
|
||
}
|
||
|
||
@end
|