2015-12-10 49 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来解决这个问题。