【问题标题】:UIView cropped off even though constraints are set即使设置了约束,UIView 也会被裁剪掉
【发布时间】:2015-12-28 16:37:43
【问题描述】:

我在 xib 文件中创建了一个自定义视图,其中我将所有模拟指标设置为“推断”

在我看来,我通过固定左侧和顶部将堆栈视图 x 浮动到左侧,并通过固定右侧和顶部将堆栈视图浮动到右侧。不知何故像这样(= 符号象征着屏幕边框)

==========
=x      y=
=        =
=        =
=        =
=        = 
==========

我没有为宽度和高度设置任何约束,因为一切都应该被推断出来。

我的观点对应的类很简单:

class MyView: UIView {

    var view:UIView!
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        view = UIView.loadFromNibNamed("MyView")
        addSubview(view)
    }
}
extension UIView {

    class func loadFromNibNamed(nibNamed: String, bundle : NSBundle? = nil) -> UIView? {
        return UINib(
            nibName: nibNamed,
            bundle: bundle
            ).instantiateWithOwner(nil, options: nil)[0] as? UIView
    }

}

我在故事板中使用此视图,将其固定在左侧、右侧、顶部和底部。 .

问题是视图是从笔尖加载的,但宽度在某种程度上不是动态的。我希望视图根据父级的大小调整自身的大小。但是,即使我设置了约束,右侧 Stack View 的大约 1/3 被裁剪掉并且在屏幕上不可见。

我该怎么做才能解决这个问题?

【问题讨论】:

    标签: swift uiview autolayout nslayoutconstraint


    【解决方案1】:

    如果您希望从 XIB 加载的任何视图具有动态帧大小,则需要将 translatesAutoresizingMaskIntoConstraints 属性设置为 false。否则系统将自动创建布局约束,例如固定宽度和固定高度,以防止您的视图调整大小。

    此外,在将视图添加到视图层次结构后,您需要在代码中添加一些约束,将其顶部、底部、左侧和右侧边缘固定到其父视图的相应边缘。毕竟,您将 XIB 的内容作为子视图添加到您的自定义视图 MyView 即两个视图不相同,您需要告诉系统它应该如何定位子视图(您在情节提要中添加的约束仅与您的 MyView 实例相关,而不是与其子视图相关)。这些添加到您的代码中应该可以解决问题:

    class MyView: UIView {
    
        var view:UIView!
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
    
            view = UIView.loadFromNibNamed("MyView")
            view.translatesAutoresizingMaskIntoConstraints = false
            addSubview(view)
    
            // Pin view to all four edges of its superview
            self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[view]|", options: [], metrics: nil, views: ["view": view]))
            self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[view]|", options: [], metrics: nil, views: ["view": view]))
    
        }
    }
    

    旁注:

    • 阅读official documentation 中有关translatesAutoresizingMaskIntoConstraints 属性的更详细说明。
    • Interface Builder 中“模拟指标”部分的所有设置仅适用于 Interface Builder 本身。当您在模拟器或真实设备上运行应用时,它们不会对您的应用产生任何影响。

    【讨论】:

    • 感谢您提供非常好的解释和链接,Mischa。我唯一需要更改的是将约束添加到 self(即父视图),否则我们会收到“未准备好约束”错误。
    • 你说的没错,当然。不幸的是,我无法接受您的编辑建议,因为它已经被其他一些同行评审员拒绝了,所以我自己进行了编辑。我很高兴它成功了!
    【解决方案2】:
    1. 我们需要确定问题所在,所以让我们首先确认堆栈视图正在获取其框架的设置。在堆栈视图所在的视图控制器中,我们可以覆盖 following methods 并检查堆栈视图的帧。

        viewWillLayoyutSubviews()
        viewDidLayoutSubviews()
      
    2. 确认框架正在设置,我们现在可以查看在情节提要中设置的约束。您提供的信息不干净,您希望如何将堆栈视图布局在一起,是一个在另一个视图之上吗?他们应该并排吗?

      您需要检查约束对于您想要的布局是否有效。

    3.确认您的视图的尺寸等级配置正确。 Apple 在这里有一个名为“Size Classes Design Help”的文档。我相信这是你的问题。您的自定义类设置为具有 Any/Any 的大小类,并且自定义视图的超级视图具有一组不同的大小类,例如 Compact/Regular。因此,您的自定义视图不会根据尺寸类别调整其尺寸,因为对于尺寸类别的任何组合,它都设置为相同。尝试为您的自定义类配置不同大小的类组合,以查看是否有任何差异 - 例如 Compact/Regular。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-11
      • 1970-01-01
      • 2020-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多