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.
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.
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. 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. Should I do this in TableView? I thought that collectionView is better approach and easier for design-wise.
Here are codes for this page 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.
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.
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.
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
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. I have made it, so I am moving to next level of this app.
Thank you all help ;)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.