Change Frame of Subview in Superview

427 views Asked by At

I have a ViewController that adds an UIView, SpeciesImageView as a subview in viewDidLoad and set constraints in viewWillLayoutSubviews.

SpeciesImageView does not have a nib file. When we create speciesImageView in viewDidLoad, it calls initWithFrame in SpeciesImageView class.

This works fine (in both landscape and portrait) until the phone rotates. I tried setting the constraints as speciesImageView.frame.size.width, but that doesn't work because initWithFrame isn't called when the orientation changes, so the height/width of the speciesImageView remains unchanged.

On the other hand, using screenRect doesn't change the actual size of the UIView, it changes its size within the superview. So in other words, I haven't found a way to change the size of the actual speciesImageView on orientation change.

And for reasons lost to me, it gets completely messed up when you rotate it back to the original position.

- (void)viewDidLoad
{

    self.tabBarController.tabBar.hidden=YES;
    self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
    self.navigationController.navigationBar.hidden = NO;
    //self.navigationController.navigationBar.translucent = YES;


    UIImage *plantinfo;
    if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
        plantinfo = [UIImage imageNamed:@"plantinfo_frame.png"];
    } else {
        plantinfo = [UIImage imageNamed:@"plantinfo.png"];
    }

    UIBarButtonItem *tempButton = [[UIBarButtonItem alloc] initWithImage:plantinfo
                                                                   style:UIBarButtonItemStylePlain
                                                                  target:self
                                                                  action:@selector(toggleText:)];
    self.navigationItem.rightBarButtonItem = tempButton;
    [tempButton release];
    self.title = theSpecies.scientificName;
    //[self.navigationItem.backBarButtonItem setTitle:@""];
    self.navigationItem.backBarButtonItem.title = @"";


    infoViewSegmentedControl.backgroundColor = [UIColor blackColor];
    webView.backgroundColor = [UIColor blackColor];
    _activityIndicator.hidden = YES;

    [webView setOpaque:YES];
    webView.delegate = self;
    // Do double justification
    [webView loadHTMLString:[self formatHTML:theSpecies] baseURL:nil];
    showingInfoView = NO;

    //
    //  Resize containerView, infoview according to iphone 5 screen size.
    //

    infoView.autoresizingMask = UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight;
    CGPoint screenOrigin = [[UIScreen mainScreen] bounds].origin;
    CGSize viewSize = [[UIScreen mainScreen] bounds].size;
    CGPoint origin = infoView.frame.origin;

    CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];

    if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
        infoView.frame = CGRectMake(screenOrigin.x,
                                    screenOrigin.y + statusBarFrame.size.height,
                                    viewSize.width,
                                    viewSize.height - origin.y - statusBarFrame.size.height);

        speciesImageView = [[SpeciesImageView alloc]
                            initWithFrame:CGRectMake(screenOrigin.x,
                                                     screenOrigin.y,
                                                     viewSize.width,
                                                     viewSize.height)];
    } else {
        infoView.frame = CGRectMake(screenOrigin.x,
                                    screenOrigin.y,
                                    viewSize.width,
                                    viewSize.height - origin.y - statusBarFrame.size.height);

        speciesImageView = [[SpeciesImageView alloc]
                            initWithFrame:CGRectMake(screenOrigin.x,
                                                     screenOrigin.y,
                                                     viewSize.width,
                                                     viewSize.height - statusBarFrame.size.height)];
    }

    speciesImageView.delegate = self;
    [containerView addSubview:speciesImageView];

    managedObjectContext = [(LeafletAppDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext];
    [self parseImageURLArray];
}

