自定义界面适配iOS横屏和竖屏模式

5
我试图为纵向和横向方向布置不同的用户界面。差异体现在以下几个方面:
  1. 我有一些 UIStackViews,在横向模式下它们的轴变成了水平方向,在纵向模式下变成了垂直方向,

  2. UIStackView 中按钮的顺序在两种模式下可能会不同,

  3. 一个按钮被添加到 subview1 中在横向模式下需要被删除并添加到 subview2 中,在纵向模式下 subview1 可能根本不存在,

  4. 自动布局约束在两种模式下是不同的。

我开始尝试 XCode 中的“vary for traits”,但它似乎有限制。我正在代码中手动切换约束以观察 trait 集合的更改(viewWillTransition:...),但这看起来很笨拙。是否有更好的方法,或者最好的方式是为两种模式创建重复的控件集,并隐藏在横向/纵向模式下不需要的那些?

2
最近的WWDC视频谈到了在不同“模式”下使用不同的约束条件。值得一看。具体从26:00开始观看... https://developer.apple.com/videos/play/wwdc2018/220 - DonMag
这就是我正在做的事情,但似乎还不够,特别是条件3。 - Deepak Sharma
你能分享一下这个xib文件吗? - Arun Balakrishnan
2个回答

2
如果你正确使用它,接口生成器非常强大。我不完全确定你想做什么,如果你至少分享一些截图会很有用。我假设你的每个UIStackView子视图都是一个按钮,或者它包含一个按钮,在这种情况下,我会这样做:
1. 拥有两个不同的UIStackView,一个用于横屏,另一个用于竖屏。 2. 为特征添加installed接口生成器属性的变体。因此,只有其中之一的UIStackView将被安装。 3. 对于每个UIButton,添加事件,将其连接到相应的IBActionselector。即使有两个执行相同操作的按钮,这也会起作用。 4. 因此,关于你的问题: 1. axis本身不会改变,但这将起作用,因为有两个版本的UIStackView。 2. 你可以选择在每个UIStackView上排列按钮。 3. 只需在每个UIStackView上添加按钮。 4. 根据你正在处理的UIStackView设置约束条件。
我漏掉了什么吗?请更新你的问题,提供更多信息,以便人们能够更好地帮助你。

1
我也做了同样的事情,但问题是每次代码中都需要管理两个UIButtons或UIStackViews。 - Deepak Sharma
你可以添加一个方法,根据设备的旋转(或是否连接到父视图),返回活动的 UIButtonUIStackView,这样你的代码将更加稳定和清晰,避免重复相同的操作。 - Fantini

1
我所做的是观察UIDevice.orientationDidChangeNotification并更新必要的约束条件以实现不同的布局,就像您已经实现的那样。我认为这是解决问题的更好方法,从未尝试过或甚至考虑为每个方向创建不同的视图 ‍♂️满足以下条件:
  • 第一个条件只需要相应地设置axis属性。
  • arrangedSubviews的顺序是设计的一部分,因此如果开发人员需要,他/她可以手动重新排列它们。
  • 在这部分中,我将执行您所说的操作:将按钮removeFromSuperview()并从一个子视图addSubview(view:)移动到另一个子视图。
  • 只要我们激活一个方向的约束条件并停用其他方向的约束条件,系统就会自动进行更新UI,没有任何问题。

最重要的是确保在删除子视图时,任何与其相关联的约束条件都被删除,否则应用程序将崩溃。


现在我对removeFromSuperView()和addSubview有一个问题,那就是如何在Storyboard中为两种模式定义约束条件?为了为纵向模式定义约束条件,我需要先将视图从父视图中拉出,并将其添加到另一个子视图中,以适应Compact WidthxRegular Height trait collection。但这在vary for traits中是不允许的。唯一剩下的选择是在两种模式下以编程方式定义约束条件。 - Deepak Sharma
我尽量避免使用Interface Builder,因为在将模型与代码链接时我的大脑会崩溃。很抱歉,我们必须等待IB中的超级英雄。但是对于编程方式:您只需要为一个方向创建Storyboard,另一个方向通过代码创建即可。可以在WWDC视频的约30:00处看到一个很好的例子,但是我们需要观察UIDevice.current.orientation.isLandscape而不是traitCollections,并相应地停用或启用约束。 - Ángel Téllez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接