ios - targetContentOffsetForProposedContentOffset - 错误的建议偏移量

标签 ios swift uicollectionviewlayout

我有一个自定义的 UICollectionViewLayout 并且它实现了 targetContentOffsetForProposedContentOffset 以设置分页。 UICollectionView 中的中心项目是完整的“大”尺寸,而每个其他项目都有一个“缩小”比例值的 CGAffineTransformScale

我的问题是 contentOffset 似乎有一个上限,因此我只能滚动到第 5 项(共 7 项),它会弹回。代码后的细节:

我将 collectionViewContentSize() 设置如下:

@IBInspectable var shrunkScale: CGFloat = 0.5 // 0.5 in IB
@IBInspectable var largeSize: CGSize = CGSizeZero // 360x490 in IB
@IBInspectable var itemSpacing: CGFloat = 0 // 32 in IB

var widthPerAdditionalItem: CGFloat {
    return largeSize.width * shrunkScale + itemSpacing
}

override func collectionViewContentSize() -> CGSize {
    guard let collectionView = self.collectionView else {
        return CGSizeZero
    }

    let count = CGFloat(collectionView.numberOfItemsInSection(0))

    let width = largeSize.width + (count) * widthPerAdditionalItem
    let height = collectionView.bounds.height

    let size = CGSize(width: width, height: height)

    return size
}

targetOffset... 方法引用单个辅助方法:

override func targetContentOffsetForProposedContentOffset(proposedContentOffset: CGPoint) -> CGPoint {

    let closestPlace = round(proposedContentOffset.x / widthPerAdditionalItem)

    guard let offsetX = offsetXForItemAtIndex(Int(closestPlace)) else {
        return proposedContentOffset
    }
    print("Calculated: \(offsetX), Proposed: \(proposedContentOffset.x), ContentWidth: \(collectionView?.contentSize.width ?? 0 )")
    return CGPoint(x: offsetX, y: proposedContentOffset.y)
}

override func targetContentOffsetForProposedContentOffset(proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
    return targetContentOffsetForProposedContentOffset(proposedContentOffset)
}

func contentOffsetForItemAtIndexPath(indexPath: NSIndexPath) -> CGPoint? {
    guard
        let collectionView = self.collectionView,
        let offsetX =  offsetXForItemAtIndex(indexPath.item)
    else {
        return nil
    }
    print("Tap Offset: - \(offsetX) vs. \(collectionView.contentOffset.x)")
    return CGPoint(x: offsetX, y: collectionView.contentOffset.y)

}

private func offsetXForItemAtIndex(index: Int) -> CGFloat? {
    guard
        let count = collectionView?.numberOfItemsInSection(0)
    else {
        return nil
    }

    let proposed =  CGFloat(index) * widthPerAdditionalItem
    let maximum = CGFloat(count) * widthPerAdditionalItem

    // bound min = 0, max = count*width
    return max( min(maximum, proposed), 0)
}

这是我得到的:

  1. 我的内容宽度是 1844.0
  2. 我在 offset.x = 1187.5
  3. 处完成拖动 View
  4. targetContentOffsetForProposedContentOffset 收到建议的偏移量。x = 820.0
  5. 我返回 848.0
  6. 的“分页”offset.x 值
  7. collectionView 滚动到 820.0
  8. 的 offset.x

我的期望:

  1. 我的内容宽度是 1844.0
  2. 我在 offset.x = 1187.5
  3. 处完成拖动 View
  4. targetContentOffsetForProposedContentOffset 收到一个 建议 offset.x = 1187.5
  5. 我返回 1272.0
  6. 的“分页”offset.x 值
  7. collectionView 滚动到 1272.0
  8. 的 offset.x

调试:

如果我使用计算出的 1272.0 偏移量手动调用 setContentOffset,它就会滚动到正确的位置。但是当我尝试滚动它时,它会 swift 返回到 820.0

最佳答案

坐下来做一些数学计算后,我得出以下结论:

contentWidth = 1844
poposedContentOffset.x = 820
1844 - 820 = 1024 // <--- Width of the screen.

第一个项目的内容从屏幕的中心显示到中心第二项的屏幕。

这意味着我需要添加一半 collectionView 的 frame.width 以便第一个项目可以居中,然后再添加一半以便最后一个项目可以居中。

collectionViewContentSize() 现在返回

let width = (count-1) * widthPerAdditionalItem + collectionView.bounds.width
let height = collectionView.bounds.height
let size = CGSize(width: width, height: height)

关于ios - targetContentOffsetForProposedContentOffset - 错误的建议偏移量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33351784/

相关文章:

ios - 如何根据行交替 UICollectionViewCell 背景颜色?

ios - 如何获取顺序 MKDirection 请求响应 Swift

ios - 我不能在 Swift 中调用多个应用程序消息

swift - MapKit SearchResultsUpdating 未调用

swift - 自定义拖放 UICollectionViewLayout 捕捉到网格

ios - UICollectionView 单行中的两个单元格

ios - AlertController - 与 UIViewController 冲突

ios - 旋转行为 iOS8 与 iOS9

ios - 何时以及何时不在 Objective-C 中使用 __block?

ios - UITableview 添加填充到自定义部分标题 imageview