-(void)viewWillLayoutSubviews{
    if(speciesImageView.window != nil){
        CGRect screenRect = [[UIScreen mainScreen] bounds];
        speciesImageView.translatesAutoresizingMaskIntoConstraints = NO;
        NSLayoutConstraint *widthConst = [NSLayoutConstraint
                                          constraintWithItem:speciesImageView
                                          attribute:NSLayoutAttributeWidth
                                          relatedBy:NSLayoutRelationEqual
                                          toItem:nil
                                          attribute:NSLayoutAttributeNotAnAttribute
                                          multiplier:1.0
                                          constant:screenRect.size.width];

        NSLayoutConstraint *heightConst = [NSLayoutConstraint
                                           constraintWithItem:speciesImageView
                                           attribute:NSLayoutAttributeHeight
                                           relatedBy:NSLayoutRelationEqual
                                           toItem:nil
                                           attribute:NSLayoutAttributeNotAnAttribute
                                           multiplier:1.0
                                           constant:screenRect.size.height];

        NSLayoutConstraint *rightConstraint = [NSLayoutConstraint
                                               constraintWithItem:speciesImageView
                                               attribute:NSLayoutAttributeCenterX
                                               relatedBy:NSLayoutRelationEqual
                                               toItem:self.view
                                               attribute:NSLayoutAttributeCenterX
                                               multiplier:1.0
                                               constant:0.0];


        NSLayoutConstraint *bottomConstraint = [NSLayoutConstraint
                                                constraintWithItem:speciesImageView
                                                attribute:NSLayoutAttributeBottom
                                                relatedBy:NSLayoutRelationEqual
                                                toItem:self.view
                                                attribute:NSLayoutAttributeBottom
                                                multiplier:1.0
                                                constant:0.0];
        [self.view addConstraints:@[widthConst, heightConst, bottomConstraint, rightConstraint]];
    }
}

- (id)initWithFrame:(CGRect)frame
{

    if (self = [super initWithFrame:frame])
    {
        imageScrollView = [[UIScrollView alloc] initWithFrame:frame];
        imageScrollView.delegate = self;
        imageScrollView.backgroundColor = [UIColor blackColor];
        [self addSubview:imageScrollView];

        imageScrollView.translatesAutoresizingMaskIntoConstraints = NO;


        NSLayoutConstraint *widthConst = [NSLayoutConstraint constraintWithItem:imageScrollView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:imageScrollView.frame.size.width];

        NSLayoutConstraint *heightConst = [NSLayoutConstraint constraintWithItem:imageScrollView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:imageScrollView.frame.size.height];


        NSLayoutConstraint *rightConstraint = [NSLayoutConstraint
                                               constraintWithItem:imageScrollView
                                               attribute:NSLayoutAttributeRight
                                               relatedBy:NSLayoutRelationEqual
                                               toItem:self
                                               attribute:NSLayoutAttributeRight
                                               multiplier:1.0
                                               constant:0.0];


        NSLayoutConstraint *bottomConstraint = [NSLayoutConstraint
                                                constraintWithItem:imageScrollView
                                                attribute:NSLayoutAttributeTop
                                                relatedBy:NSLayoutRelationEqual
                                                toItem:self
                                                attribute:NSLayoutAttributeTop
                                                multiplier:1.0
                                                constant:0.0];
        [self addConstraints:@[widthConst, heightConst, bottomConstraint, rightConstraint]];
    }
    return self;
}

Enter Rotate Once Rotate back again

1

There are 1 answers

8
Aris On

If you want your views to adjust to the size of the superview, then you need something like this (set the margin to whatever you like):

CGFloat margin = 0;

NSString * visualFormatH = [NSString stringWithFormat:@"|-(%f)-[speciesImageView]-(%f)-|", margin, margin];
[self.containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:visualFormatH
                                                                           options:0
                                                                           metrics:Nil
                                                                             views:@{@"speciesImageView": speciesImageView}]];
NSString * visualFormatV = [NSString stringWithFormat:@"V:|-(%f)-[speciesImageView]-(%f)-|", margin, margin];
[self.containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:visualFormatV
                                                                           options:0
                                                                           metrics:Nil
                                                                             views:@{@"speciesImageView": speciesImageView}]];

Now speciesImageView will adjust its frame whenever the superview frame changes.

Here is a generic example:

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

UIView * sampleView = [UIView new];
sampleView.backgroundColor = [UIColor redColor];
sampleView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:sampleView];


CGFloat margin = 0;

NSString * visualFormatH = [NSString stringWithFormat:@"|-(%f)-[sampleView]-(%f)-|", margin, margin];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:visualFormatH
                                                                       options:0
                                                                       metrics:Nil
                                                                         views:@{@"sampleView": sampleView}]];
NSString * visualFormatV = [NSString stringWithFormat:@"V:|-(%f)-[sampleView]-(%f)-|", margin, margin];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:visualFormatV
                                                                       options:0
                                                                       metrics:Nil
                                                                         views:@{@"sampleView": sampleView}]];


 }

Auto Layout Getting Started

Auto Layout Visual Format Documentation