2016-09-19 29 views
9

我在UIScrollView上遇到了一個問題,該問題似乎是iOS10特有的。我似乎在滾動視圖的頂部和內部的內容視圖之間存在差距,這應該會卡在頂部。iOS10 UIScrollView頂端的差距

在iOS 9上似乎沒有任何差距,但在iOS 10上出現了差距。
需要說明的是,在這兩種情況下,滾動視圖頂部都固定在頂部佈局指南的底部,該指南完美地與導航欄的底部對齊。 iOS 10引入了滾動視圖頂部和內容視圖頂部之間的導航欄大小的差距。

我可以將滾動視圖的頂部對齊到頂部佈局指南的頂部,這會將導航欄下方的間隙與內容視圖排成一行,但在iOS 9上,內容視圖將位於下方導航欄是不可取的。

我已經快速創建了一些演示以下問題的操場代碼。有什麼明顯的我失蹤了嗎?在iOS 10中改變了這個問題,我該如何解決這個問題?

comparison of screenshots from iPhone 5s simulator

import UIKit 
import PlaygroundSupport 

class TestViewController: UIViewController { 
    var mainScrollView: UIScrollView 
    var contentView: UIView 

    init() { 
     self.mainScrollView = UIScrollView() 
     self.contentView = UIView() 

     super.init(nibName: nil, bundle: nil) 

     self.view.backgroundColor = UIColor.white 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 

    override func viewDidLoad() { 
     self.mainScrollView.backgroundColor = UIColor.green 
     self.contentView.backgroundColor = UIColor.blue 

     self.mainScrollView.translatesAutoresizingMaskIntoConstraints = false 
     self.contentView.translatesAutoresizingMaskIntoConstraints = false 

     self.view.addSubview(self.mainScrollView) 
     self.mainScrollView.addSubview(self.contentView) 

     // constrain the scroll view bounds to the view 
     self.view.addConstraint(NSLayoutConstraint(item: self.mainScrollView, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal, toItem: self.topLayoutGuide, attribute: NSLayoutAttribute.bottom, multiplier: 1, constant: 0)) 
     self.view.addConstraint(NSLayoutConstraint(item: self.mainScrollView, attribute: NSLayoutAttribute.bottom, relatedBy: NSLayoutRelation.equal, toItem: self.bottomLayoutGuide, attribute: NSLayoutAttribute.top, multiplier: 1, constant: 0)) 
     self.view.addConstraint(NSLayoutConstraint(item: self.mainScrollView, attribute: NSLayoutAttribute.leading, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.leading, multiplier: 1, constant: 0)) 
     self.view.addConstraint(NSLayoutConstraint(item: self.mainScrollView, attribute: NSLayoutAttribute.trailing, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.trailing, multiplier: 1, constant: 0)) 

     // constrain the content view bounds to the scroll view 
     self.mainScrollView.addConstraint(NSLayoutConstraint(item: self.contentView, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal, toItem: self.mainScrollView, attribute: NSLayoutAttribute.top, multiplier: 1, constant: 0)) 
     self.mainScrollView.addConstraint(NSLayoutConstraint(item: self.contentView, attribute: NSLayoutAttribute.bottom, relatedBy: NSLayoutRelation.equal, toItem: self.mainScrollView, attribute: NSLayoutAttribute.bottom, multiplier: 1, constant: 0)) 
     self.mainScrollView.addConstraint(NSLayoutConstraint(item: self.contentView, attribute: NSLayoutAttribute.leading, relatedBy: NSLayoutRelation.equal, toItem: self.mainScrollView, attribute: NSLayoutAttribute.leading, multiplier: 1, constant: 0)) 
     self.mainScrollView.addConstraint(NSLayoutConstraint(item: self.contentView, attribute: NSLayoutAttribute.trailing, relatedBy: NSLayoutRelation.equal, toItem: self.mainScrollView, attribute: NSLayoutAttribute.trailing, multiplier: 1, constant: 0)) 

     // constrain the content view's size to the view's size 
     self.view.addConstraint(NSLayoutConstraint(item: self.contentView, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.width, multiplier: 1, constant: 0)) 
     self.view.addConstraint(NSLayoutConstraint(item: self.contentView, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.greaterThanOrEqual, toItem: self.view, attribute: NSLayoutAttribute.height, multiplier: 1, constant: 0)) 
    } 
} 

let rootViewController = TestViewController() 
rootViewController.title = "Test" 

let navigationController = UINavigationController(rootViewController: rootViewController) 
PlaygroundPage.current.liveView = navigationController.view 
+0

我有同樣的問題......只發生在iOS 10.你有沒有運氣修復它? – inorganik

+0

@inorganik - 不,還沒有。現在就讓這個項目繼續下去吧。可能最終不得不放入一個操作系統版本檢查,我希望避免。 –

+0

添加了我找到答案的解決方案,希望它對您有用。 – inorganik

回答

1

在第一個約束你設置你將其設置爲topLayoutGuidebottom。因此,從Apple documentationtopLayoutGuidebottom取決於您堆疊子視圖的方式。所以在你的例子中,如果你把它設置爲

self.view.addConstraint(NSLayoutConstraint(item: self.mainScrollView, attribute: .top, relatedBy: .equal, toItem: self.topLayoutGuide, attribute: .top, multiplier: 1, constant: 0))它的工作原理。

但我經常使用我的子視圖的頂部,以便我沒有「邊距」。所以它可能看起來像:self.view.addConstraint(NSLayoutConstraint(item: self.mainScrollView, attribute: .top, relatedBy: .equal, toItem: self.view, attribute: .top, multiplier: 1, constant: 0))

希望它有幫助。

+0

我離開我的電腦,所以我不能再次檢查但我敢肯定,如果我將它設置爲頂級佈局指南的頂部,它確實可以在iOS 10上使用,但在iOS 9上,它最終位於導航欄後面,我試圖避免,這是爲什麼我沒有去調整它到超級視圖的頂部。 –

+0

只需添加到此,滾動視圖的頂部位於我希望它位於iOS 9和iOS 10上的位置:符合導航欄的底部。問題在於滾動視圖頂部與內容視圖頂部之間的差距。如果我將滾動視圖移動到頂部佈局指南的頂部,則在iOS 10上,滾動視圖的頂部位於導航欄下方,並且內容視圖與導航欄一致。在iOS 9上,內容視圖也位於導航欄下方。 –

0

我有這個相同的問題,在我的情況下爲一個UISearchController,其中視圖添加動態完成,所以我不會有機會添加約束。我只需要手動設置滾動視圖的contentInset(在我的例子中是一個表格視圖),並將其設置爲您想要的屏幕頂部的距離。對你來說,它可能看起來像這樣:

// status bar + nav bar = 64 
self.mainScrollView.contentInset = UIEdgeInsetsMake(64, 0, 0, 0); 
self.view.automaticallyAdjustsScrollViewInsets = NO; 

請注意我適應了這個從我的對象迅速。 C代碼很抱歉,如果它稍微關閉。我在iOS 9和10中進行了測試,兩者看起來都很對。