简体   繁体   English

水平滚动 UICollectionView 时对齐单元格的中心

[英]Snap to center of a cell when scrolling UICollectionView horizontally

I know some people have asked this question before but they were all about UITableViews or UIScrollViews and I couldn't get the accepted solution to work for me.我知道有些人以前问过这个问题,但他们都是关于UITableViewsUIScrollViews的,我无法让接受的解决方案为我工作。 What I would like is the snapping effect when scrolling through my UICollectionView horizontally - much like what happens in the iOS AppStore.我想要的是水平滚动我的UICollectionView时的捕捉效果——就像在 iOS AppStore 中发生的一样。 iOS 9+ is my target build so please look at the UIKit changes before answering this. iOS 9+ 是我的目标版本,所以在回答这个问题之前请先查看 UIKit 的变化。

Thanks.谢谢。

While originally I was using Objective-C, I since switched so Swift and the original accepted answer did not suffice.虽然最初我使用的是 Objective-C,但后来我切换为 Swift 并且最初接受的答案还不够。

I ended up creating a UICollectionViewLayout subclass which provides the best (imo) experience as opposed to the other functions which alter content offset or something similar when the user has stopped scrolling.我最终创建了一个UICollectionViewLayout子类,它提供了最好的(imo)体验,而不是在用户停止滚动时改变内容偏移或类似内容的其他功能。

class SnappingCollectionViewLayout: UICollectionViewFlowLayout {

    override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
        guard let collectionView = collectionView else { return super.targetContentOffset(forProposedContentOffset: proposedContentOffset, withScrollingVelocity: velocity) }

        var offsetAdjustment = CGFloat.greatestFiniteMagnitude
        let horizontalOffset = proposedContentOffset.x + collectionView.contentInset.left

        let targetRect = CGRect(x: proposedContentOffset.x, y: 0, width: collectionView.bounds.size.width, height: collectionView.bounds.size.height)

        let layoutAttributesArray = super.layoutAttributesForElements(in: targetRect)

        layoutAttributesArray?.forEach({ (layoutAttributes) in
            let itemOffset = layoutAttributes.frame.origin.x
            if fabsf(Float(itemOffset - horizontalOffset)) < fabsf(Float(offsetAdjustment)) {
                offsetAdjustment = itemOffset - horizontalOffset
            }
        })

        return CGPoint(x: proposedContentOffset.x + offsetAdjustment, y: proposedContentOffset.y)
    }
}

For the most native feeling deceleration with the current layout subclass, make sure to set the following:对于当前布局子类最原生的感觉减速,请确保设置以下内容:

collectionView?.decelerationRate = UIScrollViewDecelerationRateFast

Based on answer from Mete and comment from Chris Chute ,根据Mete的回答和Chris Chute的评论

Here's a Swift 4 extension that will do just what OP wants.这是一个 Swift 4 扩展,它将满足 OP 的需求。 It's tested on single row and double row nested collection views and it works just fine.它在单行和双行嵌套集合视图上进行了测试,并且运行良好。

extension UICollectionView {
    func scrollToNearestVisibleCollectionViewCell() {
        self.decelerationRate = UIScrollViewDecelerationRateFast
        let visibleCenterPositionOfScrollView = Float(self.contentOffset.x + (self.bounds.size.width / 2))
        var closestCellIndex = -1
        var closestDistance: Float = .greatestFiniteMagnitude
        for i in 0..<self.visibleCells.count {
            let cell = self.visibleCells[i]
            let cellWidth = cell.bounds.size.width
            let cellCenter = Float(cell.frame.origin.x + cellWidth / 2)

            // Now calculate closest cell
            let distance: Float = fabsf(visibleCenterPositionOfScrollView - cellCenter)
            if distance < closestDistance {
                closestDistance = distance
                closestCellIndex = self.indexPath(for: cell)!.row
            }
        }
        if closestCellIndex != -1 {
            self.scrollToItem(at: IndexPath(row: closestCellIndex, section: 0), at: .centeredHorizontally, animated: true)
        }
    }
}

You need to implement UIScrollViewDelegate protocol for your collection view and then add these two methods:您需要为您的集合视图实现UIScrollViewDelegate协议,然后添加这两个方法:

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    self.collectionView.scrollToNearestVisibleCollectionViewCell()
}

func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
    if !decelerate {
        self.collectionView.scrollToNearestVisibleCollectionViewCell()
    }
}

Snap to the nearest cell, respecting scroll velocity.捕捉到最近的单元格,尊重滚动速度。

Works without any glitches.工作没有任何故障。

import UIKit

