我遇到了設置UIViews
的問題。UIView的框架被隨機覆蓋
形勢
我有,我會添加一些細節視圖的視圖。這些細節視圖按順序排列,非常類似於UITableView
的行。這實際上是一個很好的比較。不同之處在於,在這個視圖中,我們不是上下滾動,而是橫向滾動。
在這些細節視圖中,屏幕上總是隻有一個。當我添加第一個屏幕時,我也加載下一個(向右)並將其從屏幕上拉出(再次,向右)。當用戶點擊一個按鈕時,我們用小動畫前進到下一個視圖。最後一個可見視圖向左滑動,右側從第二個視圖進入。此時,我保留對現在剩下的視圖的引用,並加載新的右側視圖(如果有的話)。我創建了一個協議,使任何其他對象成爲我稱爲SlidableDetailViewController
(SDVC
)的數據源。
目前,我在數據源的didSet
期間配置了詳細視圖。在此設置過程中,它會生成這三個幀(再次,左側,中間和右側)。
問題
當視圖加載並第一次出現在屏幕上,中心視圖的框架是不應該的,但方式更小。第二個詳細視圖將正確顯示。當我回到第一個框架時,框架也會更新並更正。
當我調試它時,幀的計算和設置都是正確的。當我在viewWillAppear(_:)
中休息時,即使視圖的框架是我所期望的。當我在viewDidAppear(_:)
中做同樣的事情時,它已經縮小到沒有人想要的奇怪大小。我沒有做任何事情;我只是用它們來調試代碼。
有沒有人看到我在做什麼錯在這裏?
我很確定這只是我最後的愚蠢錯誤,但我現在無法弄清楚。
更新代碼示例
計算框架:
private func calculateFrames() {
// Get the size for our views from the dataSource.
let detailViewSize: CGSize
if let theDataSource = dataSource {
detailViewSize = theDataSource.detailViewSize()
} else {
// Just use a few default values.
detailViewSize = CGSizeMake(320, 185)
}
// Calculate the frame for on screen display.
let detailFrameX = (view.frame.width - detailViewSize.width)/2
let detailFrameY = (view.frame.height/2 - detailViewSize.height/2)
centerFrame = CGRectMake(detailFrameX, detailFrameY, detailViewSize.width, detailViewSize.height)
// The other two frames are basically just offsets of the original centerFrame.
leftFrame = centerFrame?.offsetBy(dx: (detailViewOffset * -1), dy: 0.0)
rightFrame = centerFrame?.offsetBy(dx: detailViewOffset, dy: 0.0)
}
加載下一個視圖(加載一個視圖的工作幾乎相同的方式):
func showNextDetailView() {
// 1. If we're at the last item, we can't advance.
if selectedIndex == detailsCount() - 1 {
return
}
// 2. Check if there is a view on the left spot
if leftView != nil {
// 2.1. … if so, remove it from superView.
leftView?.removeFromSuperview()
}
UIView.animateWithDuration(animationDuration, delay: 0.0, options: .CurveEaseInOut, animations: {() -> Void in
// 3. Set the frame of the view at selectedIndex to leftFrame.
self.centerView?.frame = self.leftFrame!
// 4. Set the frame of the view at selectedIndex + 1 to center frame.
self.rightView?.frame = self.centerFrame!
}) { (finished) -> Void in
print("animation to next detail view finished")
}
// 5. Increase the selectedIndex
selectedIndex++
// Store the new positions for quick reference.
if let theDataSource = dataSource {
if let newLeftView = theDataSource.detailViewAtIndex(selectedIndex - 1) {
leftView = newLeftView
}
if let newCenterView = theDataSource.detailViewAtIndex(selectedIndex) {
centerView = newCenterView
}
// 6. Check if we have more views left
if detailsCount() - 1 > selectedIndex {
// 6.1 … and if so, add a new one to the right.
rightView = theDataSource.detailViewAtIndex(selectedIndex + 1)
rightView?.frame = rightFrame!
contentView.addSubview(rightView!)
} else {
rightView = nil
}
}
}
謝謝您!
您能否提供一個用於設置這些框架並在它們之間移動的代碼示例?此外,如果這樣做有意義,則可以使用帶有標準流佈局的集合視圖來進行側向滾動視圖。 –
當然,請查看更新後的帖子。實際上,使用'UICollectionView'的想法從來沒有超越我的想法,因爲我基本上認爲它們是一個網格視圖,它不會讓它自己以線性,從左到右的方式使用它。如果是這樣,這可能是擺脫我的許多代碼的好方法。我必須考慮這一點。謝謝你的提示! – flohei
謝謝,是的,UICollectionViewFlowLayout實際上適合線性的從左到右的滾動視圖。您可以將佈局上的滾動方向設置爲.Horizontal。可以爲你節省一點努力,可重複使用的觀點總是很好! –