mle*_*evi 38 uiscrollview ios uicollectionview
我有一个水平滚动collectionView,每个单元格都是视图的大小.当我浏览collectionView时,它不会逐个页面.单元格不在屏幕的中心.我已经尝试了很多东西试图解决它,并没有任何运气.以下是该问题的视频:https: //www.youtube.com/watch ?v = tXsxWelk16w有什么想法吗?
Vla*_*lad 122
删除项目之间的空格.对于水平滚动集合视图,将最小行间距设置为0.您可以使用界面生成器或UICollectionViewDelegateFlowLayout协议方法执行此操作:
- (CGFloat)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
minimumLineSpacingForSectionAtIndex:(NSInteger)section {
return 0;
}
Run Code Online (Sandbox Code Playgroud)

另一种方法是使单元格的宽度小于collectionView的宽度,以获得项目之间水平空间的值.然后使用左右插图添加部分插入,这些插入等于项目之间的水平空间的一半.例如,您的最小行距为10:
- (CGFloat)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
minimumLineSpacingForSectionAtIndex:(NSInteger)section {
return 10;
}
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return CGSizeMake(collectionView.frame.size.width - 10, collectionView.frame.size.height);
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(0, 5, 0, 5);
}
Run Code Online (Sandbox Code Playgroud)

第三种方法:在scrollViewDidEndDecelerating:方法中操纵collectionView滚动:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
if (scrollView == self.collectionView) {
CGPoint currentCellOffset = self.collectionView.contentOffset;
currentCellOffset.x += self.collectionView.frame.size.width / 2;
NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:currentCellOffset];
[self.collectionView scrollToItemAtIndexPath:indexPath
atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally
animated:YES];
}
}
Run Code Online (Sandbox Code Playgroud)