final class SnapCenterLayout: UICollectionViewFlowLayout {
  override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
    guard let collectionView = collectionView else { return super.targetContentOffset(forProposedContentOffset: proposedContentOffset, withScrollingVelocity: velocity) }
    let parent = super.targetContentOffset(forProposedContentOffset: proposedContentOffset, withScrollingVelocity: velocity)

    let itemSpace = itemSize.width + minimumInteritemSpacing
    var currentItemIdx = round(collectionView.contentOffset.x / itemSpace)

    // Skip to the next cell, if there is residual scrolling velocity left.
    // This helps to prevent glitches
    let vX = velocity.x
    if vX > 0 {
      currentItemIdx += 1
    } else if vX < 0 {
      currentItemIdx -= 1
    }

    let nearestPageOffset = currentItemIdx * itemSpace
    return CGPoint(x: nearestPageOffset,
                   y: parent.y)
  }
}

For what it is worth here is a simple calculation that I use (in swift):这里值得的是我使用的一个简单计算(快速):

func snapToNearestCell(_ collectionView: UICollectionView) {
    for i in 0..<collectionView.numberOfItems(inSection: 0) {

        let itemWithSpaceWidth = collectionViewFlowLayout.itemSize.width + collectionViewFlowLayout.minimumLineSpacing
        let itemWidth = collectionViewFlowLayout.itemSize.width

        if collectionView.contentOffset.x <= CGFloat(i) * itemWithSpaceWidth + itemWidth / 2 {                
            let indexPath = IndexPath(item: i, section: 0)
            collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
            break
        }
    }
}

Call where you need it.在需要的地方打电话。 I call it in我把它叫进来

func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
    snapToNearestCell(scrollView)
}

And

func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
    snapToNearestCell(scrollView)
}

Where collectionViewFlowLayout could come from: collectionViewFlowLayout 可能来自哪里:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    // Set up collection view
    collectionViewFlowLayout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
}

SWIFT 3 version of @Iowa15 reply SWIFT 3 版@Iowa15 回复

func scrollToNearestVisibleCollectionViewCell() {
    let visibleCenterPositionOfScrollView = Float(collectionView.contentOffset.x + (self.collectionView!.bounds.size.width / 2))
    var closestCellIndex = -1
    var closestDistance: Float = .greatestFiniteMagnitude
    for i in 0..<collectionView.visibleCells.count {
        let cell = collectionView.visibleCells[i]
        let cellWidth = cell.bounds.size.width
        let cellCenter = Float(cell.frame.origin.x + cellWidth / 2)

        // Now calculate closest cell
        let distance: Float = fabsf(visibleCenterPositionOfScrollView - cellCenter)
        if distance < closestDistance {
            closestDistance = distance
            closestCellIndex = collectionView.indexPath(for: cell)!.row
        }
    }
    if closestCellIndex != -1 {
        self.collectionView!.scrollToItem(at: IndexPath(row: closestCellIndex, section: 0), at: .centeredHorizontally, animated: true)
    }
}

Needs to implement in UIScrollViewDelegate:需要在 UIScrollViewDelegate 中实现:

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    scrollToNearestVisibleCollectionViewCell()
}

func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
    if !decelerate {
        scrollToNearestVisibleCollectionViewCell()
    }
}

Here is my implementation这是我的实现

func snapToNearestCell(scrollView: UIScrollView) {
     let middlePoint = Int(scrollView.contentOffset.x + UIScreen.main.bounds.width / 2)
     if let indexPath = self.cvCollectionView.indexPathForItem(at: CGPoint(x: middlePoint, y: 0)) {
          self.cvCollectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
     }
}

Implement your scroll view delegates like this像这样实现您的滚动视图委托

func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
    self.snapToNearestCell(scrollView: scrollView)
}

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    self.snapToNearestCell(scrollView: scrollView)
}

Also, for better snapping此外,为了更好地捕捉

self.cvCollectionView.decelerationRate = UIScrollViewDecelerationRateFast

Works like a charm奇迹般有效

I tried both @Mark Bourke and @mrcrowley solutions but they give the pretty same results with unwanted sticky effects.我尝试了@Mark Bourke 和@mrcrowley 两种解决方案,但它们给出了几乎相同的结果,但具有不需要的粘性效果。

I managed to solve the problem by taking into account the velocity .我设法通过考虑velocity来解决问题。 Here is the full code.这是完整的代码。

final class BetterSnappingLayout: UICollectionViewFlowLayout {
override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
    guard let collectionView = collectionView else {
        return super.targetContentOffset(forProposedContentOffset: proposedContentOffset, withScrollingVelocity: velocity)
    }

