在UICollectionView中更改滚动方向

11

我有一个已经设置好的UICollectionView,一切都很正常(选择、标题等),但是在某些情况下我想改变滚动方向。

简而言之,如果我进入故事板并更改scrollDirection,则一切正常,但我想通过编程方式完成它!

我尝试直接更改集合视图的滚动方向:

    [myCollectionView setScrollDirection:....and so on.......
但这并不起作用,我在那里找不到scrollDirection或类似的东西。 我还尝试设置流式布局,但我确信我的做法是错误的(即尝试将ViewLayout设置为FlowLayout)。
    UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc]init];
    [flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
    [myCollectionView setCollectionViewLayout:flowLayout];

这会导致很多约束问题而且我怀疑我需要在flowLayout上做更多的工作(从我发现的情况来看,它超出了我的能力范围)。

还应该注意到我正在使用自定义单元格、标题和页脚。

简而言之,有没有一种简单的方法来解决这个问题?或者有没有人知道一个好的流布局教程?

修改

我设置集合视图如下;

[myCollectionView setDataSource:self];
[myCollectionView setDelegate:self];

我实现了这些委托方法,一切都正常工作。

viewForSupplementaryElementOfKind
numberOfSectionsInCollectionView
numberOfItemsInSection
cellForItemAtIndexPath
didSelectItemAtIndexPath

我已经将DataSource和Delegate添加到.h文件中,还添加了FlowLayout delegate,但是我不确定后者还需要添加什么。

大部分的视觉布局都在Story Board中完成,有一些诸如字体、大小和颜色等内容需要通过编程来完成。

另一个编辑

当我尝试更改FlowLayout时出现了这个错误,当我尝试使布局失效时也会出现这个错误。

无法同时满足约束条件。可能以下列表中至少有一个约束条件不符合您的意愿。请尝试:(1)查看每个约束条件,找出不符合预期的约束条件;(2)找到添加不需要的约束条件的代码并进行修复。(注意:如果您看到了一些您不理解的NSAutoresizingMaskLayoutConstraints,请参考UIView属性translatesAutoresizingMaskIntoConstraints的文档)

"<NSAutoresizingMaskLayoutConstraint:0x89967f0 h=--& v=--& V:[menuCell:0x8991700(50)]>",
"<NSLayoutConstraint:0x8991200 menuCell:0x8991700.bottom == UILabel:0x8992be0.bottom + 100>",
"<NSLayoutConstraint:0x898fd50 UILabel:0x8992be0.top == menuCell:0x8991700.top + 3>"

将尝试通过打破约束来进行恢复

在调试器中使用objc_exception_throw中断以捕获此异常。 UIView中UIConstraintBasedLayoutDebugging类别中列出的方法也可能有所帮助。


集合视图所绘制的视图是否符合UICollectionViewFlowLayoutDelegate协议?您确定要绘制的内容量足够大,以使集合视图实际滚动吗?我们能看到更多有关集合视图设置的内容吗?通过尝试在流布局上设置滚动方向,您正在朝着正确的方向前进,做得很好! - Matthew Hallatt
@MatthewHallatt 我添加了更多信息。这是一个大表,可能有4或5个部分中的50-60项。集合视图是底部的长条,可以水平滚动,可以单击按钮使集合展开到几乎整个屏幕(已经起作用),但我希望滚动移动到垂直滚动。 - Recycled Steel
4个回答

20

做这个:

- (IBAction)changeDirection:(UIButton *)sender
{
     UICollectionViewFlowLayout *layout = (UICollectionViewFlowLayout *)[self.collectionView collectionViewLayout];
     if(layout.scrollDirection == UICollectionViewScrollDirectionHorizontal)
     {
        layout.scrollDirection = UICollectionViewScrollDirectionVertical;
     }
     else
     {
         layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
     }
}

它对我有效。


对我来说仍然不起作用。即使我在更改后调用[layout invalidateLayout] - Arsynth
很高兴能够帮助 :) - Pratham Mehta

5
在 Swift 中,您可以这样做:
//From the collection view subclass
    if let layout: UICollectionViewFlowLayout = self.collectionViewLayout as? UICollectionViewFlowLayout {
        layout.scrollDirection = .Vertical
    }

0

你可以使用属性观察器didSet{}来处理你的集合视图 outlet。

假设collectionView的outlet名称为myCollectionView,在代码中添加一个didSet属性观察器到outlet,并更改布局方向。类似于以下代码-

@IBOutlet weak var myCollectionView:UICollectionView!{
      didSet{
            let layout = contentCollectionView.collectionViewLayout as!
UICollectionViewFlowLayout
            layout.scrollDirection = .Vertical
        }
}

通常情况下,我们可以从对象库中在Storyboard中拖入一个collectionView,它会自动带有FlowLayout。您可以通过告诉代码,当我获取我的collectionView时,我希望它的布局滚动方向是水平或垂直来更改此布局的流程方向。

0

好的,尝试在你的集合视图上调用invalidateLayout方法,像这样:

[myCollectionView.collectionViewLayout invalidateLayout];

这将强制集合视图在该点更新其布局(请参见此处的苹果文档)。我不确定,但我想当您更改滚动方向时不会调用此函数。

看看这是否能帮到您!


我尝试了这个,但是得到了相同的结果,为了清晰起见,我在我的问题中放置了整个错误。我很快就会达到这样一个点:当需要时,我将简单地添加两个集合视图并显示/隐藏它们,但这似乎是一种浪费资源的做法。 - Recycled Steel
它看起来好像全部都是在接口构建器中完成的。没有设置任何约束条件,因此我认为它们是自动完成的。我尝试添加一些,但是还是一样。 - Recycled Steel
你在单元格的 'prepareForReuse' 方法中做了什么吗?如果没有,请尝试将标签的文本设置为 nil(@“”),并将任何图像也设置为 nil,以防万一! - Matthew Hallatt
我已经尝试在绘制页眉和页脚的viewForSupplementaryElementOfKind中返回nil,但结果相同。我可以复制一份并删除整个页眉页脚,因为(正如您所说)它看起来像是某些问题所在。 - Recycled Steel
不要使用 prepareForReuse。 - Recycled Steel
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接