0

I have a UIDatePicker being shown in a popover. When I spin, half the time the value won't update, then it will every time after that. The other half, it updates the first time and every time after that - just as expected.

Scenario 1: tap, choose time, update, value updates, update again, value updates again... repeat.

Scenario 2: tap, choose time, update, value doesn't update, update again, value updates, update again, value updates... repeat.

At first, it was skipping the update the first time every time, then implementing this answer's fix seemed to help until I used it more to see it only works now about half the time.

@property (nonatomic, strong) UIViewController *datePickerController;

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.row == kAddEditProductsTargetBatchTime) {
        [self setupDatePickerWithIndexPath:indexPath];
    }
}

- (void)setupDatePickerWithIndexPath:(NSIndexPath *)indexPath {
    CGRect cellFrame = [self.tableView rectForRowAtIndexPath:indexPath];
    CGRect popoverFrame = CGRectMake(cellFrame.size.width - 100.0f, cellFrame.origin.y, 50.0f, cellFrame.size.height);

    CGSize dpSize = CGSizeMake(200, 180);
    _datePickerController = [[UIViewController alloc] init];

    UIDatePicker *datePicker=[[UIDatePicker alloc]init];

    datePicker.frame = CGRectMake(0,0,dpSize.width, dpSize.height);
    datePicker.datePickerMode = UIDatePickerModeCountDownTimer;
    datePicker.countDownDuration = 0;

    batchTarget *defaultCycleTarget = [cycleTargetRepository defaultCycleTarget:_product.cycleTargets]; //NSTimeInterval

    if (indexPath.row == kAddEditProductsTargetBatchTime) {
        NSDateComponents *dateComp = [NSDateComponents new];
        dateComp.hour = [NSNumberFormatter hoursComponent:defaultCycleTarget.targetBatchTime]; //NSTimeInterval
        dateComp.minute = [NSNumberFormatter minutesComponent:defaultCycleTarget.targetBatchTime]; //NSTimeInterval
        NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
        NSDate *pickerDate = [calendar dateFromComponents:dateComp];

        [datePicker setDate:pickerDate animated: YES];
        [datePicker addTarget:self action:@selector(batchTimeChanged:) forControlEvents:UIControlEventValueChanged];
    }
    _datePickerController.view = datePicker;

    _datePickerController.modalPresentationStyle = UIModalPresentationPopover;
    _datePickerController.preferredContentSize = dpSize;
    [self presentViewController:_datePickerController animated:YES completion:nil];
    _datePickerController.popoverPresentationController.sourceRect = popoverFrame;
    _datePickerController.popoverPresentationController.sourceView = self.view;
}

//timeChanged doesn't even get fired off.. randomly && only on the first try
- (void)timeChanged:(UIDatePicker *)sender {
    batchTarget *defaultCycleTarget = [cycleTargetRepository defaultCycleTarget:_product.cycleTargets];
    if (defaultCycleTarget) {
        defaultCycleTarget.targetBatchTime = sender.countDownDuration;
    } else {
        // If no defaultCycleTarget we need to initialize the data
        batchTarget *newCycleTarget = [batchTarget new];
        newCycleTarget.targetBatchTime = sender.countDownDuration;
        _product.cycleTargets = [NSArray arrayWithObject:newCycleTarget];
    }
    [self.tableView reloadData];
}

I have essentially the same exact code in a different view using Swift and experience the same problem.

Community
  • 1
  • 1

1 Answers1

0

Seems like iOS buffer issues.

try to change the runloop and make the multiple of 60 secs. It works for me.

- (void) someMethodName
{
    [self performSelector:@selector(sel:) withObject:datePicker afterDelay:0];
}

- (void) sel:(UIDatePicker *)datePicker
{
    datePicker.countDownDuration = 60;
}
GDSM
  • 166
  • 2
  • 7
  • So I add `[self performSelector:@selector(setDuration:) withObject:datePicker afterDelay:0];` to `setupDatePickerWithIndexPath` and `- (void)setDuration:(UIDatePicker *)datePicker { datePicker.countDownDuration = 60; }`. This made the problem worse in that it _always_ takes two spins to update now. – Nick Calabro Sep 23 '16 at 18:36