• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

ios - 显示启用/禁用时间单位的倒计时

[复制链接]
菜鸟教程小白 发表于 2022-12-12 18:09:08 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

这个问题基本上是关于自定义日期格式的。我设法开发了一个倒计时应用程序,该应用程序设法创建一个事件,以后可以由客户查看、自定义或跟踪。重要的部分是倒计时计时器,它从 db 中获取秒数并根据日期格式化程序显示剩余时间。到目前为止,我在应用程序中使用默认设置,计数器格式为 dd:hh:mm,显然我的客户希望允许应用程序用户自定义时间的显示方式。所以现在用户可以选择四个选项,例如 yy:weeks:hh:mm 或months:weeks:days:hours。我认为最好的方法是将表四个索引作为字符串保存到 db 中。我的问题出现在日历上。

conversionInfo = [sysCalendar components:NSHourCalendarUnit | NSMinuteCalendarUnit | NSDayCalendarUnit | NSSecondCalendarUnit fromDate:today  toDate:future  options:0];

        one = [NSString stringWithFormat"%d Days %d Hours %d Minutes %d Seconds %@", [conversionInfo day], [conversionInfo hour],[conversionInfo minute],[conversionInfo second], untilOrSince]; self.eventTimer.text = one;

conversionInfo = [sysCalendar components: NSHourCalendarUnit | NSSecondCalendarUnit fromDate:today  toDate:future  options:0];

        one = [NSString stringWithFormat"%ld Seconds %@", (long)[conversionInfo second], untilOrSince];

此外,如果我确实使用所有单位构建日历但仅显示秒,那么倒计时将仅显示 59 秒而不是 343746545 秒,直到 The counter

例如,这些日历单位不能放置在数组中,那么如果用户选择 2、4、5、6(即月:日:小时:分钟),我将如何选择日历格式?我不能说 components = [NSArray arrayWithObjects: [arrComponents objectAtIndex:2], [arrComponents objectAtIndex:2],nil];

User options

有什么想法吗?



Best Answer-推荐答案


好吧,这比我最初想象的要难


在整个系统中,单位标志用于将日期定义为组件等。这个单元缺陷可以组合成一个值,一个位掩码。我将它用于我的代码。

年份单位可能是0....000010 月份单位可能是 0....000100

两者的位掩码都是

  0....000010    NSCalendarUnitYear
  0....000100    NSCalendarUnitMonth
 ------------
& 0....000110

所以要保存要使用一个单元的信息意味着我们只需将适当的位设置为 1

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.selectedUnitsBitmask= 0;
    self.unitNames = @[ @"Year", @"Month", @"Week", @"Day", @"Hour", @"Minute", @"Second"];
    self.units = @[@(NSCalendarUnitYear), @(NSCalendarUnitMonth), @(NSCalendarUnitWeekOfMonth), @(NSCalendarUnitDay), @(NSCalendarUnitHour), @(NSCalendarUnitMinute), @(NSCalendarUnitSecond)];


    NSDateComponents *c = [[NSDateComponents alloc] init];
    c.year = 2014;
    c.month = 12;
    c.day = 25;

    self.futureDate = [[NSCalendar currentCalendar] dateFromComponents:c];
}

self.unitNames 的值用于填充表格 View 。
self.units 存储每个可用单元的单元标志。

-(UITableViewCell *)tableViewUITableView *)tableView
        cellForRowAtIndexPathNSIndexPath *)indexPath
{
    static NSString *CellIdentifier =@"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    cell.textLabel.text = _unitNames[indexPath.row];


    NSUInteger s;
    NSUInteger row = indexPath.row;
    s = NSIntegerMax & [self.units[row] integerValue];
    cell.accessoryType = (self.selectedUnitsBitmask & s) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
    return cell;

}

如果选择了一个单元格,s = NSIntegerMax & [self.units[row] integerValue]; 将检查位掩码,如果要使用这个单元。

如果选择了一个单元格,我们想要切换它所代表的单元的位

