无法使用AutoLayout设置UICollectionViewCell的宽度

问题描述 投票:2回答:2

我有一个带有动态高度单元格的集合视图(基于可能的多行标签和里面的文本视图),当我跨越多行时,它在高度上完美适应。但是,当文本只是一个单词或者它没有覆盖整个屏幕宽度时,单元格就像需要的那样宽,导致单元格彼此相邻而不是彼此相对。

Take a look at the result with different lengths of text inside the textview.

但是,我希望细胞在彼此之下,想想Instagram或Twitter的观点。我显然需要为单元格设置宽度约束,使其等于屏幕的整个宽度,但我似乎无法找到如何做到这一点。

我在AppDelegate中使用FlowLayout和estimatedItemSize:

let layout = UICollectionViewFlowLayout()
window?.rootViewController = UINavigationController(rootViewController: HomeController(collectionViewLayout: layout))

layout.estimatedItemSize = CGSize(width: 414, height: 150)

我还在viewDidLoad中为collectionView设置了约束,因此collectionView占据了屏幕的整个宽度和高度:

collectionView?.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
collectionView?.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
collectionView?.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true
collectionView?.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true

我对标签和textview的约束看起来像这样,也允许宽度采用所需的大小(所以它不是固定的):

// vertical constraints usernameLabel & commentTextView
addConstraintsWithFormat(format: "V:|-16-[v0]-2-[v1]-16-|", views: usernameLabel, commentTextView)

// horizontal constraints usernameLabel
addConstraintsWithFormat(format: "H:|-16-[v0]-16-|", views: usernameLabel)

// horizontal constraints commentTextView
addConstraintsWithFormat(format: "H:|-16-[v0]-16-|", views: commentTextView)

根据我的说法,这一切对于完成这项工作至关重要。但是,在我看来,我还没有设置宽度约束来使其工作。我试图在collectionView上添加一个widthAnchor(等于view.widthAnchor),这不起作用:

collectionView?.widthAnchor.constraint(equalTo: self.view.widthAnchor).isActive = true

我也尝试在sizeForItemAt方法中设置宽度,但这也不起作用:

return CGSize(width: view.frame.width, height: 100)

现在,我正在检查宽度以查看它出错的地方,但我得到了我需要的结果,我想:

print("collectionView width: ", collectionView?.frame.size.width)
print("collectionView height: ", collectionView?.frame.size.height)

print("screen width: ", UIScreen.main.bounds.width)
print("screen height: ", UIScreen.main.bounds.height)

结果是:

collectionView width:  Optional(414.0)
collectionView height:  Optional(736.0)
screen width:  414.0
screen height:  736.0

我不知道如何前进。我所经历的与此问题相关的所有文章或帖子要么明确地计算高度,要么使用我上面提到的两个解决方案。

关于我做错了什么的任何想法?

ios swift uicollectionview uicollectionviewcell uicollectionviewflowlayout
2个回答
0
投票

更新:

我根据Siju Satheesachandran的回答为我的HomeController添加了一个扩展:

extension HomeController {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: 400, height: 100)
    }
}

然后,在cellForItemAt方法中,我为当前单元格的宽度添加了一个print:

print("cell width: ", cell.frame.size.width)

返回五次以下:

cell width:  400.0

所以在我看来,听到了所需的大小,但是我的手机只能适应它想要的任何宽度?

另一个有趣的更新

当我将TextView的文本更改为某种方式太长时,它应该突破多行,并且我运行应用程序,应用程序在无法加载和显示黑屏时无限次地提供此调试错误:

2018-09-18 15:34:35.806688+0200 prjDynamicCells[39793:1627318] The behavior of the UICollectionViewFlowLayout is not defined because:
2018-09-18 15:34:35.807472+0200 prjDynamicCells[39793:1627318] the item width must be less than the width of the UICollectionView minus the section insets left and right values, minus the content insets left and right values.
2018-09-18 15:34:35.807572+0200 prjDynamicCells[39793:1627318] Please check the values returned by the delegate.
2018-09-18 15:34:35.807911+0200 prjDynamicCells[39793:1627318] The relevant UICollectionViewFlowLayout instance is <UICollectionViewFlowLayout: 0x7feb5ec17650>, and it is attached to <UICollectionView: 0x7feb5f841600; frame = (0 0; 414 736); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x60000044e6d0>; layer = <CALayer: 0x60000003f4a0>; contentOffset: {0, -64}; contentSize: {414, 1000}; adjustedContentInset: {64, 0, 0, 0}> collection view layout: <UICollectionViewFlowLayout: 0x7feb5ec17650>.
2018-09-18 15:34:35.808009+0200 prjDynamicCells[39793:1627318] Make a symbolic breakpoint at UICollectionViewFlowLayoutBreakForInvalidSizes to catch this in the debugger.

0
投票

确保在应用程序中添加此协议

UICollectionViewDelegate
UICollectionViewDataSource
UICollectionViewDelegateFlowLayout

请使用以下方法

    extension YourViewController: UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout {

        func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
             return CGSize(width: screenWidth, height: screenWidth)
        }

    }
© www.soinside.com 2019 - 2024. All rights reserved.