2017-10-21 92 views
1

我从this SO question a few months ago得到了以下扩展,并且我想将其转换为NSLayoutAnchor(或更详细的布局API),原因很简单,原因是可视格式不支持指定安全区域布局指南。将约束以可视格式转换为NSLayoutAnchor API

在链路的扩展是这一个:

extension UIView { 

    /// Adds constraints to this `UIView` instances `superview` object to make sure this always has the same size as the superview. 
    /// Please note that this has no effect if its `superview` is `nil` – add this `UIView` instance as a subview before calling this. 
    func bindFrameToSuperviewBounds() { 
     guard let superview = self.superview else { 
      print("Error! `superview` was nil – call `addSubview(view: UIView)` before calling `bindFrameToSuperviewBounds()` to fix this.") 
      return 
     } 

     self.translatesAutoresizingMaskIntoConstraints = false 
     superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self])) 
     superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self])) 
    } 
} 

我的视图层次是:

的UINavigationController - >根视图控制器:UIPageViewController - >第一页:的UIViewController - >的UIScrollView - >的UIImageView

当我打电话bindFrameToSuperviewBounds(),结果如下:

enter image description here

看起来大多都很好。问题是图像视图在导航栏下,我不想要。因此,为了解决这个问题,我试图重写bindFrameToSuperviewBounds()就象这样:

guard let superview = self.superview else { 
      fatalError("Attempting to bound to a non-existing superview.") 
     } 

translatesAutoresizingMaskIntoConstraints = false 
self.topAnchor.constraint(equalTo: superview.safeAreaLayoutGuide.topAnchor).isActive = true 
self.leadingAnchor.constraint(equalTo: superview.safeAreaLayoutGuide.leadingAnchor).isActive = true 
self.bottomAnchor.constraint(equalTo: superview.safeAreaLayoutGuide.bottomAnchor).isActive = true 
self.trailingAnchor.constraint(equalTo: superview.safeAreaLayoutGuide.trailingAnchor).isActive = true 

然后将结果是:

enter image description here

这一次,它正确地不会在导航栏下去,但是,好吧...你可以看到它被拉伸,我不想要。

将视觉布局API转换为可以考虑安全区域布局指南的东西的正确方法是什么?

完成的缘故,建立滚动视图和图像视图的代码如下:

override func viewDidLoad() { 
    super.viewDidLoad() 
    imageScrollView.addSubview(imageView) 
    imageScrollView.layoutIfNeeded() 
    imageView.bindFrameToSuperviewBounds() 
    view.addSubview(imageScrollView) 
    imageView.layoutIfNeeded() 
    imageScrollView.backgroundColor = .white 
    imageScrollView.bindFrameToSuperviewBounds() 
    imageScrollView.delegate = self 
} 

回答

1

与Fattie提供的代码,我能到达此解决方案:现在

guard let superview = self.superview else { 
    fatalError("Attempting to bound to a non-existing superview.") 
} 

translatesAutoresizingMaskIntoConstraints = false 
self.topAnchor.constraint(equalTo: superview.safeAreaLayoutGuide.topAnchor).isActive = true 
self.leadingAnchor.constraint(equalTo: superview.leadingAnchor).isActive = true 
self.bottomAnchor.constraint(equalTo: superview.bottomAnchor).isActive = true 
self.trailingAnchor.constraint(equalTo: superview.trailingAnchor).isActive = true 

(即我只锚定的T适合安全的布局是指导。这是否会给iPhone X带来问题尚待观察)。

其中给出的结果我想到:

enter image description here

1

老实说,我不会与离奇的“可视化”布局的事情打扰,他们将很快消失。

这有帮助吗?

extension UIView { 

    // put this view "inside" it's superview, simply stretched all four ways 
    // amazingly useful 

    func bindEdgesToSuperview() { 

     guard let s = superview else { 
      preconditionFailure("`superview` nil in bindEdgesToSuperview") 
     } 

     translatesAutoresizingMaskIntoConstraints = false 
     leadingAnchor.constraint(equalTo: s.leadingAnchor).isActive = true 
     trailingAnchor.constraint(equalTo: s.trailingAnchor).isActive = true 
     topAnchor.constraint(equalTo: s.topAnchor).isActive = true 
     bottomAnchor.constraint(equalTo: s.bottomAnchor).isActive = true 
    } 

} 

只要使用这样的..

textOnTop = .. UILabel or whatever 
    userPhoto.addSubview(textOnTop) 
    textOnTop.bindEdgesToSuperview() 

容易!

(PS - 不要忘了,如果它是一个形象:你几乎可以肯定要设置为AspectFit,在所有情况下,所有的时间。)

安全布局引导手柄就像.. 。

.safeAreaLayoutGuide 
+0

我可能已经提到,我没有使用故事板,我写我的UI代码。我想我没有正确说出我的问题。您的示例代码可以进行翻译,但它没有考虑到安全的布局边距,因此结果与我发布的第一张照片相同。另外,考虑到许多人可以达到的问题,您应该明确地解决我提供的示例代码的所有错误。你的代码和我基本上是一样的,我尝试使用安全的布局指南。 –

+0

嗨@AndyIbanez,是的,这是我的观点。 **我知道你是用代码来做的。老实说,>>>不要使用<<<这个拙劣的视觉语言的东西。**这是完全愚蠢的,不工作,并且现在将被弃用! – Fattie

+0

哦,对不起,我没有包含'.safe .. etc'作为其中一个约束的例子。看起来像你在下面! – Fattie