Bug 18657 - AutoLayout does not appear to be working properly.
Summary: AutoLayout does not appear to be working properly.
Status: RESOLVED NOT_REPRODUCIBLE
Alias: None
Product: iOS
Classification: Xamarin
Component: General ()
Version: 7.2.0
Hardware: PC Windows
: Normal normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2014-03-30 23:53 UTC by curtis.harrison@wavetronix.com
Modified: 2014-07-24 10:17 UTC (History)
4 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED NOT_REPRODUCIBLE

Description curtis.harrison@wavetronix.com 2014-03-30 23:53:52 UTC
I have been trying to use the AutoLayout functionality from iOS 6 and 7, but it doesn't appear to work.  Perhaps the Xamarin implementation is buggy, or perhaps I am just doing it wrong.  Here is some code I wrote that should put an iAD banner at the bottom of the screen and a UIView above the banner and both should take the full width of the screen.  When the iPad is rotated and orientation changes, the banner should stay at the bottom of the screen and the view should stay above the banner filling up the remainder of the screen.

The actual result is that the iAD banner is being displayed below the visible screen area and the main UIView is being displayed on the left half of the screen.

Please see the controller code below to duplicate this issue:

using System;
using MonoTouch.iAd;
using MonoTouch.UIKit;

namespace ADayBDayiOS
{
    public class ADViewController : UIViewController
    {
        private UIView InternalView { get; set; }
        private ADBannerView AdView { get; set; }

        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            InternalView = new UIView{BackgroundColor=UIColor.Blue}; 

            //This is apple's standard ADBannerView
            AdView = new ADBannerView(ADAdType.Banner) {Hidden = true};
            AdView.FailedToReceiveAd += HandleFailedToReceiveAd;
            AdView.AdLoaded += HandleAdLoaded;

            View.BackgroundColor = UIColor.Clear;

            //I'm pretty sure that we need these three lines
            View.TranslatesAutoresizingMaskIntoConstraints = false;
            InternalView.TranslatesAutoresizingMaskIntoConstraints = false;
            AdView.TranslatesAutoresizingMaskIntoConstraints = false;

            View.AddSubview(InternalView);
            View.AddSubview(AdView);

            Resize();
        }

        public override void DidRotate(UIInterfaceOrientation fromInterfaceOrientation)
        {
            base.DidRotate(fromInterfaceOrientation);
            Resize();
        }

        public override void ViewDidAppear(bool animated)
        {
            base.ViewDidAppear(animated);
            Resize();
        }

        private void Resize()
        {
            //Remove all constraints, and reset them...
            View.RemoveConstraints(View.Constraints);

            if (AdView == null || AdView.Hidden)
            {//Fill up the entire screen with our InternalView
                View.AddConstraint(NSLayoutConstraint.Create(InternalView, NSLayoutAttribute.Width, NSLayoutRelation.Equal, View, NSLayoutAttribute.Width, 1, 0));
                View.AddConstraint(NSLayoutConstraint.Create(InternalView, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, View, NSLayoutAttribute.Bottom, 1, 0));
                View.AddConstraint(NSLayoutConstraint.Create(InternalView, NSLayoutAttribute.Top, NSLayoutRelation.Equal, View, NSLayoutAttribute.Top, 1, 0));
            }
            else
            {//Put banner ad at the bottom of the screen and fill the rest of the screen with our InternalView
                View.AddConstraint(NSLayoutConstraint.Create(AdView, NSLayoutAttribute.Width, NSLayoutRelation.Equal, View, NSLayoutAttribute.Width, 1, 0));
                View.AddConstraint(NSLayoutConstraint.Create(InternalView, NSLayoutAttribute.Width, NSLayoutRelation.Equal, View, NSLayoutAttribute.Width, 1, 0));

                View.AddConstraint(NSLayoutConstraint.Create(AdView, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, View, NSLayoutAttribute.Bottom, 1, 0));
                View.AddConstraint(NSLayoutConstraint.Create(InternalView, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, View, NSLayoutAttribute.Bottom, 1, AdView.Bounds.Height));
                View.AddConstraint(NSLayoutConstraint.Create(InternalView, NSLayoutAttribute.Top, NSLayoutRelation.Equal, View, NSLayoutAttribute.Top, 1, 0));
            }
        }
        
        /// <summary>
        /// Shows the AdView when a new Ad loads
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void HandleAdLoaded(object sender, EventArgs e)
        {
            if (AdView == null)
                return;
            AdView.Hidden = false;
            Resize();
        }

        /// <summary>
        /// Hides the AdView when no ads are available
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void HandleFailedToReceiveAd(object sender, AdErrorEventArgs e)
        {
            if (AdView == null)
                return;
            AdView.Hidden = true;
            Resize();
        }
    }
}
Comment 1 curtis.harrison@wavetronix.com 2014-03-31 10:19:07 UTC
Further experimentation seems to indicate that there is no difference when I set attribute on item 1 to be top or bottom.  If I set the bottoms of my control and the view to be equal, I also have to set the constant to negative the height of my control.  I would expect this if I had selected top, but it happens when I select bottom.
Comment 2 curtis.harrison@wavetronix.com 2014-03-31 10:19:34 UTC
Further experimentation seems to indicate that there is no difference when I set attribute on item 1 to be top or bottom.  If I set the bottoms of my control and the view to be equal, I also have to set the constant to negative the height of my control.  I would expect this if I had selected top, but it happens when I select bottom.
Comment 3 Udham Singh 2014-03-31 11:44:35 UTC
I have checked this issue and getting the same behavior. To reproduce this I have implemented the code given into bug description.

Screencast : http://screencast.com/t/VRmzU3ON

Environment Info :

Windows 8.1
VS 2013
iOS for VS : 1.10.47
Mac OS X 10.9.2
Xamarin.iOS : 7.2.0.2 (Enterprise Edition)
Xcode 5.1 (5035) Build 5B45j
Comment 4 Rolf Bjarne Kvinge [MSFT] 2014-04-02 13:16:12 UTC
@Udham Singh: could you please attach the project you used to reproduce this bug?
Comment 6 Rolf Bjarne Kvinge [MSFT] 2014-07-24 10:17:50 UTC
As far as I can see there doesn't seem to be any Xamarin.iOS bugs in the sample.

With the following constraints the blue view takes the whole screen:

View.AddConstraint(NSLayoutConstraint.Create(InternalView, NSLayoutAttribute.Left, NSLayoutRelation.Equal, View, NSLayoutAttribute.Left, 1, 0));
View.AddConstraint(NSLayoutConstraint.Create(InternalView, NSLayoutAttribute.Right, NSLayoutRelation.Equal, View, NSLayoutAttribute.Right, 1, 0));
View.AddConstraint(NSLayoutConstraint.Create(InternalView, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, View, NSLayoutAttribute.Bottom, 1, 0));
View.AddConstraint(NSLayoutConstraint.Create(InternalView, NSLayoutAttribute.Top, NSLayoutRelation.Equal, View, NSLayoutAttribute.Top, 1, 0));

If you have any trouble with auto layout, I suggest you ask in our forums (http://forums.xamarin.com), there are plenty of people there and you usually have answers within a day unless you ask something fairly obscure.