我有一个视图控制器,它应该显示一个大文本(如文章,其中包含一些图像)。为此,我使用动态表视图。该表视图有三个部分:
第一行只有一行,单元格包含UIImageView
和UILabel
(标题)。
第二个行可以有不同的行数,每个单元格由UIImageView
和UILabel
组成。这是文章的实际文本和图像的位置。
最后一行只有一行,单元格由UIImageView
和UILabel
组成。这是关于作者的信息的地方。
现在,要实现这一点,我使用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
中的第二部分配置有关,但我无法找到它。
如果你知道导致这个问题的原因,或者你知道用图片实现长文本的更好方法(比如在文章中),我将非常感谢你的帮助和建议。
答案 0 :(得分:1)
要发布是因为表格视图在第二部分中为行设置了错误的高度。为了解决这个问题,我使用了heightForRowAt UITableViewDelegate
方法。在其中我返回UITableViewAutomaticDimension
。
我不确定原因,但在tableView
内将rowHeight
UITableViewAutomaticDimension
属性设置为viewDidLoad
不起作用。也许,那时单元格内的标签没有文字。
如果您知道具体原因,请与我们分享。
P.S。感谢@Damo向我展示了正确的思考方向。