    var offsetAdjusment = CGFloat.greatestFiniteMagnitude
    let horizontalCenter = proposedContentOffset.x + (collectionView.bounds.width / 2)
    
    let targetRect = CGRect(x: proposedContentOffset.x, y: 0, width: collectionView.bounds.size.width, height: collectionView.bounds.size.height)
    let layoutAttributesArray = super.layoutAttributesForElements(in: targetRect)
    layoutAttributesArray?.forEach({ (layoutAttributes) in
        let itemHorizontalCenter = layoutAttributes.center.x
        
        if abs(itemHorizontalCenter - horizontalCenter) < abs(offsetAdjusment) {
            if abs(velocity.x) < 0.3 { // minimum velocityX to trigger the snapping effect
                offsetAdjusment = itemHorizontalCenter - horizontalCenter
            } else if velocity.x > 0 {
                offsetAdjusment = itemHorizontalCenter - horizontalCenter + layoutAttributes.bounds.width
            } else { // velocity.x < 0
                offsetAdjusment = itemHorizontalCenter - horizontalCenter - layoutAttributes.bounds.width
            }
        }
    })

    return CGPoint(x: proposedContentOffset.x + offsetAdjusment, y: proposedContentOffset.y)
}

} }

If you want simple native behavior, without customization:如果您想要简单的本机行为,无需自定义:

collectionView.pagingEnabled = YES;

This only works properly when the size of the collection view layout items are all one size only and the UICollectionViewCell 's clipToBounds property is set to YES .这仅在集合视图布局项的大小均为一种大小且UICollectionViewCellclipToBounds属性设置为YES时才能正常工作。

Got an answer from SO post here and docs here这里的 SO 帖子和这里的文档中得到了答案

First What you can do is set your collection view's scrollview's delegate your class by making your class a scrollview delegate首先,您可以做的是通过使您的类成为滚动视图委托来设置您的集合视图的滚动视图的委托您的类

MyViewController : SuperViewController<... ,UIScrollViewDelegate>

Then make set your view controller as the delegate然后将您的视图控制器设置为委托

UIScrollView *scrollView = (UIScrollView *)super.self.collectionView;
scrollView.delegate = self;

Or do it in the interface builder by control + shift clicking on your collection view and then control + drag or right click drag to your view controller and select delegate.或者在界面构建器中通过 control + shift 单击您的集合视图然后控制 + 拖动或右键单击拖动到您的视图控制器并选择委托。 (You should know how to do this). (你应该知道如何做到这一点)。 That doesn't work.那是行不通的。 UICollectionView is a subclass of UIScrollView so you will now be able to see it in the interface builder by control + shift clicking UICollectionView 是 UIScrollView 的子类,因此您现在可以通过 control + shift 单击在界面构建器中看到它

Next implement the delegate method - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView接下来实现委托方法- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView

MyViewController.m

... 

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{

}

The docs state that:文档指出:

Parameters参数

scrollView |滚动视图 | The scroll-view object that is decelerating the scrolling of the content view.使内容视图的滚动减速的滚动视图对象。

Discussion The scroll view calls this method when the scrolling movement comes to a halt.讨论当滚动停止时,滚动视图调用这个方法。 The decelerating property of UIScrollView controls deceleration. UIScrollView 的 decelerating 属性控制减速。

Availability Available in iOS 2.0 and later.可用性适用于 iOS 2.0 及更高版本。

Then inside of that method check which cell was closest to the center of the scrollview when it stopped scrolling然后在该方法内部检查哪个单元格在停止滚动时最接近滚动视图的中心

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
  //NSLog(@"%f", truncf(scrollView.contentOffset.x + (self.pictureCollectionView.bounds.size.width / 2)));

float visibleCenterPositionOfScrollView = scrollView.contentOffset.x + (self.pictureCollectionView.bounds.size.width / 2);

//NSLog(@"%f", truncf(visibleCenterPositionOfScrollView / imageArray.count));


NSInteger closestCellIndex;

for (id item in imageArray) {
    // equation to use to figure out closest cell
    // abs(visibleCenter - cellCenterX) <= (cellWidth + cellSpacing/2)

    // Get cell width (and cell too)
    UICollectionViewCell *cell = (UICollectionViewCell *)[self collectionView:self.pictureCollectionView cellForItemAtIndexPath:[NSIndexPath indexPathWithIndex:[imageArray indexOfObject:item]]];
    float cellWidth = cell.bounds.size.width;

    float cellCenter = cell.frame.origin.x + cellWidth / 2;

    float cellSpacing = [self collectionView:self.pictureCollectionView layout:self.pictureCollectionView.collectionViewLayout minimumInteritemSpacingForSectionAtIndex:[imageArray indexOfObject:item]];

    // Now calculate closest cell

    if (fabsf(visibleCenterPositionOfScrollView - cellCenter) <= (cellWidth + (cellSpacing / 2))) {
        closestCellIndex = [imageArray indexOfObject:item];
        break;
    }
}

