Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't get background gradient to fill entire screen upon rotation

I have a background gradient that draws nicely when the screen is initially rendered in portrait mode. However, when the device is rotated to landscape mode, the right 40% of the screen is black (i.e. the background is not drawn on the part of the screen that wasn't previously drawn). I don't know how to get the background to redraw to fill the entire screen.

Can anyone tell me what I am doing wrong? Thanks!

Here is how it looks when initially drawn. enter image description here

And here is now it looks when I rotate it:

enter image description here

Here is the code for my background gradient class:

#import "BackgroundGradient.h"

@interface BackgroundGradient()
@property (strong, nonatomic) UIView *view;
@end

@implementation BackgroundGradient

- (id) initWithView:(UIView *) view
{
    if (!_view)
        _view = view;

    return self;
}

- (void) makeGradient
{
    UIColor *darkOp = [UIColor colorWithRed:(193.0 / 255.0) green:(215.0 / 255.0) blue:(46.0 / 255.0) alpha: 1];
    UIColor *lightOp = [UIColor colorWithRed:(222.0 / 255.0) green:(233.0 / 255.0) blue:(143.0 / 255.0) alpha: 1];

    // Create the gradient
    CAGradientLayer *gradient = [CAGradientLayer layer];

    // Set colors
    gradient.colors = [NSArray arrayWithObjects:
                       (id)darkOp.CGColor,
                       (id)lightOp.CGColor,
                       (id)darkOp.CGColor,
                       nil];

    // Update the start and end points
    gradient.startPoint = CGPointMake(0.5, 0.0);
    gradient.endPoint = CGPointMake(0.5, 1.0);

    // Set bounds
    gradient.frame = self.view.bounds;

    // Add the gradient to the view
    [self.view.layer insertSublayer:gradient atIndex:0];

    gradient.locations = [NSArray arrayWithObjects:
                          [NSNumber numberWithFloat:0.0f],
                          [NSNumber numberWithFloat:0.7],
                          [NSNumber numberWithFloat:0.9],
                          nil];

}

@end

And finally, here is how I instantiate the background object:

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.background = [[BackgroundGradient alloc] initWithView:self.view];
    [self.background makeGradient];

}

EDIT: I've added the following code and included updates to the start and end points (above):

- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [self.background makeGradient];
}

I'm almost there, but now, I get this. Notice how there is still a vertical line. It looks to me like the new background is getting drawn behing the previous background such that the previous background is still there and is blocking the new background. This is particularly noticeable as the animation from portrait to landscape is occurring.

enter image description here

like image 750
AndroidDev Avatar asked Jan 12 '23 13:01

AndroidDev


2 Answers

This is where you are doing it wrong: CAGradientLayer *gradient = [CAGradientLayer layer]; and [self.view.layer insertSublayer:gradient atIndex:0];

You are 'adding'a new instance of gradient layer each time the device rotates. You shouldn't do that. Instead, only set it's frame on rotation, and everything will work absolutely fine. Use only one instance. Create it in viewDidLoad

Use view debugging to help out in such cases.

like image 142
n00bProgrammer Avatar answered Jan 27 '23 21:01

n00bProgrammer


I solved this issue with this: Resize the sublayer of my background image.

Swift

override func willAnimateRotationToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
    self.backgroundImageView.layer.sublayers?.first?.frame = self.view.bounds

}
like image 28
Dasoga Avatar answered Jan 27 '23 22:01

Dasoga