Swift - How to expand cell in UICollectionView
<p>I currently have a UICollectionView to create a news page with several news items, kind of like what Facebook is using. Because I am not using a live server just yet, I am trying to code most of the functionalities by using temporary static entries (see code).</p>

<p>My next goal: <strong>I would like to add "show more" to a news cell when the text inside that cell is longer than I want it to be. Tapping "show more" will expand the cell and display the rest of the text. Tapping it again will set it back to its initial height.</strong>  </p>

<pre><code>let cellId = "cellId"

class Post {
    var title: String?
    var statusText: String?
    var nameDate: String?
}

class NewsController: UICollectionViewController, UICollectionViewDelegateFlowLayout {

var posts = [Post]()

override func viewDidLoad() {

    super.viewDidLoad()

    let postDennis = Post()
    postDennis.title = "How to start programming in Swift!"
    postDennis.statusText = "Swift is a powerful and intuitive programming language for macOS, iOS, watchOS and tvOS. Writing Swift code is interactive and fun, the syntax is concise yet expressive, and Swift includes modern features developers love. Swift code is safe by design, yet also produces software that runs lightning-fast. Swift is free and open source, and it’s available to a wide audience of developers, educators and students under the Apache 2.0 open-source licence."
    postDennis.nameDate = "\nAugust 21st, Dennis van Mazijk"

    let postMai = Post()
    postMai.title = "What is Swift?"
    postMai.statusText = "Hello, this is some news!"
    postMai.nameDate = "\nAugust 18th, Mai Satou"

    posts.append(postDennis)
    posts.append(postMai)

    collectionView?.alwaysBounceVertical = true
    collectionView?.contentInset = UIEdgeInsets(top: 10, left: 0, bottom: 0, right: 0)
    collectionView?.backgroundColor = UIColor(white: 0.95, alpha: 1)
    collectionView?.registerClass(FeedCell.self, forCellWithReuseIdentifier: cellId)
}

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

override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -&gt; Int {
    return posts.count
}

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -&gt; UICollectionViewCell {
    let feedCell = collectionView.dequeueReusableCellWithReuseIdentifier(cellId, forIndexPath: indexPath) as! FeedCell

    feedCell.post = posts[indexPath.item]

    return feedCell
}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -&gt; CGSize {

    if let statusText = posts[indexPath.item].statusText {
        let rect = NSString(string: statusText).boundingRectWithSize(CGSizeMake(view.frame.width, 1000), options: NSStringDrawingOptions.UsesFontLeading.union(NSStringDrawingOptions.UsesLineFragmentOrigin), attributes: [NSFontAttributeName: UIFont.systemFontOfSize(14)], context: nil)

        let cellHeight: CGFloat = 40

        return CGSizeMake(view.frame.width, rect.height + cellHeight)
    }

    return CGSizeMake(view.frame.width, 100)
}
}

class FeedCell: UICollectionViewCell {

var post: Post? {

    didSet {

        if let header = post?.title {
            if let extra = post?.nameDate {

                let attributedText = NSMutableAttributedString(string: header.trunc(40), attributes: [NSFontAttributeName: UIFont.boldSystemFontOfSize(14)])

                attributedText.appendAttributedString(NSAttributedString(string: extra, attributes: [NSFontAttributeName: UIFont.boldSystemFontOfSize(12), NSForegroundColorAttributeName: UIColor(red: 155/255, green: 161/255, blue: 171/255, alpha: 1)]))

                let paragraphStyle = NSMutableParagraphStyle()
                paragraphStyle.lineSpacing = 4

                attributedText.addAttribute(NSParagraphStyleAttributeName, value: paragraphStyle, range: NSMakeRange(0, attributedText.string.characters.count))

                nameLabel.attributedText = attributedText
            }
        }

        if let statusText = post?.statusText {
            statusTextView.text = statusText
        }
    }
}

override init(frame: CGRect) {
    super.init(frame: frame)

    setupViews()
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

let nameLabel: UILabel = {
    let label = UILabel()
    label.numberOfLines = 2
    return label
}()

let profileImageView: UIImageView = {
    let imageView = UIImageView()
    imageView.image = UIImage(named: "news_profile")
    imageView.contentMode = .ScaleAspectFit
    return imageView
}()

let statusTextView: UITextView = {
    let textView = UITextView()
    textView.scrollEnabled = false
    return textView
}()


func setupViews() {
    backgroundColor = UIColor.whiteColor()

    addSubview(nameLabel)
    addSubview(profileImageView)
    addSubview(statusTextView)

    addConstraintsWithFormat("H:|-8-[v0(44)]-8-[v1]|", views: profileImageView, nameLabel)

    addConstraintsWithFormat("H:|-4-[v0]-4-|", views: statusTextView)

    addConstraintsWithFormat("V:|-12-[v0]", views: nameLabel)

    addConstraintsWithFormat("V:|-8-[v0(44)]-4-[v1]", views: profileImageView, statusTextView)
}
}
</code></pre>