Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/102.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone UICollectionView:类似Safari选项卡或应用商店搜索的分页_Iphone_Ios_Objective C_Ios6_Uicollectionview - Fatal编程技术网

Iphone UICollectionView:类似Safari选项卡或应用商店搜索的分页

Iphone UICollectionView:类似Safari选项卡或应用商店搜索的分页,iphone,ios,objective-c,ios6,uicollectionview,Iphone,Ios,Objective C,Ios6,Uicollectionview,我想在我的应用程序中实现“卡片”,比如Safari标签或应用商店搜索 我将在屏幕中央向用户显示一张卡,并在左右两侧显示上一张卡和下一张卡的一部分。(例如,请参见应用商店搜索或Safari选项卡) 我决定使用UICollectionView,我需要更改页面大小(不知道如何更改)或实现自己的布局子类(不知道如何更改) 有什么帮助吗?下面是我找到的获得这种效果的最简单方法。它包括您的收藏视图和一个额外的秘密滚动视图 设置收藏视图 设置集合视图及其所有数据源方法 框架集合视图;它应该跨越您希望可见的整

我想在我的应用程序中实现“卡片”,比如Safari标签或应用商店搜索

我将在屏幕中央向用户显示一张卡,并在左右两侧显示上一张卡和下一张卡的一部分。(例如,请参见应用商店搜索或Safari选项卡)

我决定使用
UICollectionView
,我需要更改页面大小(不知道如何更改)或实现自己的布局子类(不知道如何更改)


有什么帮助吗?

下面是我找到的获得这种效果的最简单方法。它包括您的收藏视图和一个额外的秘密滚动视图

设置收藏视图

  • 设置集合视图及其所有数据源方法
  • 框架集合视图;它应该跨越您希望可见的整个宽度
  • 设置集合视图的
    contentInset

    _collectionView.contentInset = UIEdgeInsetsMake(0, (self.view.frame.size.width-pageSize)/2, 0, (self.view.frame.size.width-pageSize)/2);
    
这有助于正确偏移单元格

设置您的秘密滚动视图

  • 创建一个滚动视图,将其放置在您喜欢的任何位置。如果愿意,可以将其设置为
    隐藏
  • 将scrollview边界的大小设置为所需的页面大小
  • 将自己设置为scrollview的代理
  • 将其
    contentSize
    设置为集合视图的预期内容大小
移动手势识别器

  • 将secret scrollview的手势识别器添加到集合视图,并禁用集合视图的手势识别器:

    [_collectionView addGestureRecognizer:_secretScrollView.panGestureRecognizer];
    _collectionView.panGestureRecognizer.enabled = NO;
    
代表

- (void) scrollViewDidScroll:(UIScrollView *)scrollView {
    CGPoint contentOffset = scrollView.contentOffset;
    contentOffset.x = contentOffset.x - _collectionView.contentInset.left;
    _collectionView.contentOffset = contentOffset;
}
当scrollview移动时,获取其偏移量并将其设置为集合视图的偏移量


我在这里写了关于这一点的博客,因此请查看此链接以获取更新:

前面的链接非常复杂,UICollectionView是UIScrollView的一个子类,所以只需执行以下操作:

[self.collectionView setPagingEnabled:YES];
你们都准备好了


看看这个。

对索罗斯的答案进行了一点编辑,这对我来说很有帮助。 我唯一没有禁用手势的编辑:

[_collectionView addGestureRecognizer:_secretScrollView.panGestureRecognizer];
_collectionView.panGestureRecognizer.enabled = NO;
我禁用了collectionview上的滚动:

_collectionView.scrollEnabled = NO;

禁用该手势时,也会禁用秘密滚动视图手势。

您可以将UICollectionViewFlowLayout子类化,并进行如下覆盖:

- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)contentOffset 
                                 withScrollingVelocity:(CGPoint)velocity
{
    NSArray* layoutAttributesArray = 
   [self layoutAttributesForElementsInRect:self.collectionView.bounds];

    if(layoutAttributesArray.count == 0)
        return contentOffset;


    UICollectionViewLayoutAttributes* candidate = 
    layoutAttributesArray.firstObject;

    for (UICollectionViewLayoutAttributes* layoutAttributes in layoutAttributesArray)
    {
        if (layoutAttributes.representedElementCategory != UICollectionElementCategoryCell)
            continue;


        if((velocity.x > 0.0 && layoutAttributes.center.x > candidate.center.x) ||
           (velocity.x <= 0.0 && layoutAttributes.center.x < candidate.center.x))
            candidate = layoutAttributes;


    }

    return CGPointMake(candidate.center.x - self.collectionView.bounds.size.width * 0.5f, contentOffset.y);
}
-(CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)contentOffset
带Crollingvelocity:(CGPoint)速度
{
NSArray*布局属性阵列=
[self-layouttributesforelementsinrect:self.collectionView.bounds];
如果(layoutAttributesArray.count==0)
返回内容偏移;
UICollectionViewLayoutAttribute*候选项=
layoutAttributesArray.firstObject;
对于(UICollectionViewLayoutAttribute*LayoutAttribute阵列中的LayoutAttribute)
{
if(layoutAttributes.representedElementCategory!=UICollectionElementCategoryCell)
继续;
if((velocity.x>0.0&&layouttributes.center.x>candidate.center.x)||

(velocity.x我将添加另一个解决方案。就地捕捉并不完美(不如设置了分页启用时好,但效果足够好)

我已经尝试过实现索罗斯的解决方案,但它对我不起作用

由于
UICollectionView
UIScrollView
的子类,因此它将响应一个重要的
UIScrollViewDelegate
方法,即:

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView
                     withVelocity:(CGPoint)velocity
              targetContentOffset:(inout CGPoint *)targetContentOffset
使用
targetContentOffset
(一个inout指针)可以重新定义集合视图的停止点(如果水平滑动,则为
x

下面是关于几个变量的简要说明:

  • self.cellWidth
    –这是集合视图单元格的宽度(如果需要,您甚至可以在那里硬编码)

  • self.minimumlinespace
    –这是您在单元格之间设置的最小行间距

  • self.scrollingObjects
    是集合视图中包含的对象数组(我需要它主要用于计数,以便知道何时停止滚动)

因此,我们的想法是在集合视图的委托中实现此方法,如下所示:

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView
                     withVelocity:(CGPoint)velocity
              targetContentOffset:(inout CGPoint *)targetContentOffset
{       
    if (self.currentIndex == 0 && velocity.x < 0) {
        // we have reached the first user and we're trying to go back
        return;
    }

    if (self.currentIndex == (self.scrollingObjects.count - 1) && velocity.x > 0) {
        // we have reached the last user and we're trying to go forward
        return;
    }

    if (velocity.x < 0) {
        // swiping from left to right (going left; going back)
        self.currentIndex--;
    } else {
        // swiping from right to left (going right; going forward)
        self.currentIndex++;
    }

    float xPositionToStop = 0;

    if (self.currentIndex == 0) {
        // first row
        xPositionToStop = 0;
    } else {
        // one of the next ones
        xPositionToStop = self.currentIndex * self.cellWidth + (self.currentIndex + 1) * self.minimumLineSpacing - ((scrollView.bounds.size.width - 2*self.minimumLineSpacing - self.cellWidth)/2);
    }

    targetContentOffset->x = xPositionToStop;

    NSLog(@"Point of stopping: %@", NSStringFromCGPoint(*targetContentOffset));
}
-(void)ScrollViewWillendDraging:(UIScrollView*)scrollView
withVelocity:(CGPoint)速度
targetContentOffset:(输入输出CGPoint*)targetContentOffset
{       
if(self.currentIndex==0&&velocity.x<0){
//我们已经找到了第一个用户,我们正在尝试返回
返回;
}
if(self.currentIndex==(self.scrollingObjects.count-1)和&velocity.x>0){
//我们已经联系到最后一个用户,我们正在尝试继续
返回;
}
if(速度x<0){
//从左向右滑动(向左;向后)
self.currentIndex--;
}否则{
//从右向左滑动(向右;向前)
self.currentIndex++;
}
float xPositionToStop=0;
if(self.currentIndex==0){
//第一排
xPositionToStop=0;
}否则{
//下一个
xPositionToStop=self.currentIndex*self.cellWidth+(self.currentIndex+1)*self.minimumLineSpacing-((scrollView.bounds.size.width-2*self.minimumLineSpacing-self.cellWidth)/2);
}
targetContentOffset->x=xPositionToStop;
NSLog(@“停止点:%@”,NSStringFromCGPoint(*targetContentOffset));
}
期待您的反馈,以使捕捉效果更好。我还会继续寻找更好的解决方案…

在Swift中

class CenteringFlowLayout: UICollectionViewFlowLayout {

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

        guard let collectionView = collectionView,
            let layoutAttributesArray = layoutAttributesForElementsInRect(collectionView.bounds),
            var candidate = layoutAttributesArray.first else { return proposedContentOffset }

        layoutAttributesArray.filter({$0.representedElementCategory == .Cell }).forEach { layoutAttributes in

            if (velocity.x > 0 && layoutAttributes.center.x > candidate.center.x) ||
                (velocity.x <= 0 && layoutAttributes.center.x < candidate.center.x) {
                candidate = layoutAttributes
            }
        }

        return CGPoint(x: candidate.center.x - collectionView.bounds.width / 2, y: proposedContentOffset.y)
    }

}
class CenteringFlowLayout:UICollectionViewFlowLayout{
覆盖func targetContentOffsetForProposedContentOffset(proposedContentOffset:CGPoint,使用CrollingVelocity:CGPoint)->CGPoint{
guard let collectionView=collectionView,
让layoutAttributesArray=LayoutAttributesForElementsRect(collectionView.bounds),
var候选者=la