Đây là cách triển khai của tôi trong Swift 5 cho phân trang dựa trên ô dọc :
override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
guard let collectionView = self.collectionView else {
let latestOffset = super.targetContentOffset(forProposedContentOffset: proposedContentOffset, withScrollingVelocity: velocity)
return latestOffset
}
// Page height used for estimating and calculating paging.
let pageHeight = self.itemSize.height + self.minimumLineSpacing
// Make an estimation of the current page position.
let approximatePage = collectionView.contentOffset.y/pageHeight
// Determine the current page based on velocity.
let currentPage = velocity.y == 0 ? round(approximatePage) : (velocity.y < 0.0 ? floor(approximatePage) : ceil(approximatePage))
// Create custom flickVelocity.
let flickVelocity = velocity.y * 0.3
// Check how many pages the user flicked, if <= 1 then flickedPages should return 0.
let flickedPages = (abs(round(flickVelocity)) <= 1) ? 0 : round(flickVelocity)
let newVerticalOffset = ((currentPage + flickedPages) * pageHeight) - collectionView.contentInset.top
return CGPoint(x: proposedContentOffset.x, y: newVerticalOffset)
}
Một số lưu ý:
- Không trục trặc
- ĐẶT PAGING THÀNH FALSE ! (nếu không điều này sẽ không hoạt động)
- Cho phép bạn thiết lập vận tốc của riêng mình một cách dễ dàng.
- Nếu điều gì đó vẫn không hoạt động sau khi thử cách này, hãy kiểm tra xem bạn có
itemSize
thực sự khớp với kích thước của mặt hàng hay không vì đó thường là một vấn đề, đặc biệt là khi sử dụng collectionView(_:layout:sizeForItemAt:)
, hãy sử dụng biến tùy chỉnh với itemSize để thay thế.
- Điều này hoạt động tốt nhất khi bạn thiết lập
self.collectionView.decelerationRate = UIScrollView.DecelerationRate.fast
.
Đây là phiên bản ngang (chưa được kiểm tra kỹ lưỡng vì vậy xin vui lòng bỏ qua cho bất kỳ sai sót nào):
override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
guard let collectionView = self.collectionView else {
let latestOffset = super.targetContentOffset(forProposedContentOffset: proposedContentOffset, withScrollingVelocity: velocity)
return latestOffset
}
// Page width used for estimating and calculating paging.
let pageWidth = self.itemSize.width + self.minimumInteritemSpacing
// Make an estimation of the current page position.
let approximatePage = collectionView.contentOffset.x/pageWidth
// Determine the current page based on velocity.
let currentPage = velocity.x == 0 ? round(approximatePage) : (velocity.x < 0.0 ? floor(approximatePage) : ceil(approximatePage))
// Create custom flickVelocity.
let flickVelocity = velocity.x * 0.3
// Check how many pages the user flicked, if <= 1 then flickedPages should return 0.
let flickedPages = (abs(round(flickVelocity)) <= 1) ? 0 : round(flickVelocity)
// Calculate newHorizontalOffset.
let newHorizontalOffset = ((currentPage + flickedPages) * pageWidth) - collectionView.contentInset.left
return CGPoint(x: newHorizontalOffset, y: proposedContentOffset.y)
}
Mã này dựa trên mã tôi sử dụng trong dự án cá nhân của mình, bạn có thể kiểm tra tại đây bằng cách tải xuống và chạy mục tiêu Ví dụ.