如何在 Swift 中使用多个标签单独调整 UICollectionViewCells?

How do I make individually self-sizing UICollectionViewCells with multiple labels in Swift?

这是我的视图控制器:

//  ReadArticleViewController.swift
//
//  Created by Nathan Cain on 11/26/14.
//  Copyright (c) 2014 Nathan Cain. All rights reserved.
//

import UIKit
import Realm

class ReadArticleViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource
{
    var pronunciationArray: [String] = []
    var wordArray: [String] = []

    @IBOutlet var collectionView: UICollectionView!

    @IBOutlet weak var flow: UICollectionViewFlowLayout!

    var article: Article?

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return pronunciationArray.count
    }

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
        return UIEdgeInsetsMake(20, 20, 20, 20)
    }

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let wordCell: ReadArticleCollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier("wordCell", forIndexPath: indexPath) as ReadArticleCollectionViewCell
        println(pronunciationArray[indexPath.row])
        wordCell.pronunciationLabel.text = convertPinyinNumbersToToneMarks(pronunciationArray[indexPath.row])
        println(wordArray[indexPath.row])
        wordCell.wordLabel.text = wordArray[indexPath.row]
        println("wordCell width is \(wordCell.frame.size.width.description)")
        return wordCell
    }

    override func viewDidLoad()
    {
        super.viewDidLoad()
        var Realm = RLMRealm.defaultRealm()

        // tell the collection view layout object to let the cells self-size
        var flowLayout = self.collectionView!.collectionViewLayout as UICollectionViewFlowLayout
        flowLayout.estimatedItemSize = CGSize(width: 25, height: 50)

        println(article!.articleContent)
        let paragraphObjectsRLMArray = article!.paragraphs

        for (index,paragraphObject) in enumerate(paragraphObjectsRLMArray)
        {
            var paragraph = paragraphObject as Paragraph

            var sentenceObjectsRLMArray = paragraph.sentences

            for sentenceObject in sentenceObjectsRLMArray
            {
                let sentence = sentenceObject as Sentence
                let wordObjectsRLMArray = sentence.words

                for (index,word) in enumerate(wordObjectsRLMArray)
                {

                    let word = word as Word
                    let index = UInt(index)

                    wordArray.append(word.simplified)

                    print("word #\(index + 1) is \(word.simplified); ")

                    let pinyinArray = word.pinyin
                    let pinyinObject = definitionObject.pinyin as Pinyin?
                    if let pronunciationText: String? = Optional(convertPinyinNumbersToToneMarks(pinyinObject!.pinyin)) {
                        if pronunciationText != ""{
                            pronunciationArray.append(pinyinObject!.pinyin)//.text = pronunciationText!
                        }
                        else
                        {
                            pronunciationArray.append(word.simplified)
                        }

                    }
                    else
                    {
                        pronunciationArray.append("")
                    }
                }
            }

        }

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

这是我的 collectionViewCell.swift

//
//  ReadArticleCollectionViewCell.swift
//
//  Created by Nathan Cain on 2/14/15.
//  Copyright (c) 2015 Nathan Cain. All rights reserved.
//

import UIKit

class ReadArticleCollectionViewCell: UICollectionViewCell {

    @IBOutlet weak var pronunciationLabel: UILabel!
    @IBOutlet weak var wordLabel: UILabel!

}

当我 运行 应用程序时,单元格不会调整它们的大小。这是启动时传递的 -UIViewShowAlignmentRects YES 参数的样子:

我希望每个单元格的大小都单独设置,刚好足以容纳其内容。

对我做错了什么有什么想法吗?

你应该处理 blockSizeForItemAtIndexPath。看看这里的项目是否有一些想法? https://github.com/bryceredd/RFQuiltLayout

每个集合视图都有一个关联的布局。您正在为该项目使用预制流布局。

更新 class 声明以表明它将符合流布局委托协议:

class ReadArticleViewController: UIViewController, 
                                 UICollectionViewDelegate, 
                                 UICollectionViewDataSource,     
                                 UICollectionViewDelegateFlowLayout

添加以下方法:

func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!,
                    sizeForItemAtIndexPath indexPath: NSIndexPath!) -> CGSize {

}

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

}

collectionView(_:layout:sizeForItemAtIndexPath:) 负责告诉布局给定单元格的大小。为此,您必须首先确定您正在查看的是哪个项目,因为每个项目可能有不同的尺寸。

collectionView(_:layout:insetForSectionAtIndex:) returns 单元格、页眉和页脚之间的间距。常量用于存储值。

有关更多信息,您可以阅读优秀的 Beginning iOS Collection Views in Swift: Part 1/2

希望对你有所帮助。

尝试在名为 sizeForItemAtIndexPath 的 collectionViewLayout 上实现委托方法,并return每个单元格的正确大小。

我通过在这个存储库中完成的操作之后对我的视图进行建模来做到这一点: https://github.com/algal/SelfSizingCellsDemo

首先你创建一个labelView,然后将它们添加到子视图(cell)中。然后你制作一个 newLabel 并调整它的大小等等。

接下来以编程方式设置自动布局约束。

最后你说self.labelView = newLabel