动态表格视图单元格在表格视图的特定部分内相互重叠

时间:2018-03-16 16:51:44

标签: ios swift mvvm tableview

我有一个视图控制器,它应该显示一个大文本(如文章,其中包含一些图像)。为此,我使用动态表视图。该表视图有三个部分:

第一行只有一行,单元格包含UIImageViewUILabel(标题)。

第二个行可以有不同的行数,每个单元格由UIImageViewUILabel组成。这是文章的实际文本和图像的位置。

最后一行只有一行,单元格由UIImageViewUILabel组成。这是关于作者的信息的地方。

现在,要实现这一点,我使用MVVM设计模式并从简单的JSON文件中获取信息。以下是模型的外观:

 struct Review: Codable {
var reviewTitleAndImage: ReviewTitle
var reviewTextAndImage: [ReviewTextAndImage]
var reviewAuthorInfo: AuthorInfo
}

struct ReviewTitle: Codable {
var imageName: String
var reviewTitle: String
}

struct ReviewTextAndImage: Codable {
var reviewText: String
var reviewImageName: String
}

struct AuthorInfo: Codable {
var authorName: String
var authorImageName: String
}

如您所见,它分为三个部分(标题信息,实际文本和作者信息)。

在我的 ViewModel 中,我使用enum来区分各个部分。这是它的样子:

 enum ReviewSectionTypes {
case title
case reviewText
case reviewAuthorInfo
}

我还定义了一个协议,每个项目(构造部分)应符合这个协议。它有两个属性:type和numberOfRows:

 protocol ReviewViewModelSectionItem {
var type: ReviewSectionTypes {get}
var numberOfRows: Int {get}
}

extension ReviewViewModelSectionItem {
var numberOfRows: Int {
    return 1
  }
}

以下是项目:

 class TitleItem: ReviewViewModelSectionItem {
var type: ReviewSectionTypes {
    return .title
}
var numberOfRows: Int {
    return 1
}

var titleImageName: String
var titleText: String

init(titleImageName: String, titleText: String) {
    self.titleImageName = titleImageName
    self.titleText = titleText
   }
}

class ReviewText: ReviewViewModelSectionItem {
var type: ReviewSectionTypes {
    return .reviewText
}

var numberOfRows: Int {

    return reviewTextsAndImages.count
}

var reviewTextsAndImages: [ReviewTextAndImage]

init (reviewTextsAndImages: [ReviewTextAndImage]) {
    self.reviewTextsAndImages = reviewTextsAndImages
 }
}

class ReviewAuthorInfo: ReviewViewModelSectionItem {
var type: ReviewSectionTypes {
    return .reviewAuthorInfo
}

var authorName: String
var authorImageName: String

init (authorName: String, authorImageName: String) {
    self.authorName = authorName
    self.authorImageName = authorImageName
}

}

在我ViewModel的初始化中,我解析了JSON并配置了每个项目。之后,我创建了三种类型的单元格,在表格视图中使用。

以下是表视图的dataSource(sectionItems是Array,其中包含在ViewModel初始化期间配置它们之后的项目:

func numberOfSections(in tableView: UITableView) -> Int {
    print ("SECTIONS NUMBER:", sectionItems.count)
    return sectionItems.count
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    print (sectionItems[section].numberOfRows, sectionItems[section].numberOfRows)
    return sectionItems[section].numberOfRows
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let sectionItem = sectionItems[indexPath.section]

    switch sectionItem.type {
    case .title:
        if let cell = tableView.dequeueReusableCell(withIdentifier: TitleTableViewCell.identifier, for: indexPath) as? TitleTableViewCell {
            cell.item = sectionItem
            return cell
        }

    case .reviewText:
        if let item = sectionItem as? ReviewText, let cell = tableView.dequeueReusableCell(withIdentifier: ReviewTextAndImageTableViewCell.identifier, for: indexPath) as? ReviewTextAndImageTableViewCell {
            cell.item = item.reviewTextsAndImages[indexPath.row]
            return cell
        }

    case .reviewAuthorInfo:
        if let cell = tableView.dequeueReusableCell(withIdentifier:    ReviewAuthorInfoTableViewCell.identifier, for: indexPath) as? ReviewAuthorInfoTableViewCell {
            cell.item = sectionItem
            return cell
        }
    }

    return UITableViewCell()
}

我的视图控制器

 @IBOutlet weak var tableView: UITableView!
var reviewViewModel = ReviewViewModel()


override func viewDidLoad() {
    super.viewDidLoad()

    tableView.dataSource = reviewViewModel
    tableView.estimatedRowHeight = 120
    tableView.rowHeight = UITableViewAutomaticDimension

    tableView.register(TitleTableViewCell.nib, forCellReuseIdentifier: TitleTableViewCell.identifier)
    tableView.register(ReviewTextAndImageTableViewCell.nib, forCellReuseIdentifier: ReviewTextAndImageTableViewCell.identifier)
    tableView.register(ReviewAuthorInfoTableViewCell.nib, forCellReuseIdentifier: ReviewAuthorInfoTableViewCell.identifier)
}

问题是,第一部分是正常设置的,但是,第二部分内部的单元格相互重叠,第三部分根本没有配置(出列方法没有得到)要求第三种类型的细胞)。因此,由于这些问题,表格视图无法完全向其底部滚动。

我认为问题与表格视图data source中的第二部分配置有关,但我无法找到它。

如果你知道导致这个问题的原因,或者你知道用图片实现长文本的更好方法(比如在文章中),我将非常感谢你的帮助和建议。

1 个答案:

答案 0 :(得分:1)

要发布是因为表格视图在第二部分中为行设置了错误的高度。为了解决这个问题,我使用了heightForRowAt UITableViewDelegate方法。在其中我返回UITableViewAutomaticDimension

我不确定原因,但在tableView内将rowHeight UITableViewAutomaticDimension属性设置为viewDidLoad不起作用。也许,那时单元格内的标签没有文字。

如果您知道具体原因,请与我们分享。

P.S。感谢@Damo向我展示了正确的思考方向。