1

I've used this tutorial to create a gradient background for my app. It looks beautiful. However there is a problem when I change the orientation.

It looks proper in portrait mode but in landscape orientation the gradient doesn't cover the entire view. I've uploaded a screenshot -

http://www.screencast.com/t/c4vUv55Xq0

The red is the gradient and the blue part is the default background color which is supposed to be completely covered by the red gradient.

How can I cover entire view? I tried to call the gradient method after detecting rotation change but it didn't work. This is the code I used:

    [[NSNotificationCenter defaultCenter]
     addObserver:self
     selector:@selector(deviceOrientationDidChangeNotification:)
     name:UIDeviceOrientationDidChangeNotification
     object:nil];// this is in 'viewWillAppear' method


- (void)deviceOrientationDidChangeNotification:(NSNotification*)note
{
    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
    [self addBackground];
}
Rob
  • 415,655
  • 72
  • 787
  • 1,044
Bilbo Baggins
  • 3,644
  • 8
  • 40
  • 64
  • What does your addBackground method look like? If you are using the code found in the tutorial `gradient.frame = self.view.bounds;` make sure your self.view.bounds are reporting the correct bounds. – davis Jun 23 '13 at 05:58
  • @DavisG. How can I get the correct bounds at runtime when the orientation is changed? – Bilbo Baggins Jun 23 '13 at 06:02
  • [This](http://stackoverflow.com/questions/2686882/incorrect-frame-window-size-after-re-orientation-in-iphone) might help. It would appear that the method `-(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {` correctly reports the bounds in landscape orientation. – davis Jun 23 '13 at 06:05
  • This is news to me, but [this](http://the.ichibod.com/kiji/how-to-handle-device-rotation-for-uiviews-in-ios/) site states that "any changes based on the bounds of the view (self) will not be updated by the time this method has been called." And it is referring to the deviceOrientationDidChangeNotification – davis Jun 23 '13 at 06:06
  • I wonder why it takes so long to update the values. Anyway viewDidLayoutSubviews works properly. Thanks. – Bilbo Baggins Jun 23 '13 at 20:24

1 Answers1

4

My guess is the system sends UIDeviceOrientationDidChangeNotification before actually updating the view hierarchy for the landscape layout.

Instead of redoing the gradient in response to UIDeviceOrientationDidChangeNotification, do it in viewDidLayoutSubviews. When your view controller receives viewDidLayoutSubviews, its view's frame has already been modified for the new interface orientation. Something like this should do:

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    self.background.frame = self.view.bounds;
}
rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • This worked, thanks! I used replaceSublayer to apply a new coat of gradient when the orientation was changed. - http://stackoverflow.com/questions/3713292/replacesublayer-example I had to use 2 similar methods. One draws the gradient on viewDidLoad and the other replaces it with viewDidLayoutSubviews. – Bilbo Baggins Jun 23 '13 at 20:23