我如何与自动布局自转时,重新排列的意见? [英] How can I rearrange views when autorotating with autolayout?

查看:119
本文介绍了我如何与自动布局自转时,重新排列的意见?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经常遇到这个问题,我想安排在一个方式为纵向,横向有点截然不同的方式我的看法。

I frequently run into this problem where I want my views arranged in one manner for portrait and a somewhat drastically different manner for landscape.

有关一个简单的例子,考虑以下几点:

For a simplified example, consider the following:

请注意,在肖像图像被垂直堆叠,而在横向上,他们是并排侧

Notice how in portrait the images are stacked vertically, but in landscape, they are side-by-side?

当然,我可以手动计算的位置和大小,但是对于比较复杂的观点,这很快变得复杂。另外,我想preFER使用自动布局所以有较少的设备专用code(如有的话)。但是,这似乎是一个的自动布局code的大量的写作。有没有办法做到通过故事板设立这类东西的约束?

Of course, I can manually calculate the positions and sizes, but for more complicated views, this quickly becomes complex. Plus, I'd prefer to use Autolayout so there's less device-specific code (if any at all). But that seems like a lot of Autolayout code to write. Is there a way to do set up the constraints for this sort of stuff through the storyboard?

推荐答案

有X code'S界面构建两个未充分利用的功能,我们可以利用这里做完全这样的事情一个同步。

There are two underused features of Xcode's interface builder we can make use of here to make exactly this sort of thing a synch.


  1. 您可以创建 NSLayoutConstraints IBOutlet中连接。

  2. 您可以连接插座收藏,这是 IBOutlet中对象的数组。

  1. You can create IBOutlet connections for NSLayoutConstraints.
  2. You can hook up "outlet collections", which is an array of IBOutlet objects.

所以,在考虑这两个东西,什么,我们想要做的要点是创造了我们所有的自动布局约束一个方向,一个出口集合中勾他们都放弃了。现在,对于每个约束,取消接口生成器已安装选项。然后,让我们所有的另一个布局的出口集合,和钩它们备份到另一个插座集合。我们可以创建许多布局团体,因为我们想要的。

So with these two things in mind, the gist of what we want to do is create all of our autolayout constraints for one orientation, hook them all up in an outlet collection. Now, for each of these constraints, uncheck the "Installed" option on interface builder. Then make all of our outlet collections for another layout, and hook them up to another outlet collection. We can create as many of these layout groups as we want.

要注意的是,我们需要有直接安装在其上的限制任何UI元素的引用,这一点很重要,我们需要一个单独的出口集不只是因为我们希望每个布局,但对于具有约束每个UI对象安装它直接。

It's important to note that we will need a reference to any UI element which has constraints installed on it directly, and we will need a seperate outlet collection not just for each layout we want, but for each UI object which has constraints installed on it directly.

让我们来看看从你的问题还算简单的例子。

Let's take a look at the fairly simplified example from your question.

如果您在限制名单看左边,你可以看到一半的人都变灰。变灰的约束是景观约束。我创造了所有这些,然后选中安装为他们每个人的:

If you look in the constraints list on the left, you can see half of them are grayed-out. The grayed-out constraints are the landscape constraints. I created all of these, then unchecked "Installed" for each of them:

同时,ungrayed,正常寻找约束是所述肖像的约束。对于这些,我就离开他们安装。这是完全没有必要离开其中任何安装,但如果你把安装了多套你会遇到的问题(他们最有可能发生冲突)。

Meanwhile, the ungrayed, normal looking constraints are the portrait constraints. For these, I left them "Installed". It's completely unnecessary to leave any of them installed, but you will run into problems if you leave multiple sets installed (they most likely conflict).

确保不检查任何这些在构建时删除。我们不想限制去掉在构建时。这仅仅意味着在所有未创建约束(所以我们会失去对它的引用)。如果我们把这个标记,同时检查我们有一个 IBOutlet中来约束,X code会产生一个警告:

