我有一个collectionView可以在缩放时进行缩放。
它是这样的:
我在collectionView上添加了一个UIPinchGestureRecognizer,当发生收缩时,我使布局无效,这迫使collectionView向委托(delegate)要求新的大小。
它运作良好。
我无法解决的问题是,在捏捏期间,我想将电池保持在同一位置。在屏幕中间的指示器下方。 (请参见屏幕截图)。
我当时想在开始捏时存储当前的scrollView偏移量,然后以新的大小重新显示单元格时,我计算宽度差并向contentOffset添加或减去。
我有一个contentInset,以便滚动collectionView中间的第一个单元格。
这是我的代码:
@objc func handlePinchGesture(gesture: UIPinchGestureRecognizer) {
if (gesture.state == .Began) {
scaleStart = metrics.scale // remember current scale
widthStart = collectionView.visibleCells()\[0\].bounds.width // get size of a cell to calulate a difference when scale will change
originalContentOffset = collectionView.contentOffset.x // remember original content offset
}
else if (gesture.state == .Changed) {
let newScale = metrics.normalizeScale(scaleStart * gesture.scale) // normalize scale. give 0.5, 1, 1.5, 2
metrics.scale = newScale // global struct
//let ZoomIn = (newScale > scaleStart)
collectionView.collectionViewLayout.invalidateLayout() // invalidate layout in order to redisplay cell with updated scale
let scaleRatio = newScale / self.scaleStart
var newContentOffset = CGFloat(0)
let widthDiff: CGFloat = (scaleRatio * self.widthStart) - self.widthStart
newContentOffset = originalContentOffset + widthDiff
self.collectionView.setContentOffset(CGPointMake(newContentOffset ,0), animated: false)
}
}
它只是不起作用...
你有好主意吗?
非常感谢您的输入。
这是我拥有和想要的偏移量正确的屏幕截图。但是我无法找到捏捏手势后计算内容偏移量的正确方法。
蒂埃里
最佳答案
关于您的原始问题,您希望缩放中心位于屏幕中间,请尝试以下操作:
@objc func handlePinchGesture(_ gesture: UIPinchGestureRecognizer) {
let scaleValue: CGFloat = gesture.scale
if (gesture.state == .began) {
scaleStart = metrics.scale // remember current scale
widthStart = collectionView.visibleCells[0].bounds.width // get size of a cell to calulate a difference when scale will change
originalContentOffset = collectionView.contentOffset.x // remember original content offset
originalNumberOfCellsToOffset = (originalContentOffset + (self.view.frame.size.width/2)) / (widthStart * 2) //for zooming at the middle of the screen
}
else if (gesture.state == .changed) {
let newScale = scaleStart * gesture.scale
//let newScale = metrics.normalizeScale(scaleStart * gesture.scale) // use this line instead, if you want to normalize scale. give 0.5, 1, 1.5, 2
metrics.scale = newScale // global struct
//let ZoomIn = (newScale > scaleStart)
collectionView.collectionViewLayout.invalidateLayout() // invalidate layout in order to redisplay cell with updated scale
let scaleRatio = newScale / scaleStart
var newContentOffset = CGFloat(0)
let offsetDiffForEachCell: CGFloat = (scaleRatio * widthStart) - widthStart
newContentOffset = (offsetDiffForEachCell)*originalNumberOfCellsToOffset + (originalContentOffset)
collectionView.setContentOffset(CGPoint(x: newContentOffset ,y: 0), animated: false)
}
}
根据屏幕上collectionView的位置和大小,它可能并没有真正在屏幕中间缩放。如果是这种情况,您要做的就是更改此行:
originalNumberOfCellsToOffset = (originalContentOffset + (self.view.frame.size.width/2)) / (widthStart * 2) //for zooming at the middle of the screen
到
originalNumberOfCellsToOffset = (originalContentOffset + (self.view.frame.size.width/2) - 20) / (widthStart * 2) //for zooming at the middle of the screen
如果您希望缩放中心向左增加20px。
奖励:如果相反,您想放大捏的中间,然后更改此行:
originalNumberOfCellsToOffset = (originalContentOffset + (self.view.frame.size.width/2)) / (widthStart * 2) //for zooming at the middle of the screen
至
originalNumberOfCellsToOffset = (gesture.location(ofTouch: 0, in: sectionSequenceCollectionView).x + gesture.location(ofTouch: 1, in: sectionSequenceCollectionView).x) / (widthStart * 2)
关于ios - 保持收藏后查看单元格位置以进行缩放,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37622366/