-(void)tableViewUITableView *)tableView didSelectRowAtIndexPathNSIndexPath *)indexPath
{

    NSUInteger s;
    NSUInteger row = indexPath.row;
    s = NSIntegerMax & [self.units[row] integerValue];
    self.selectedUnitsBitmask ^= s ;
    NSLog(@"%lu, %lu", (unsigned long)s, (unsigned long)self.selectedUnitsBitmask);

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    cell.accessoryType =(self.selectedUnitsBitmask & s) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
    [self updateCountDownLabel:nil];
}

这里

NSUInteger s;
NSUInteger row = indexPath.row;
s = NSIntegerMax & [self.units[row] integerValue];

s代表被选中的位,

self.selectedUnitsBitmask ^= s ;

将在位掩码中切换它。 bitmask ^= sbitmask = bitmask ^ s 的简写形式,其中 ^ 是异或:位掩码的第 n 位有与s的第n位相反

  0011    bitmask
^ 0101    s
  ----
= 1100

现在我们可以根据位掩码中的单位标志更新将打印时差的字符串:

- (IBAction)updateCountDownLabelid)sender {

    BOOL includeYear  = self.selectedUnitsBitmask & NSCalendarUnitYear;
    BOOL includeMonth = self.selectedUnitsBitmask & NSCalendarUnitMonth;
    BOOL includeDay   = self.selectedUnitsBitmask & NSCalendarUnitDay;
    BOOL includeHour  = self.selectedUnitsBitmask & NSCalendarUnitHour;
    BOOL includeMinute= self.selectedUnitsBitmask & NSCalendarUnitMinute;
    BOOL includeSecond= self.selectedUnitsBitmask & NSCalendarUnitSecond;

    NSDateComponents *diffDateComponents = [[NSCalendar currentCalendar] components:self.selectedUnitsBitmask fromDate:[NSDate date] toDate:self.futureDate options:0];

    NSMutableString *outputString = [@"" mutableCopy];
    if (includeYear && diffDateComponents.year)
        [outputString appendFormat"%d Year", diffDateComponents.year];
    if (includeMonth && diffDateComponents.month)
        [outputString appendFormat" %d Month", diffDateComponents.month];
    if (diffDateComponents.weekOfMonth < NSIntegerMax && diffDateComponents.weekOfMonth)
        [outputString appendFormat" %d Week", diffDateComponents.weekOfMonth];
    if (includeDay && diffDateComponents.day)
        [outputString appendFormat" %d Day", diffDateComponents.day];
    if (includeHour && diffDateComponents.hour)
        [outputString appendFormat" %d Hour", diffDateComponents.hour];
    if (includeMinute && diffDateComponents.minute)
        [outputString appendFormat" %d Minute", diffDateComponents.minute];
    if (includeSecond && diffDateComponents.second)
        [outputString appendFormat" %d Second", diffDateComponents.second];




    self.countDownLabel.text = [outputString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];

}

要确定是否设置了标志,我们使用 & AND 运算符

BOOL includeYear  = self.selectedUnitsBitmask & NSCalendarUnitYear;

如果年份标志是 0....000010

位掩码包含0....010110

& 操作会返回

  0....000010    NSCalendarUnitYear
& 0....010110    bitmask
-------------
= 0....000010    -> NSCalendarUnitYear

我们为所有单位执行此操作一周。我不知道为什么,但是 & 操作总是为它返回 0。这里我们使用 hack:

if (diffDateComponents.weekOfYear < NSIntegerMax)
    [outputString appendFormat" %d Week", diffDateComponents.weekOfYear];

对于新的 NSDateComponents week 用整数表示的最大数 NSIntegerMax 进行实例化。如果它的值小于 NSIntegerMax 我们假设它被设置并且我们将它附加到字符串中。


结果:

enter image description here


将整个代码合二为一:


#import "ViewController.h"

@interface ViewController () <UITableViewDataSource, UITableViewDelegate>

