Question

My app uses UIStepper controls in a few different views. I released a minor update to the app that shouldn't affect these views at all, and I started getting reports that all the UISteppers in the app are now disabled. One user sent a screen shot, and the stepper control appears as if its enabled property were set to NO. However, there's no place in my code where I set this property at all, and the default is YES. I've searched my app for instances of the term "enabled" to make sure I'm not somehow disabling it accidentally, and I'm not.

I thought perhaps the default value for the enabled property changed between iOS versions, but the users who have reported this are running iOS 5.1.1, the same as my development devices. And I only started hearing about the problem with this app update.

Besides setting the enabled property, I found that the steppers will be disabled if the min and max values are set to the same value. I'm pretty sure this is not happening in my app. The values are hard-coded and passed to a setup method, and I haven't changed this code since many app versions ago.

Do you know any other reason why this would happen? I can't reproduce the problem myself, and it only affects some users, so it's difficult to troubleshoot.

Here's my code for creating the UISteppers, for what it's worth:

- (UIStepper *)makeStepperInput:(float )currentValue minValue:(float)minValue maxValue:(float)maxValue increment:(float)increment {
    int stepperWidth = 94;
    int stepperHeight = 27;
    CGRect stepperFrame = CGRectMake(0, 0, stepperWidth, stepperHeight);

    UIStepper *stepperInput = [[[UIStepper alloc] initWithFrame:stepperFrame] autorelease];
    stepperInput.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;

    [stepperInput setValue:currentValue];
    [stepperInput setMinimumValue:minValue];
    [stepperInput setMaximumValue:maxValue];
    [stepperInput setStepValue:stepValue];
    [stepperInput setContinuous:NO];

    NSLog(@"making stepper with values %f, %f, %f, %f (%i)", currentValue, minValue, maxValue, stepValue, stepperInput.enabled);

    [stepperInput addTarget:self action:@selector(onChange:) forControlEvents:UIControlEventValueChanged];

    return stepperInput;
}

UPDATE: I have a user who was willing to install a debug version with the NSLog line above. He sent me the console output and it shows that the min and max value of the stepper are correct (1 and 20 in one case) and that the enabled property is YES. Unfortunately, that eliminates both of my theories about what could be happening here...

Was it helpful?

Solution

Okay, here's what happened. The method posted above is a simplified version of my real method, which provides some branching for pre-iOS 5 devices. To help with pre-iOS 5 support, I was actually declaring stepperInput as a UIControl, and then returning something different on iOS versions that don't support UIStepper.

Now the interesting part. I rolled my project back and started looking at my build settings, and remembered that before my last release, Xcode gave me one of those alert messages about my build settings being out of date. I had clicked the button to allow Xcode to make all the recommended changes. This time, I performed one change at a time and tested my app after each change.

The first of the recommended changes was to "Upgrade Compiler configuration to LVVM". ("The compiler configuration is set to 'com.apple.compilers.llvmgcc42'. This will upgrade to 'Apple LLVM compiler 4.0', which is the recommended setting for iOS targets.") As soon as I made that change, the problem appeared on my test device. So it seems that the old compiler allowed me to set UIStepper properties on an object declared as a UIControl, while the new compiler did not. Indeed, when I changed my NSLog line above to output the actual values of the stepper, instead of the values passed into the method, they all returned 0. Having its min and max values both set to 0 is what made the stepper appear to be disabled.

I didn't think this affected all users because I couldn't reproduce it, but I was testing with the older build settings rather than the build settings used for the release. So now I'm thinking that this probably does affect all users, and only some users have noticed it.

Anyway, the solution is to reorganize my code so I can declare that UIStepper as a real UIStepper, since the newer compiler doesn't allow the kind of fudging I was doing before.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top