Be sure not to check "Remove at build time" for any of these. We don't want the constraints "removed" at build time. This simply means the constraint isn't created at all (so we'll lose the reference to it). If we leave this check marked while we have an IBOutlet to the constraint, Xcode will generate a warning:

配置不受支持
连接到占位符约束。标记为IB占位符约束不应该有任何联系,因为这些限制不会被编译到该文件,并在运行时将不存在。

Unsupported Configuration
Connection to placeholder constraint. Constraints marked as placeholders in IB should not have any connections since these constraints are not compiled into the document and will not exist at runtime.

不管怎样,现在我们需要将限制挂钩到一个出口,所以我们可以在运行时访问它们。

Anyway, so now we need to hook up the constraints to an outlet so we can access them at run time.

按住<大骨节病>控制点击并拖动从制约因素之一到源$ C ​​$ C文件,就像你连接任何其他UI元素。在弹出的对话框中,选择出口收集和描述性名称:

Hold Ctrl and click and drag from one of the constraints to your source code file, just as you would connect any other UI element. On the dialog that pops up, choose Outlet Collection and a descriptive name:

现在挂钩这一切约束小组赛到同一个插座集合其他约束:

Now hook up all of the other constraints that match that constraint group into the same outlet collection:

一旦我们完成挂钩,我们所有的限制,它只是一个删除/在适当的时候将他们的问题。

Once we've finished hooking up all of our constraints, it's just a matter of removing/adding them at the appropriate time.

对于这样一个简单的例子作为问题描述的场景中,我们可以覆盖 updateViewConstraints 一些code是这样的:

For such a simple example as the scenario described in the question, we can override updateViewConstraints with some code like this:

class ViewController: UIViewController {
    @IBOutlet var landscapeConstraints: [NSLayoutConstraint]!
    @IBOutlet var portraitConstraints: [NSLayoutConstraint]!

    override func updateViewConstraints() {
        let isPortrait = self.view.bounds.width < self.view.bounds.height

        self.view.removeConstraints(self.portraitConstraints)
        self.view.removeConstraints(self.landscapeConstraints)
        self.view.addConstraints(isPortrait ? self.portraitConstraints : self.landscapeConstraints)

        super.updateViewConstraints()
    }
}

的Objective-C

@interface ViewController()

@property (strong, nonatomic) IBOutletCollection(NSLayoutConstraint) NSArray *landscapeConstraints;
@property (strong, nonatomic) IBOutletCollection(NSLayoutConstraint) NSArray *portraitConstraints;

@end

@implementation ViewController

- (void)updateViewConstraints {
    BOOL isPortrait = self.view.bounds.size.width < self.view.boudns.size.height;

    [self.view removeConstraints:self.portraitConstraints];
    [self.view removeConstraints:self.landscapeConstraints];
    [self.view addConstraints:(isPortrait ? self.portraitConstraints : self.landscapeConstraints)];

    [super updateViewConstraints];
}

@end

我们没有检查哪些设置的限制视图previously过的,所以只要删除这两个我们的约束集,然后添加我们要使用适当的设置。

We're not checking which set of constraints the view previously had, so just remove both of our constraint sets, and then add the appropriate set we want to use.

这是所有code,我们需要管理彻底改变了一整套约束的在运行时的对象上。这允许在界面生成器来设置我们所有的约束了,而不必以编程方式(我觉得这一点比较繁琐且容易出错)。

This is all the code we need to manage completely changing out an entire set of constraints on an object at run time. This allows to work in the interface builder to set all of our constraints up instead of having to do it programmatically (which I find a little more tedious and error-prone).

最终的结果?非常漂亮的自转不重排拉你的头发,获得自动版式code完全可以做到的:

The end result? Very nice looking autorotation rearrangement without pulling your hair out getting the autolayout code done perfectly:

这篇关于我如何与自动布局自转时,重新排列的意见?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