小智 33
在Swift 3中进行演示:https: //github.com/damienromito/CollectionViewCustom
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
let pageWidth = Float(itemWidth + itemSpacing)
let targetXContentOffset = Float(targetContentOffset.pointee.x)
let contentWidth = Float(collectionView!.contentSize.width )
var newPage = Float(self.pageControl.currentPage)
if velocity.x == 0 {
newPage = floor( (targetXContentOffset - Float(pageWidth) / 2) / Float(pageWidth)) + 1.0
} else {
newPage = Float(velocity.x > 0 ? self.pageControl.currentPage + 1 : self.pageControl.currentPage - 1)
if newPage < 0 {
newPage = 0
}
if (newPage > contentWidth / pageWidth) {
newPage = ceil(contentWidth / pageWidth) - 1.0
}
}
self.pageControl.currentPage = Int(newPage)
let point = CGPoint (x: CGFloat(newPage * pageWidth), y: targetContentOffset.pointee.y)
targetContentOffset.pointee = point
}
Run Code Online (Sandbox Code Playgroud)
斯威夫特4:
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
let pageWidth = Float(itemWidth + itemSpacing)
let targetXContentOffset = Float(targetContentOffset.pointee.x)
let contentWidth = Float(collectionView!.contentSize.width )
var newPage = Float(self.pageControl.currentPage)
if velocity.x == 0 {
newPage = floor( (targetXContentOffset - Float(pageWidth) / 2) / Float(pageWidth)) + 1.0
} else {
newPage = Float(velocity.x > 0 ? self.pageControl.currentPage + 1 : self.pageControl.currentPage - 1)
if newPage < 0 {
newPage = 0
}
if (newPage > contentWidth / pageWidth) {
newPage = ceil(contentWidth / pageWidth) - 1.0
}
}
self.pageControl.currentPage = Int(newPage)
let point = CGPoint (x: CGFloat(newPage * pageWidth), y: targetContentOffset.pointee.y)
targetContentOffset.pointee = point
}
Run Code Online (Sandbox Code Playgroud)
Ale*_*nko 14
Swift版@vlad-che接受了答案:
extension GoodsViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 10
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let frameSize = collectionView.frame.size
return CGSize(width: frameSize.width - 10, height: frameSize.height)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
}
}
Run Code Online (Sandbox Code Playgroud)
小智 6
斯威夫特 3
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
if scrollView == self.collectionView {
var currentCellOffset = self.collectionView.contentOffset
currentCellOffset.x += self.collectionView.frame.width / 2
if let indexPath = self.collectionView.indexPathForItem(at: currentCellOffset) {
self.collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
}
}
}
Run Code Online (Sandbox Code Playgroud)
能够使单元格较小的单元格collectionView与单元格之间留有空间,可以向用户暗示其他任何单元格都可以滚动到其中,这对于UX来说是一个巨大的胜利。但是,页面居中无法按预期工作,随着用户滚动,每个单元格逐渐变得越来越偏移。我发现以下方法可以很好地工作。用户几乎看不见每个单元格上的居中/捕捉动画,因为它只是调整collectionView滚动自然结束的位置,而不是抽动它collectionView快速滚动到另一个indexPath。拥有仍然很重要,sectionInset属性设置得足够大,以使单元格不会粘附到包含的框架边缘,。另外,由于单元之间存在空间,因此目标可以降落在indexPath的值是nil,这会导致collectionView滚动回到起点。我已经修复了一些偏移,然后再试一次,但是这里可以采用不同的方法。
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView
withVelocity:(CGPoint)velocity
targetContentOffset:(inout CGPoint *)targetContentOffset
{
//Ensure the scrollview is the collectionview we care about
if (scrollView == self.collectionView) {
// Find cell closest to the frame centre with reference from the targetContentOffset.
CGPoint frameCentre = self.collectionView.center;
CGPoint targetOffsetToCentre = CGPointMake((* targetContentOffset).x + frameCentre.x, (* targetContentOffset).y + frameCentre.y);
NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:targetOffsetToCentre];
//Check for "edgecase" that the target will land between cells and then find a close neighbour to prevent scrolling to index {0,0}.
while (!indexPath) {
targetOffsetToCentre.x += ((UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout).minimumInteritemSpacing;
indexPath = [self.collectionView indexPathForItemAtPoint:targetOffsetToCentre];
}
// Find the centre of the target cell
CGPoint centreCellPoint = [self.collectionView layoutAttributesForItemAtIndexPath:indexPath].center;
// Calculate the desired scrollview offset with reference to desired target cell centre.
CGPoint desiredOffset = CGPointMake(centreCellPoint.x - frameCentre.x, centreCellPoint.y - frameCentre.y);
*targetContentOffset = desiredOffset;
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
Swift 3.0 设置自己的UICollectionViewFlowLayout
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
let width = UIScreen.main.bounds.width
layout.itemSize = CGSize(width: width, height: 154)
layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 0
layout.scrollDirection = .horizontal
collectionView?.collectionViewLayout = layout
Run Code Online (Sandbox Code Playgroud)
Swift 4解决方案,删除行距以保持单元居中:
public func collectionView(_ collectionView: UICollectionView, layout
collectionViewLayout: UICollectionViewLayout,
minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
Run Code Online (Sandbox Code Playgroud)
collectionView.isPagingEnabled如果您在设置 contentInset 或间距时追求(因此具有“适当的惯性感”等)但没有错误的偏移量的行为,那么这就是您所需要的:
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
let itemWidth = cellSize.width + spacing
let inertialTargetX = targetContentOffset.pointee.x
let offsetFromPreviousPage = (inertialTargetX + collectionView.contentInset.left).truncatingRemainder(dividingBy: itemWidth)
// snap to the nearest page
let pagedX: CGFloat
if offsetFromPreviousPage > itemWidth / 2 {
pagedX = inertialTargetX + (itemWidth - offsetFromPreviousPage)
} else {
pagedX = inertialTargetX - offsetFromPreviousPage
}
let point = CGPoint(x: pagedX, y: targetContentOffset.pointee.y)
targetContentOffset.pointee = point
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
36115 次 |
| 最近记录: |