2017-10-21 114 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

相關問題