if (closestCellIndex != nil) {

[self.pictureCollectionView scrollToItemAtIndexPath:[NSIndexPath indexPathWithIndex:closestCellIndex] atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:YES];

// This code is untested. Might not work.

}

A modification of the above answer which you can also try:您也可以尝试修改上述答案:

-(void)scrollToNearestVisibleCollectionViewCell {
    float visibleCenterPositionOfScrollView = _collectionView.contentOffset.x + (self.collectionView.bounds.size.width / 2);

    NSInteger closestCellIndex = -1;
    float closestDistance = FLT_MAX;
    for (int i = 0; i < _collectionView.visibleCells.count; i++) {
        UICollectionViewCell *cell = _collectionView.visibleCells[i];
        float cellWidth = cell.bounds.size.width;

        float cellCenter = cell.frame.origin.x + cellWidth / 2;

        // Now calculate closest cell
        float distance = fabsf(visibleCenterPositionOfScrollView - cellCenter);
        if (distance < closestDistance) {
            closestDistance = distance;
            closestCellIndex = [_collectionView indexPathForCell:cell].row;
        }
    }

    if (closestCellIndex != -1) {
        [self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:closestCellIndex inSection:0] atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
    }
}

This solution gives a better and smoother animation.此解决方案提供了更好、更流畅的动画。

Swift 3斯威夫特 3

To get the first and last item to center add insets:要使第一个和最后一个项目居中添加插图:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {

    return UIEdgeInsetsMake(0, cellWidth/2, 0, cellWidth/2)
}

Then use the targetContentOffset in the scrollViewWillEndDragging method to alter the ending position.然后使用scrollViewWillEndDragging方法中的targetContentOffset来改变结束位置。

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {

    let numOfItems = collectionView(mainCollectionView, numberOfItemsInSection:0)
    let totalContentWidth = scrollView.contentSize.width + mainCollectionViewFlowLayout.minimumInteritemSpacing - cellWidth
    let stopOver = totalContentWidth / CGFloat(numOfItems)

    var targetX = round((scrollView.contentOffset.x + (velocity.x * 300)) / stopOver) * stopOver
    targetX = max(0, min(targetX, scrollView.contentSize.width - scrollView.frame.width))

    targetContentOffset.pointee.x = targetX
}

Maybe in your case the totalContentWidth is calculated differently, fe without a minimumInteritemSpacing , so adjust that accordingly.也许在您的情况下, totalContentWidth的计算方式不同, fe 没有minimumInteritemSpacing ,因此请相应地进行调整。 Also you can play around with the 300 used in the velocity您也可以使用velocity中使用的300

PS Make sure the class adopts the UICollectionViewDataSource protocol PS 确保类采用UICollectionViewDataSource协议

I just found what I think is the best possible solution to this problem:我刚刚找到了我认为是解决这个问题的最佳方法:

First add a target to the collectionView's already existing gestureRecognizer:首先在collectionView已经存在的gestureRecognizer中添加一个target:

[self.collectionView.panGestureRecognizer addTarget:self action:@selector(onPan:)];

Have the selector point to a method which takes a UIPanGestureRecognizer as a parameter:让选择器指向一个将 UIPanGestureRecognizer 作为参数的方法:

- (void)onPan:(UIPanGestureRecognizer *)recognizer {};

Then in this method, force the collectionView to scroll to the appropriate cell when the pan gesture has ended.然后在此方法中,强制 collectionView 在平移手势结束时滚动到相应的单元格。 I did this by getting the visible items from the collection view and determining which item I want to scroll to depending on the direction of the pan.我通过从集合视图中获取可见项目并根据平移的方向确定要滚动到哪个项目来做到这一点。

if (recognizer.state == UIGestureRecognizerStateEnded) {

        // Get the visible items
        NSArray<NSIndexPath *> *indexes = [self.collectionView indexPathsForVisibleItems];
        int index = 0;

        if ([(UIPanGestureRecognizer *)recognizer velocityInView:self.view].x > 0) {
            // Return the smallest index if the user is swiping right
            for (int i = index;i < indexes.count;i++) {
                if (indexes[i].row < indexes[index].row) {
                    index = i;
                }
            }
        } else {
            // Return the biggest index if the user is swiping left
            for (int i = index;i < indexes.count;i++) {
                if (indexes[i].row > indexes[index].row) {
                    index = i;
                }
            }
        }
        // Scroll to the selected item
        [self.collectionView scrollToItemAtIndexPath:indexes[index] atScrollPosition:UICollectionViewScrollPositionLeft animated:YES];
    }

