Swift - 如何在UICollectionView中扩展单元格

时间:2016-08-18 15:04:01

标签: ios swift uicollectionview

我目前有一个UICollectionView来创建一个包含多个新闻项目的新闻页面,就像Facebook正在使用的那样。因为我还没有使用实时服务器,所以我尝试使用临时静态条目来编写大部分功能(参见代码)。

我的下一个目标:我想在新闻单元格中添加“show more”,因为该单元格中的文本比我想要的长。点击“显示更多”将扩展单元格并显示文本的其余部分。再次点击它会将其设置回初始高度。

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) -> Int {
    return posts.count
}

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> 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) -> 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)
}
}

1 个答案:

答案 0 :(得分:2)

您已经实施了sizeForItemAtIndexPath。现在,您希望保留一组选定的单元格索引,并在indexPath.item包含在新数组中时修改cellHeight的值。为此,当有人点击“显示更多”按钮时,您将触发reloadRowsAtIndexPaths

如果您当前正在修剪它,也可以在您的cellForItemAtIndexPath中使用此新数组来更改单元格中的numberOfLines。