@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (weak, nonatomic) IBOutlet UILabel *countDownLabel;
@property (nonatomic) NSInteger selectedUnitsBitmask;
@property (strong, nonatomic) NSArray *unitNames;
@property (strong, nonatomic) NSArray *units;
@property (strong, nonatomic) NSDate *futureDate;


- (IBAction)updateCountDownLabelid)sender;
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.selectedUnitsBitmask= 0;
    self.unitNames = @[ @"Year", @"Month", @"Week", @"Day", @"Hour", @"Minute", @"Second"];
    self.units = @[@(NSCalendarUnitYear), @(NSCalendarUnitMonth), @(NSCalendarUnitWeekOfMonth), @(NSCalendarUnitDay), @(NSCalendarUnitHour), @(NSCalendarUnitMinute), @(NSCalendarUnitSecond)];


    NSDateComponents *c = [[NSDateComponents alloc] init];
    c.year = 2014;
    c.month = 12;
    c.day = 25;

    self.futureDate = [[NSCalendar currentCalendar] dateFromComponents:c];
}



-(NSInteger)numberOfSectionsInTableViewUITableView *)tableView
{
    return 1;
}

-(NSInteger)tableViewUITableView *)tableView numberOfRowsInSectionNSInteger)section
{
    return [self.units count];
}

-(UITableViewCell *)tableViewUITableView *)tableView
        cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier =@"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    cell.textLabel.text = _unitNames[indexPath.row];

    NSUInteger s;
    NSUInteger row = indexPath.row;
    s = NSIntegerMax & [self.units[row] integerValue];
    cell.accessoryType = (self.selectedUnitsBitmask & s) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;


    return cell;

}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

    NSUInteger s;
    NSUInteger row = indexPath.row;
    s = NSIntegerMax & [self.units[row] integerValue];
    self.selectedUnitsBitmask ^= s ;
    NSLog(@"%lu, %lu", (unsigned long)s, (unsigned long)self.selectedUnitsBitmask);

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    cell.accessoryType =(self.selectedUnitsBitmask & s) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
    [self updateCountDownLabel:nil];
}

- (IBAction)updateCountDownLabel:(id)sender {

    BOOL includeYear  = self.selectedUnitsBitmask & NSCalendarUnitYear;
    BOOL includeMonth = self.selectedUnitsBitmask & NSCalendarUnitMonth;
    BOOL includeDay   = self.selectedUnitsBitmask & NSCalendarUnitDay;
    BOOL includeHour  = self.selectedUnitsBitmask & NSCalendarUnitHour;
    BOOL includeMinute= self.selectedUnitsBitmask & NSCalendarUnitMinute;
    BOOL includeSecond= self.selectedUnitsBitmask & NSCalendarUnitSecond;

    NSDateComponents *diffDateComponents = [[NSCalendar currentCalendar] components:self.selectedUnitsBitmask fromDate:[NSDate date] toDate:self.futureDate options:0];

    NSMutableString *outputString = [@"" mutableCopy];
    if (includeYear && diffDateComponents.year)
        [outputString appendFormat:@"%d Year", diffDateComponents.year];
    if (includeMonth && diffDateComponents.month)
        [outputString appendFormat:@" %d Month", diffDateComponents.month];
    if (diffDateComponents.weekOfMonth < NSIntegerMax && diffDateComponents.weekOfMonth)
        [outputString appendFormat:@" %d Week", diffDateComponents.weekOfMonth];
    if (includeDay && diffDateComponents.day)
        [outputString appendFormat:@" %d Day", diffDateComponents.day];
    if (includeHour && diffDateComponents.hour)
        [outputString appendFormat:@" %d Hour", diffDateComponents.hour];
    if (includeMinute && diffDateComponents.minute)
        [outputString appendFormat:@" %d Minute", diffDateComponents.minute];
    if (includeSecond && diffDateComponents.second)
        [outputString appendFormat:@" %d Second", diffDateComponents.second];


    self.countDownLabel.text = [outputString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];

}

关于ios - 显示启用/禁用时间单位的倒计时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21289670/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap