swift CollectionView单元格textLabel自动调整大小

时间:2017-08-14 14:43:14

标签: ios swift swift3

我已经为UICollectionView和UITableView观看了很多YT教程,即使是我正在寻找帮助的这个应用程序也是通过观看和阅读几个教程来完成的,但是有一个我找不到的问题。

此应用程序是由用户决定其用户名并使用该用户名写入一些文本。我已经使用Firebase制作了这个,连接所有内容,甚至帖子都回到应用程序,但问题是它总是只显示两行文字。

这就是它的外观,所以你可以想象得更好:

enter image description here

我希望用户名上面的textLabel向下扩展,内写全文。 该文本标签上的行数设置为0.我在故事板中尝试了几个东西,有很多不同的代码和方法,但结果总是一样的。 我应该在TableView中执行此操作吗?我认为collectionView是更好的方法,更容易设计。

以下是此页面的代码VC:

import UIKit
import Firebase

class FeedViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {

    @IBOutlet weak var collectionView: UICollectionView!

    override func viewDidLoad() {
        super.viewDidLoad()
        loadData()
    }

    var fetchPosts = [Post]()

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    func loadData() {
        self.fetchPosts.removeAll()
        let ref = Database.database().reference()
        ref.child("Frusters").observeSingleEvent(of: .value, with: { (snapshot) in
            if let postDict = snapshot.value as? [String:AnyObject] {
                for (_,postElement) in postDict {
                    print(postElement);
                    let post = Post()
                    post.username = postElement["Username"] as? String
                    post.message = postElement["Message"] as? String
                    self.fetchPosts.append(post)
                }
            }
            self.collectionView.reloadData()

        }) { (error) in
            print(error.localizedDescription)
        }
        ref.removeAllObservers()
    }

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

        let deviceSize = UIScreen.main.bounds.size
        //let cellSize = sqrt(Double(deviceSize.width * deviceSize.height) / (Double(33)))

        let cellWidth = ((deviceSize.width / 2) - 10)
        let cellHeight = (deviceSize.height / 4)

        return CGSize(width: cellWidth , height: cellHeight)
    }*/

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "messageCell", for: indexPath) as! PostCell

        cell.messageLabel.text = self.fetchPosts[indexPath.row].message
        cell.usernameLabel.text = self.fetchPosts[indexPath.row].username

        return cell
    }

    /*func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeFotItemAt indexPath: IndexPath) -> CGSize {
        return CGSize (width: view.frame.width, height: 500)
    }*/
}

你可以看到我测试它的一些代码现在在"评论"方式,因为他们没有什么不同。

你能告诉我我做错了什么吗?它是故事板中的东西,还是我插入了错误的代码,可能根本没有插入任何所需的代码?

3 个答案:

答案 0 :(得分:0)

您可以更新标签preferredWidth,或者只是添加一个大于或等于值的高度约束。

P.S。确保将numberOfLines属性设置为 0 ,这样标签的最大行数也不会截断字符串。

答案 1 :(得分:0)

您可以根据估计字符串的高度为每个单元格指定动态高度。然后,如果您的标签的numberOfLines设置为0(无限)或者说4~5,那么它将按您的意愿运行。

注意:每个单元格内标签的高度约束也应设置为可以扩展到要显示的行数。

估计字符串的高度:

 extension String {
   func height(withConstrainedWidth width: CGFloat, font: UIFont) -> CGFloat {
      let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
      let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil)

       return ceil(boundingBox.height)
   }
}

UICollectionView布局委托

 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeFotItemAt indexPath: IndexPath) -> CGSize {
   let messageHeight = self.fetchPosts[indexPath.row].message.height(yourConstrainedWidth, yourFont)
   let height = height of other stuff including margins  +  messageHeight 
   return CGSize (width: view.frame.width, height: height )
}

答案 2 :(得分:0)

谢谢大家。你是对的。我已经在TableView中创建了它,并且使用相同的结果更容易。我已经做到了,所以我正在转向这个应用程序的下一个级别。

谢谢大家的帮助;)