简体   繁体   English

具有VFL约束的iOS动态自动布局

[英]iOS Dynamic Autolayout with VFL Constraints

I experience an unexpected behavior when attempting to assign constraints dynamically in a single view controller based on device orientation. 尝试基于设备方向在单个视图控制器中动态分配约束时遇到意外行为。

Desired behavior: As shown in the code below I am using VFL to attach a view to the right, top and left edges of the superview with a height of 300 of when in portrait mode and then switch to having the same view attached to the left and top edge with a height of 90 and width of 160 when in landscape mode. 所需的行为:如下面的代码所示,在纵向模式下,我正在使用VFL将视图附加到视图的右,上,左边缘,高度为300,然后切换到左侧附加相同的视图在横向模式下,顶部边缘的高度为90,宽度为160。

if (orientation == UIInterfaceOrientation.Portrait || orientation == UIInterfaceOrientation.PortraitUpsideDown)
{
    View.AddConstraints(NSLayoutConstraint.FromVisualFormat("V:|[green(300)]", 0, metrics, views));
    View.AddConstraints(NSLayoutConstraint.FromVisualFormat("H:|[green]|", 0, new NSDictionary(), views));
} 
else
{
    View.AddConstraints(NSLayoutConstraint.FromVisualFormat("V:|[green(90)]", 0, metrics, views));
    View.AddConstraints(NSLayoutConstraint.FromVisualFormat("H:|[green(160)]", 0, metrics, views));
}  

Experienced Behavior: We are instead seeing the desired behavior for the portrait mode on the initial load of the view and also when turned to landscape mode. 体验的行为:在视图的初始加载时以及转向横向模式时,我们看到的是纵向模式的期望行为。 However, when turing back to portrait mode the view control disappears each time thereafter when the device is turned to portent mode but landscape mode continues to function. 但是,当重新回到纵向模式时,此后每次将设备切换到便携模式但横向模式继续起作用时,视图控件都会消失。 In short portrait mode only works the first time. 在短人像模式下,仅首次使用。

I've done quite extensive research and could not identify the problem. 我已经进行了广泛的研究,无法确定问题所在。 I would be very appreciative of any insight towards a solution. 对于解决方案的任何见解,我将不胜感激。

Here is the complete code just in case: 这是完整的代码,以防万一:

using MonoTouch.Foundation;
using MonoTouch.UIKit;
using System;
using System.CodeDom.Compiler;

namespace iOS.UI
{
    partial class TestConstraintsController : UIViewController
    {
        public TestConstraintsController (IntPtr handle) : base (handle)
        {

        }

        public override void ViewWillAppear (bool animated)
        {
            base.ViewWillAppear (animated);
            AdjustGeometry ();
        }


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

        public void AdjustGeometry()
        {
            UIInterfaceOrientation orientation = UIApplication.SharedApplication.StatusBarOrientation;

            NSDictionary views = NSDictionary.FromObjectsAndKeys (
                                                new NSObject[] { greenBox }, 
                                                new NSObject[] { new NSString ("green") }
                                            );

            View.RemoveConstraints (View.Constraints);

            if (orientation == UIInterfaceOrientation.Portrait || orientation == UIInterfaceOrientation.PortraitUpsideDown)
            {
                View.AddConstraints(NSLayoutConstraint.FromVisualFormat("V:|[green(boxHeightPortrait)]", 0, new NSDictionary(), views));
                View.AddConstraints(NSLayoutConstraint.FromVisualFormat("H:|[green]|", 0, new NSDictionary(), views));
            } 
            else
            {
                View.AddConstraints(NSLayoutConstraint.FromVisualFormat("V:|[green(90)]", 0, new NSDictionary(), views));
                View.AddConstraints(NSLayoutConstraint.FromVisualFormat("H:|[green(160)]", 0, new NSDictionary(), views));
            }
        }
    }
}

The issue is that you're removing constraints that you didn't create that are helping the view controllers view to lay itself and subviews out. 问题在于,您正在删除未创建的约束,这些约束正在帮助视图控制器视图进行自我布局和子视图布局。

Instead of removing all of the constraints from your view, just remove the ones you created (save the arrays of constraints that are are returned from FromVisualFormat ). 无需从视图中删除所有约束,只需删除创建的约束(保存从FromVisualFormat返回的约束数组)。

Specifically, there are constraints being added to the view controllers view that control its height (in the auto layout engine) based on its autoresizing mask. 具体来说,在视图控制器视图中添加了一些约束,这些约束基于其自动调整大小蒙版来控制其高度(在自动布局引擎中)。 When these are deleted its causing your view controller to have a height of zero when it comes to auto layout (though it draws fine since it's still being drawn based on its autoresizing mask). 删除这些元素后,自动布局时会导致视图控制器的高度为零(尽管它可以很好地绘制,因为仍会根据其自动调整大小蒙版对其进行绘制)。 So when your subview is trying to fill the entire vertical space, it's just filling a vertical height of 0. 因此,当您的子视图试图填充整个垂直空间时,它只是填充了垂直高度0。

If you want to see the difference, just log the contents of your views constraints array before you clear it each time. 如果要查看差异,只需在每次清除它之前记录视图约束数组的内容即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM