简体   繁体   English

快速的CollectionView单元格textLabel自动调整大小

[英]swift CollectionView cell textLabel auto resize

I have watch a lot of YT tutorials for UICollectionView and UITableView, even this app that I am searching help for is made by watching and reading several tutorials, but there is one problem I can not find. 我看过很多关于UICollectionView和UITableView的YT教程,即使我正在寻找帮助的该应用程序也是通过观看和阅读几个教程而制成的,但是我找不到一个问题。

This app is made that user decide for its Username and wrote some text with that username. 该应用由用户决定其用户名,并使用该用户名编写了一些文本。 I have made this with Firebase, connect everything, even post is getting back to app, but problem is that is always showing only two lines of text. 我已经使用Firebase做到了这一点,连接了所有东西,甚至发布都回到了应用程序中,但是问题是总是只显示两行文本。

This is how it look, so you can imagine better: 这是它的外观,因此您可以想象得更好:

在此处输入图片说明

I would like that textLabel above Username expands towards down with full text written inside. 我希望用户名上方的textLabel向下扩展,里面写有全文。 Number of lines on that text Label are set to 0. I have tried several things in storyboard, with a lot of different codes and approaches, but result is always the same. 该文本Label上的行数设置为0。我在情节提要中尝试了几件事,使用了许多不同的代码和方法,但结果始终相同。 Should I do this in TableView? 我应该在TableView中执行此操作吗? I thought that collectionView is better approach and easier for design-wise. 我认为collectionView是更好的方法,更易于进行设计。

Here are codes for this page VC: 这是此页面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)
    }*/
}

You can see that some codes that I have testing it are now in "comment" way, because they did nothing different. 您可以看到我已经对其进行测试的某些代码现在处于“注释”方式,因为它们没有什么不同。

Can you please tell me what I am doing wrong? 你能告诉我我做错了吗? Is it something in storyboard, or did I insert wrong code, maybe did not inserted any needed code at all? 这是情节提要中的问题,还是我插入了错误的代码,也许根本没有插入任何需要的代码?

You can update label's preferredWidth or alternatively just add a height constraint with greater than or equal to value. 您可以更新标签的preferredWidth或者仅添加一个大于或等于value的高度约束。

PS Make sure you have numberOfLines property set to 0 so the label doesn't have max number of lines which will truncate the string as well. PS确保将numberOfLines属性设置为0,以便标签没有将截断字符串的最大行数。

You can assign a dynamic height for each cell based on estimating the height that your string will take. 您可以基于估计字符串将采用的高度,为每个单元格分配动态高度。 Then if numberOfLines for your label set to 0 (infinite) or let's say 4 ~ 5 then it will work as you want. 然后,如果您的标签的numberOfLines设置为0 (无穷大),或者说是numberOfLines ,那么它将按您希望的那样工作。

Notice : the height constraint for your label inside each cell also should be set in a way that can extend up to a number of lines you want to display. 注意:每个单元格内标签的高度限制也应设置为可以扩展到要显示的多行的方式。

Estimate the height of string: 估计字符串的高度:

 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 Layout delegate 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 )
}

Thank you all. 谢谢你们。 You have been right. 你说的没错。 I have made it in TableView and it is much easier with same result. 我已经在TableView中做到了,而且结果相同也容易得多。 I have made it, so I am moving to next level of this app. 我已经做到了,因此我将移至此应用程序的下一个层次。

Thank you all help ;) 谢谢大家的帮助;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM