2015-12-10 48 views
0

我遇到了設置UIViews的問題。UIView的框架被隨機覆蓋

形勢

我有,我會添加一些細節視圖的視圖。這些細節視圖按順序排列,非常類似於UITableView的行。這實際上是一個很好的比較。不同之處在於,在這個視圖中,我們不是上下滾動,而是橫向滾動。

在這些細節視圖中,屏幕上總是隻有一個。當我添加第一個屏幕時,我也加載下一個(向右)並將其從屏幕上拉出(再次,向右)。當用戶點擊一個按鈕時,我們用小動畫前進到下一個視圖。最後一個可見視圖向左滑動,右側從第二個視圖進入。此時,我保留對現在剩下的視圖的引用,並加載新的右側視圖(如果有的話)。我創建了一個協議,使任何其他對象成爲我稱爲SlidableDetailViewControllerSDVC)的數據源。

目前,我在數據源的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 
     } 
    } 
} 

謝謝您!

+1

您能否提供一個用於設置這些框架並在它們之間移動的代碼示例?此外,如果這樣做有意義,則可以使用帶有標準流佈局的集合視圖來進行側向滾動視圖。 –

+0

當然,請查看更新後的帖子。實際上,使用'UICollectionView'的想法從來沒有超越我的想法,因爲我基本上認爲它們是一個網格視圖,它不會讓它自己以線性,從左到右的方式使用它。如果是這樣,這可能是擺脫我的許多代碼的好方法。我必須考慮這一點。謝謝你的提示! – flohei

+1

謝謝,是的,UICollectionViewFlowLayout實際上適合線性的從左到右的滾動視圖。您可以將佈局上的滾動方向設置爲.Horizo​​ntal。可以爲你節省一點努力,可重複使用的觀點總是很好! –

回答

0

我能夠使用roboff mayoff建議的普通UIPageViewController來解決這個問題。