我遇到了设置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。可以为你节省一点努力,可重复使用的观点总是很好! –