Keep in mind that in my case only two items can be visible at a time.请记住,在我的情况下,一次只能看到两个项目。 I'm sure this method can be adapted for more items however.我确信这种方法可以适用于更多项目。

This from a 2012 WWDC video for an Objective-C solution.这是来自 2012 年 WWDC 视频的 Objective-C 解决方案。 I subclassed UICollectionViewFlowLayout and added the following.我将 UICollectionViewFlowLayout 子类化并添加了以下内容。

-(CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
    {
        CGFloat offsetAdjustment = MAXFLOAT;
        CGFloat horizontalCenter = proposedContentOffset.x + (CGRectGetWidth(self.collectionView.bounds) / 2);

        CGRect targetRect = CGRectMake(proposedContentOffset.x, 0.0, self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);
        NSArray *array = [super layoutAttributesForElementsInRect:targetRect];

        for (UICollectionViewLayoutAttributes *layoutAttributes in array)
        {
            CGFloat itemHorizontalCenter = layoutAttributes.center.x;
            if (ABS(itemHorizontalCenter - horizontalCenter) < ABS(offsetAdjustment))
            {
                offsetAdjustment = itemHorizontalCenter - horizontalCenter;
            }
        }

        return CGPointMake(proposedContentOffset.x + offsetAdjustment, proposedContentOffset.y);
    }

And the reason I got to this question was for the snapping with a native feel, which I got from Mark's accepted answer... this I put in the collectionView's view controller.我提出这个问题的原因是为了以一种原生的感觉捕捉,这是我从 Mark 接受的答案中得到的……我把它放在 collectionView 的视图控制器中。

collectionView.decelerationRate = UIScrollViewDecelerationRateFast;

I've been solving this issue by setting 'Paging Enabled' on the attributes inspector on the uicollectionview.我一直在通过在 uicollectionview 的属性检查器上设置“启用分页”来解决这个问题。

For me this happens when the width of the cell is the same as the width of the uicollectionview.对我来说,当单元格的宽度与 uicollectionview 的宽度相同时,就会发生这种情况。

No coding involved.不涉及编码。

Here is a Swift 3.0 version, which should work for both horizontal and vertical directions based on Mark's suggestion above:这是一个 Swift 3.0 版本,根据上面 Mark 的建议,它应该适用于水平和垂直方向:

  override func targetContentOffset(
    forProposedContentOffset proposedContentOffset: CGPoint,
    withScrollingVelocity velocity: CGPoint
  ) -> CGPoint {

    guard
      let collectionView = collectionView
    else {
      return super.targetContentOffset(
        forProposedContentOffset: proposedContentOffset,
        withScrollingVelocity: velocity
      )
    }

    let realOffset = CGPoint(
      x: proposedContentOffset.x + collectionView.contentInset.left,
      y: proposedContentOffset.y + collectionView.contentInset.top
    )

    let targetRect = CGRect(origin: proposedContentOffset, size: collectionView.bounds.size)

    var offset = (scrollDirection == .horizontal)
      ? CGPoint(x: CGFloat.greatestFiniteMagnitude, y:0.0)
      : CGPoint(x:0.0, y:CGFloat.greatestFiniteMagnitude)

    offset = self.layoutAttributesForElements(in: targetRect)?.reduce(offset) {
      (offset, attr) in
      let itemOffset = attr.frame.origin
      return CGPoint(
        x: abs(itemOffset.x - realOffset.x) < abs(offset.x) ? itemOffset.x - realOffset.x : offset.x,
        y: abs(itemOffset.y - realOffset.y) < abs(offset.y) ? itemOffset.y - realOffset.y : offset.y
      )
    } ?? .zero

    return CGPoint(x: proposedContentOffset.x + offset.x, y: proposedContentOffset.y + offset.y)
  }

Swift 4.2.斯威夫特 4.2。 Simple.简单的。 For fixed itemSize.对于固定的 itemSize。 Horizontal flow direction.水平流向。

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {

    if let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
        let floatingPage = targetContentOffset.pointee.x/scrollView.bounds.width
        let rule: FloatingPointRoundingRule = velocity.x > 0 ? .up : .down
        let page = CGFloat(Int(floatingPage.rounded(rule)))
        targetContentOffset.pointee.x = page*(layout.itemSize.width + layout.minimumLineSpacing)
    }

}

尝试以下解决方案: CarouselWithPaging

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM