8

I'm using Auto Layout in my iOS 7 project with the following view hierarchy

Main View
-Container View
---Button
---Button
---ImageView
-Banner View (iAd Banner View)

The Main View and Container View are full width and height of screen. I have Horizontal and Vertical Space Constraints on the Container View sticking to the main view (screen's height and width). And also the subviews of Container View are constrained to the button of the view with a 20px space.

My issue occurs when the Banner View is finally filled and placed at the bottom of the screen, which then I have the Container View subtract the Banner View's Height from its frame height to allow space for the Banner View to show. (code used below) The ideal outcome is the Container View to subtract the height and its subviews constraint update based on this new height ,but what end up happening is the iAD Banner View just overlays the view as shown in the picture.

Code for BannerViewDidLoadAd:

- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
    CGRect contentFrame = self.containerView.bounds;

    CGRect bannerFrame = self.bannerView.bounds;
    if (self.bannerView.bannerLoaded) {
        contentFrame.size.height = self.containerView.frame.size.height - self.bannerView.frame.size.height;

        bannerFrame.origin.y = contentFrame.size.height;;
    } else {
        bannerFrame.origin.y = contentFrame.size.height;
    }



    [UIView animateWithDuration:animated ? 0.25 : 0.0 animations:^{
        [self.containerView setFrame:contentFrame];
        [self.containerView layoutIfNeeded];
        self.bannerView.frame = bannerFrame;
        self.bannerView.hidden = NO;
    }];

    [self.containerView updateConstraints];
}

Image of iAd overlaying Container View and it's SubViews

iad overlaying

William
  • 1,033
  • 2
  • 13
  • 25
  • When using auto layout, you should never set frames directly. You need to change all frames by modifying or adding/subtracting constraints. – rdelmar Nov 30 '13 at 06:15
  • @rdelmar so I should essentially add new constraints to the hidden banner View and edit the Container View bottom constraint to the new bannerView? Thanks, If you could give me an example of how to handle this would be great! :) – William Nov 30 '13 at 06:18
  • I'm not sure exactly what you're doing. Is the banner view being added as a subview, or are you moving it in from off screen? Does the banner view have a fixed height, or is it variable? What is Preview View (is that the container view)? – rdelmar Nov 30 '13 at 06:20
  • @rdelmar sorry about that updated the post yes Preview View is the Container View. And the Banner View is not a subview of the Container View but a sibling. I create the Banner View programmatically, and add it as a subview to the Main View, so i'm unhiding it and moving it in place. Banner View does have a fixed height. – William Nov 30 '13 at 06:32

2 Answers2

8

After you create the banner view in code (and add it as a subview of main view), you should add a 0 length spacing constraint between the bottom of the container view, and the top of the banner view (the banner view would need constraints to the two sides of the main view and a height constraint as well). The container view should have 0 length constraints to all four edges of the main view. You should make an IBOutlet to that bottom constraint, and animate that constraint's constant value by an amount equal to the height of the banner view (so it will shrink, and the banner view will move up with it due to its 0 length vertical spacing constraint). So, if the outlet to the bottom constraint was called bottomCon, and the height of the banner view was 100 points, you would animate like this:

[UIView animateWithDuration:animated ? 0.25 : 0.0 animations:^{
        self.bottomCon.constant = 100;
        [self.mainView layoutIfNeeded];
    }];

There's no need to hide and unhide the view, since you will initially place it off the bottom of the screen anyway. Also make sure that you call [bannerView setTranslatesAutoresizingMaskIntoConstraints:NO] right after you create the banner view, or you'll get auto layout errors when you run the app.

rdelmar
  • 103,982
  • 12
  • 207
  • 218
  • Thanks I will try what you have suggested here and post back with how it goes. – William Dec 02 '13 at 06:01
  • So I got this working with your input, only thing I left out was the 0 length constraint between the container view and top of banner view, when i added this xcode error'd on runtime saying there was 2 constraints that conflicted, seemed to be the container view bottom to main view bottom constraint causing the error. – William Dec 02 '13 at 18:50
  • Thanks, the constraints exception has finally gone! – HotJard Jul 02 '15 at 06:59
  • 1
    @rdelmar:I am facing same issue but I have tableview above bannerview. I can not understand how the length constraint would be 0 to both bannerview and mainview? – iPhone Aug 10 '15 at 11:40
  • 1
    @rdelmar: because the top of the bannerview is not same is the bottom of the mainview. – iPhone Aug 10 '15 at 11:41
3

The response from rdelmar was enough for me to get this working, but I'll add a few things. With auto layout on, there is no need to set the banner's size with setAutoresizingMask:UIViewAutoresizingFlexibleWidth (and currentContentSizeIdentifier is deprecated in iOS 6). Just create the banner object and then pin it into position using the procedure outlined by rdelmar and auto layout takes care of the horizontal sizing.

Here are the constraints I used:

// pin sides to superview
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[_bannerView]-0-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_bannerView)]];

// set height to a constant
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_bannerView(==66)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_bannerView)]];

// pin contentView to bannerView with 0 length constraint
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_contentView]-0-[_bannerView]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_contentView,_bannerView)]];

I was concerned about setting a height constraint because the height of the banner will change depending on platform and/or orientation. But it doesn't seem to make any difference what value I set for the height constraint - the banner is always shown with the correct height, so I don't even bother setting it. I am assuming this because there is an intrinsic sizing to the height of the ad banners.

Bob
  • 559
  • 1
  • 5
  • 18