繁体   English   中英

景观方向的不同视图/布局

[英]Different View/Layout for Landscape Orientation

我正在构建一个计算器应用程序并让它在纵向模式下工作。 但是,我希望用户在切换到横向模式时有更多选项/功能。 换句话说,整个布局必须改变,因为与纵向模式相比,横向模式会有更多的按钮。

我已经使用属性检查器下的installed属性设法做到了这一点。 以下是我遇到的问题:

  1. 当我以纵向模式运行应用程序并将其旋转为横向时,我将显示按钮,但它们是重叠的。 这是一个演示(只需等待 gif 重新启动):

在此处输入图片说明

  1. 当我在横向模式下运行应用程序时,它会正确显示所有按钮,但是一旦我再次将其旋转为纵向然后再旋转回横向,就会发生与 #1 相同的问题。 这是一个演示(只需等待 gif 重新启动):

在此处输入图片说明

我究竟做错了什么? 我该如何解决这个问题?

这是我自 iOS9 以来一直在做的事情。 完整代码,您使用的IB承担(其实我觉得你不应该),并应帮助你自动布局是如何工作的。 当心,这确实需要一些自动布局和 Swift 的知识。 这也涉及一个非常简单的UIButton示例。

首先,声明两个约束数组,通常在视图控制器中:

var landscape = [NSLayoutConstraint]()
var portrait = [NSLayoutConstraint]()
var myButton = UIButton()

接下来,设置常量约束并设置活动:

myButton.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(myButton)
myButton.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 10).isActive = true
myButton.heightAnchor.constraint(equalToConstant: 40).isActive = true
myButton.widthAnchor.constraint(equalToConstant: 200).isActive = true

到现在为止还挺好。 您已经创建了一个按钮,将其添加到 VC 视图中,并声明其大小为 40x200。 您还声明它锚定到父级的safeAreaLayoutGuide顶部锚点。

现在,是时候发挥“魔法”了。 您希望根据方向将此UIButton从底部向右移动。 (请注意,虽然某些覆盖可以在 iPhone 上运行,但在全屏时 iPad 将始终具有“常规”尺寸类别 - 全屏 - 无论方向如何!)

您需要做的第一件事是将剩余的约束放入您声明的数组中。

portrait.append(myButton.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 10))
landscape.append(myButton.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -10))

现在您需要激活单个约束。 可以更多,记住我们说的是数组。 这很简单,只需根据需要停用和激活:

func changeConstraints() {
    if isInPortrait {
        NSLayoutConstraint.deactivate(landscape)
        NSLayoutConstraint.activate(portrait)
    } else {
        NSLayoutConstraint.deactivate(portrait)
        NSLayoutConstraint.activate(landscape)
    }
}

您甚至可以根据自己的意愿为事物设置动画! 最后,让我们进入 VC 生命周期。 确定还有其他(和更好的)方法,但请记住我之前提到的 - 在全屏模式下,iPad 将始终具有常规尺寸等级。 所以我更喜欢深入挖掘。 我倾向于使用三个变量——你可能需要的更少。

var initialOrientation = true
var isInPortrait = false
var orientationDidChange = false

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    if initialOrientation {
        initialOrientation = false
        if view.frame.width > view.frame.height {
            isInPortrait = false
        } else {
            isInPortrait = true
        }
        changeConstraints()
    } else {
        if view.orientationHasChanged(&isInPortrait) {
            changeConstraints()
        }
    }
}

我也有UIView的扩展:

extension UIView {
    func orientationHasChanged(_ isInPortrait:inout Bool) -> Bool {
        if self.frame.width > self.frame.height {
            if isInPortrait {
                isInPortrait = false
                return true
            }
        } else {
            if !isInPortrait {
                isInPortrait = true
                return true
            }
        }
        return false
    }
}

我认为这应该描述我的大部分代码。 基本上,(a)使用UIDevice或 (b) 使用viewWillTransition(toSize:)并在使用 iPad 时检查大小类。 (它们有一个尺寸等级变化 - 尽管根据尺寸在设备上有所不同,但仅限于在分屏模式下。至少现在!)

view willLayoutSubviews ,使用 (a) view willLayoutSubviews - 你可以使用view DidLayoutSubviews但我更喜欢尽早做事 - 然后 (b) 检查实际屏幕尺寸。

您可以在视图控制器类生命周期中使用 iOS 方向更改方法。

首先,您必须使用 stackViews 和视图 UI 对象制作所有适当的 UI。

然后,您需要使用 iOS 大小类来管理您的约束(宽度、高度、计算器 UI 按钮/视图的比率。

还要在您的视图控制器中添加此方法并管理您的视图可见性

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)

    if UIDevice.current.orientation.isLandscape {
        print("Landscape")
        // Show your additional UIs elements views for Landscape
    } else {
        print("Portrait")
        // Hide your additional UIs elements / views for Portrait
    }
}

如果您在制作 UI 尺寸方面需要任何帮助,请按照以下选项进行操作。 所以你必须使用 iOS 大小类。

  1. 您可以将约束添加到视图并在“尺寸检查器”中进行编辑。
  2. 双击适当的设置约束并使用标签前的 + 按钮添加更多所需的尺寸类。
  3. 确保取消选中“已安装”复选框并分别选中所选约束(纵向模式的约束)所需的尺寸(wC、hC / wR、hR / wC、hR / wR、hC)。
  4. 也为横向模式的 UI 添加新的约束,并执行与上述 no 相同的操作。 3 通过仅检查 iPhone 横向模式的尺寸等级。

请在此处查看 Xcode 中的检查选项

有用的网址:

https://medium.com/swlh/ios-adaptive-layout-i-size-class-c561bd730e1 https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/adaptivity-and -布局/

我为您制作了一个示例工作并添加到我的 GitHub 存储库中。

请查看 main.storyboard UI 设置并完成您的工作。

回购: https : //github.com/ryra-circuit/DynamicUICalculator

iPhone 11 人像

iPhone 11 横向

iPhone SE Gen 1 肖像

iPhone SE Gen 1 横向

谢谢

暂无
暂无

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

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