2

I am using NSUSerDefaults to store a couple strings and integers for my application. Whenever a view is opened, the string is loaded slower than the view so you see a glitch. For example, I save the selectedSegmentIndex and then read it in viewDidAppear and for a quick moment when the view is called, no segment is selected, then the right one selects. How do you make it so there is no time gap between the view being opened and the setting be read?

- (void)viewDidLoad
{
    [super viewDidLoad];

    int segmentIndex = [[NSUserDefaults standardUserDefaults] integerForKey:@"selectedIndex"];
    unitSegmentControl.selectedSegmentIndex = segmentIndex;

    BOOL location = [[NSUserDefaults standardUserDefaults] boolForKey:@"locationManager"];
    [gpsSwitch setOn:location animated:NO];

    deviceID.text =  [[NSUserDefaults standardUserDefaults] stringForKey:@"DeviceID"];

}


- (IBAction)changeSeg:(id)sender {

    if (unitSegmentControl.selectedSegmentIndex == 0) {
        [[NSUserDefaults standardUserDefaults] setObject:@"http://98.246.50.81/firecom/xml/units/E01.xml" forKey:@"parserURL"];
        [[NSUserDefaults standardUserDefaults] setObject:@"Hillsboro Main" forKey:@"selectedStation"];
        [[NSUserDefaults standardUserDefaults] setObject:@"Hillsboro Fire & Rescue" forKey:@"selectedDepartment"];
    }
    if (unitSegmentControl.selectedSegmentIndex == 1) {
        [[NSUserDefaults standardUserDefaults] setObject:@"http://98.246.50.81/firecom/xml/units/E02.xml" forKey:@"parserURL"];
        [[NSUserDefaults standardUserDefaults] setObject:@"Hillsboro Witch Hazel" forKey:@"selectedStation"];
        [[NSUserDefaults standardUserDefaults] setObject:@"Hillsboro Fire & Rescue" forKey:@"selectedDepartment"];
    }
    [[NSUserDefaults standardUserDefaults] setInteger:unitSegmentControl.selectedSegmentIndex forKey:@"selectedIndex"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}
mmc
  • 17,354
  • 2
  • 34
  • 52
Jon Erickson
  • 1,876
  • 4
  • 30
  • 73

1 Answers1

3

The defaults are not slow, you’re just loading the data too late. The standard place to populate views is in -viewDidLoad or -viewWillAppear in the view’s controller. Both will update the view soon enough to avoid visual glitches. If any of the two doesn’t work for you, here’s some tips to find the reason:

  • Try to set the selected index to a hard-wired number. This will tell you if the problem is in the defaults or (much more likely) in the -setSelectedSegmentIndex call.
  • Move the UI population code to -viewWillAppear. That’s the latest moment to update the UI before it’s displayed.
  • Use NSParameterAssert to make sure unitSegmentControl is not nil.
  • Make sure the index read back from the defaults is the expected number. Generally, it’s best to pull the defaults keys into constants. That way you can’t bump into simple typo bugs:

    static NSString *const SelectedSegmentKey = @"selectedSegment";
    
  • If everything else fails, use a custom UISegmentControl subclass for your unitSegmentControl and place a breakpoint into -setSelectedSegmentIndex to see who else might be calling it.

zoul
  • 102,279
  • 44
  • 260
  • 354
  • Well, when I place the code in either of those methods, it doesn't work at all. – Jon Erickson Dec 21 '12 at 19:45
  • Then you’re doing something wrong. Hard to say what without seeing the code. Can you replicate the problem on a [small code sample](http://sscce.org)? – zoul Dec 21 '12 at 19:47