【问题标题】:iOS 9 Autolayout: A centered square [duplicate]iOS 9 Autolayout:一个居中的正方形[重复]
【发布时间】:2016-01-15 15:59:45
【问题描述】:

这看起来应该比现在更容易。

我试图在任何 iOS 设备中以 1:1(正方形)的纵横比将 UIView 居中,无论方向如何。

详情: 我的视图有一个在 timeInterval 上更新的平局。我使用全屏视图并在每次绘制时计算我的正方形。在方向改变时,整个视图都变成了地狱。我假设如果视图是方形的,我可以相信方向改变动画。

我的约束反复失败,这就是为什么这看起来应该更容易:

View (Square)
    Constraints
        aspect 1:1
Constraints
    View.centerX = centerX
    View.centerY = centerY
    View.leading ≥ leadingMargin + 5 @ 800
    View.top ≥ Top Layout Guide.bottom + 5 @ 800
    trailingMargin ≥ View.trailing + 5 @ 800
    Bottom Layout Guide.top ≥ View.bottom + 5 @ 800

我的内容拥抱优先级为 250
我的内容抗压性为 750

这会留下约束错误:
- 缺少约束:需要约束:X 位置或宽度
- 缺少约束:需要约束:Y 位置或高度

我的困惑是我无法锁定一个维度,因为在旋转时我需要锁定另一个维度。

如前所述...这似乎应该更容易。 将边框为 5 的 Square UIView 居中在较细的尺寸上。
(纵向 5 到侧面,横向 5 到顶部和底部)

非常感谢您的建议,解释将无济于事。

【问题讨论】:

  • 您希望正方形在仍然是正方形的同时具有最大可用尺寸吗?然后居中?
  • 您是否有可行的解决方案并正在寻找更简单的版本,或者您是否需要任何可行的解决方案?
  • 我的解决方案不起作用,因为当我旋转时视图消失并且 IB 抱怨缺少约束
  • 好的,我正在试验一个仅限 IB 的解决方案,这可能是您最想要的!?这绝对不是一件小事
  • 我发现不乏琐碎。

标签: ios autolayout interface-builder constraints ios9


【解决方案1】:

方块需要指定它的大小。

Square centerX = Parent centerX
Square centerY = Parent centerY

此时,视图居中,但没有什么可以让自动布局决定视图的大小。

Square width = 200
Square aspect = 1

如果您希望正方形成为父级宽度的一部分,这也很简单。

Square width = Parent width * 0.5 //or any other multiplier

您需要根据您希望正方形在横向中的显示方式来调整宽度限制。

要拥有“可能的最大正方形”,您可以通过编程将宽度约束设置为min(parentWidth, parentHeight) 并调整方向。

或者,leading, trailing, centerX, centerY, and aspect 应该会得到类似的结果。任何一组约束都需要能够在逻辑上确定位置和大小,而不会产生歧义。

更新
在 IB 中:

 Square centerX = Parent centerX
 Square centerY = Parent centerY
 Square aspect = 1

在代码中:

 if parent width > parent height
 Square width = parent height - 2 * margin

 else
 Square width = parent width - 2 * margin

在旋转时调整它

【讨论】:

  • Stefan,你能澄清一下这是在 IB 约束中还是在代码中完成的。为了清楚起见,我已经编辑了上面的内容。
  • @LordAndrei 我更新了我的答案。对我来说最明显的解决方案是将简单和固定的约束放在 IB 中,并在代码中为可以改变/棘手的东西添加一个约束,即正方形的宽度。可能还有很多其他方法可以做到这一点,但这似乎是最明显的。
  • 需要注意的是,IB 将显示该视图的错误,因为没有定义宽度/高度。没关系;您将以编程方式添加缺少的约束。或者您可以在 IB 中添加肖像约束并在旋转时对其进行调整以消除编辑 xib/storyboard 时出现的错误。
  • 占位符约束?
  • @LordAndrei 不,不是占位符约束,而是作为出口连接到源代码并根据需要更改的约束。
【解决方案2】:

这是我刚刚汇总的一种方法。我无法在 IB 中完全做到这一点,但至少运行时代码仅限于激活/停用约束,而不必添加/删除或计算/更改任何大小。

在我的故事板中,我有一个带有以下约束的内部 UIView

  • 中心 X
  • Y 中心
  • 超级视图的前导空间 = 5,优先级 = 999
  • 到超级视图的尾随空格 = 5,优先级 = 999
  • 超级视图的顶部空间=5,优先级=1000
  • 到superview的底部空间=5,优先级=1000

我为最后四个约束创建了 IBOutlets,这是我的视图控制器 -

class ViewController: UIViewController {

    @IBOutlet var leadingConstraint: NSLayoutConstraint!
    @IBOutlet var trailingConstraint: NSLayoutConstraint!
    @IBOutlet var topConstraint: NSLayoutConstraint!
    @IBOutlet var bottomConstraint: NSLayoutConstraint!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        self.setConstraintsForSize(self.view.frame.size)
    } 

    override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
        self.setConstraintsForSize(size)
    }

    func setConstraintsForSize(size:CGSize) {
        if (size.width > size.height) {
            self.leadingConstraint.active=false;
            self.trailingConstraint.active=false;
            self.topConstraint.active=true;
            self.bottomConstraint.active=true;
        } else {
            self.leadingConstraint.active=true;
            self.trailingConstraint.active=true;
            self.topConstraint.active=false;
            self.bottomConstraint.active=false;
        }
    }  
}

这适用于 iPhone 和 iPad,包括处于窗口/分屏模式的 iPad

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-16
    • 2011-11-04
    • 2017-05-22
    • 1970-01-01
    • 2020-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多