在Swift中使用静态单元格和动态原型

时间:2019-06-10 10:28:29

标签: ios swift uitableview

我将tableview设为静态单元格。从那时起,我将这些部分分为两个部分,第1部分为静态单元格,第2部分为动态原型。但是,我想在表格视图中显示动态原型单元,以使第1部分不可见。

第1节(静态单元)是好的。请注意,此应用程序使用电影API显示电影信息。第1节使用静态单元格来表示电影的详细信息,第2节使用动态原型单元格来放置用户的评分。这部电影的细节讲得不错,但是添加动态原型失败了。

import UIKit

class MovieDetailViewController: UITableViewController {

    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var titleImage: UIImageView!
    @IBOutlet weak var gradeImage: UIImageView!
    @IBOutlet weak var dateLabel: UILabel!
    @IBOutlet weak var genreLabel: UILabel!
    @IBOutlet weak var durationLabel: UILabel!
    @IBOutlet weak var reservationRateLabel: UILabel!
    @IBOutlet weak var userRatingLabel: UILabel!
    @IBOutlet weak var audienceLabel: UILabel!
    @IBOutlet weak var sysnopsisTextView: UITextView!
    @IBOutlet weak var directorLabel: UILabel!
    @IBOutlet weak var actorLabel: UILabel!
    @IBOutlet weak var commentTableView: UITableView!

    var movieId: String?
    var movieDetail: MovieDetail?
    var movieCommentList: CommentList?

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.register(UINib(nibName: "CommentsCell", bundle: nil), forCellReuseIdentifier: "CommentsCell")

        MovieAPI.requestId(id: movieId ?? "") { (movieDetail, error) in

            self.movieDetail = movieDetail

            DispatchQueue.main.async {
                self.navigationController?.navigationBar.topItem?.title = "\(movieDetail?.title ?? "")"
                self.titleLabel.text = movieDetail?.title
                self.genreLabel.text = movieDetail?.genre
                self.dateLabel.text = movieDetail?.date
                self.durationLabel.text = ",\(movieDetail?.duration ?? 0)분"
                self.reservationRateLabel.text = "\(movieDetail?.reservationRate ?? 0)"
                self.userRatingLabel.text = "\(movieDetail?.userRating ?? 0)"
                self.audienceLabel.text = "\(movieDetail?.audience ?? 0)"
                self.sysnopsisTextView.text = movieDetail?.synopsis
                self.directorLabel.text = movieDetail?.director
                self.actorLabel.text = movieDetail?.actor
                self.gradeImage.image = UIImage(named: "\(movieDetail?.grade ?? 0)")
                self.handleImageResponse()
            }
        }

        MovieAPI.requestComments(id: movieId ?? "") { (movieComments, error) in


        }
    }

    func handleImageResponse() {
        guard let imageURL = URL(string: movieDetail?.image ?? "") else {
            return
        }

        MovieAPI.requestImageFile(url: imageURL, completionHandler: handleImageFileResponse(image:error:))
    }

    func handleImageFileResponse(image: UIImage?, error: Error?) {
        DispatchQueue.main.async {

            self.titleImage.image = image
        }
    }
}

//Dynamic prototype try!! -> failed
extension MovieDetailViewController {

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 2
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        if section == 1 {
            return movieCommentList?.comments.count ?? 0
        }
        return super.tableView(tableView, numberOfRowsInSection: section)
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cellId = "CommentsCell"
        let cell = self.commentTableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! CommentsCell

        cell.commentsView.text = movieCommentList?.comments[indexPath.row].contents

        return cell
    }
}

我想要的方向是按顺序排列第1部分(静态单元)和第2部分(动态原型)。

2 个答案:

答案 0 :(得分:0)

在我看来,numberOfRowsInSection()的默认实现将返回0行。您还必须为第2部分指定行数。

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if section == 1 {
        return movieCommentList?.comments.count ?? 0
    } 
    //Return number as per your requirement for section 2 
    return 2
}

答案 1 :(得分:0)

您的问题未得到正确的解释,主要是因为您使用的是错误的编码做法。 我建议要做的是制作一个“数据源”对象,其中将包含您的部分。

例如:

struct SectionItem {
   var header: String?
   var item: RowItem // where RowItem can be a protocol that your comment any object can be (Like the string from the contents property of your comment object)
}

然后,您可以制作一个由多个部分组成的数组。像这样,您不需要:

    if section == 1 {
        return movieCommentList?.comments.count ?? 0
    }
    return super.tableView(tableView, numberOfRowsInSection: section)

但是

return sections[indexPath.section].items.count

还有

override func numberOfSections(in tableView: UITableView) -> Int {
    return return sections.count
}

这种方式:

  • 您避免使用硬编码的值,这很难调试 比您想象的更大的项目
  • 您可以使用简单的多态性轻松地将项目更改为所需的任何内容
  • 您的列表将自动隐藏或显示您想要的部分,并且易于理解和解释,这是您当前代码无法做到的。