在ViewController中使用自定义的UITableViewCell w/external DataSource和UITableView
好吧,我想在UITableView中有一个自定义的UITableViewCell。在ViewController中使用自定义的UITableViewCell w/external DataSource和UITableView
我需要每一个部件的模块化和可重用的可能,所以我决定把他们都在不同的班级:
我的设置,现在看起来是这样的: 我有一个快速的文件我DataSoure,一个文件我的CustomTableViewCell和我的故事板我有一个UITableView旁边其他UIViees,我宣布要使用自定义单元格。
故事板是这样的:
我的ViewController类看起来是这样的:
import UIKit
class MyShitViewController: UIViewController, UITableViewDelegate {
@IBOutlet weak var importantTableView: UITableView!
var importantItems = [ContentItem]()
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
override func viewDidLoad() {
super.viewDidLoad()
// Test data
importantItems.append(ContentItem(contentType: 1, image: #imageLiteral(resourceName: "ContentIcon"), title: "SQL - Basics", subject: "informatics", grade: 11, progress: 35, action: ContentItem.ACTION_MORE))
importantItems.append(ContentItem(contentType: 1, image: #imageLiteral(resourceName: "ContentIcon"), title: "SQL - Pros", subject: "informatics", grade: 12, progress: 0, action: ContentItem.ACTION_MORE))
// Data source
let dataSource = ContentItemDataSource(items: importantItems)
importantTableView.rowHeight = 75
importantTableView.dataSource = dataSource
importantTableView.reloadData()
}
//MARK: Table view delegate
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// For debugging, never get's called, when some one clicks on any cell
let row = indexPath.row
print(row)
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
print("height")
return 48
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
print("estimated height")
return 48
}
}
我CustomTableViewCell类:
import UIKit
class ContentItemView: UITableViewCell {
//MARK: Properties
var contentItem: ContentItem?
private var contentImageView: UIImageView?
private var primaryTextView: UILabel?
private var secondaryTextView: UILabel?
private var progressView: UILabel?
private var actionView: UIButton?
private var verifiedIcon: UIImageView?
private var layoutConstraints: [NSLayoutConstraint] = []
//MARK: Initialisation
func setContent(item: ContentItem) {
self.contentItem = item
setContent()
}
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
print(style)
setUpView()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
print("coder")
setUpView()
}
//MARK: Set Up
private func setUpView() {
self.backgroundView?.backgroundColor = Colors.biology
self.textLabel?.text = "Test"
// Create views
contentImageView = UIImageView()
primaryTextView = UILabel()
secondaryTextView = UILabel()
progressView = UILabel()
actionView = UIButton()
verifiedIcon = UIImageView()
// Add Content to views
primaryTextView?.font = getFont(withSize: 14)
primaryTextView?.textColor = Colors.toolbarColor
secondaryTextView?.font = getFont(withSize: 12)
secondaryTextView?.textColor = Colors.toolbarColor
progressView?.font = getFont(withSize: 12)
progressView?.textColor = Colors.toolbarColor
// Add sub views
self.contentView.addSubview(contentImageView!)
self.contentView.addSubview(primaryTextView!)
self.contentView.addSubview(secondaryTextView!)
self.contentView.addSubview(progressView!)
self.contentView.addSubview(actionView!)
self.contentView.addSubview(verifiedIcon!)
// Apply Constraints
makeViewConstraints()
}
// MARK: Layout
private func setContent() {
contentImageView?.image = contentItem?.image
primaryTextView?.text = contentItem?.title
secondaryTextView?.text = (contentItem?.done)! ? "DONE" : (contentItem?.subject)! + " - " + getLocalizedGrade(_for: (contentItem?.grade)!)
progressView?.text = contentItem?.progress != nil ? "\(String(describing: contentItem?.progress))%" : ""
if (contentItem?.verified)! { verifiedIcon?.image = #imageLiteral(resourceName: "verified") }
else { verifiedIcon?.image = nil }
let actionImage = getActionImage()
actionView?.setImage(actionImage, for: .normal)
}
private func makeViewConstraints() {
// Clear constraints
self.contentView.removeConstraints(layoutConstraints)
layoutConstraints.removeAll()
// Force elements to exist
let imageView = self.contentImageView!
let primaryTextView = self.primaryTextView!
let secondaryTextView = self.secondaryTextView!
let progressView = self.progressView!
let actionView = self.actionView!
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.widthAnchor.constraint(equalToConstant: 48)
imageView.heightAnchor.constraint(equalToConstant: 48)
layoutConstraints.append(
NSLayoutConstraint(item: imageView, attribute: .leading, relatedBy: .equal,
toItem: self.contentView, attribute: .leading, multiplier: 1, constant: 0))
layoutConstraints.append(
NSLayoutConstraint(item: imageView, attribute: .centerY, relatedBy: .equal,
toItem: self.contentView, attribute: .centerY, multiplier: 1, constant: 0))
primaryTextView.translatesAutoresizingMaskIntoConstraints = false
layoutConstraints.append(
NSLayoutConstraint(item: primaryTextView, attribute: .leading, relatedBy: .equal,
toItem: imageView, attribute: .trailing, multiplier: 1, constant: 16))
layoutConstraints.append(
NSLayoutConstraint(item: primaryTextView, attribute: .top, relatedBy: .equal,
toItem: self.contentView, attribute: .top, multiplier: 1, constant: 8))
secondaryTextView.translatesAutoresizingMaskIntoConstraints = false
layoutConstraints.append(
NSLayoutConstraint(item: secondaryTextView, attribute: .leading, relatedBy: .equal,
toItem: imageView, attribute: .trailing, multiplier: 1, constant: 16))
layoutConstraints.append(
NSLayoutConstraint(item: secondaryTextView, attribute: .bottom, relatedBy: .equal,
toItem: self.contentView, attribute: .bottom, multiplier: 1, constant: -8))
progressView.translatesAutoresizingMaskIntoConstraints = false
layoutConstraints.append(
NSLayoutConstraint(item: progressView, attribute: .centerX, relatedBy: .equal,
toItem: imageView, attribute: .centerX, multiplier: 1, constant: 0))
layoutConstraints.append(
NSLayoutConstraint(item: progressView, attribute: .centerY, relatedBy: .equal,
toItem: imageView, attribute: .centerY, multiplier: 1, constant: 0))
actionView.translatesAutoresizingMaskIntoConstraints = false
layoutConstraints.append(
NSLayoutConstraint(item: actionView, attribute: .trailing, relatedBy: .equal,
toItem: self.contentView, attribute: .trailing, multiplier: 1, constant: 0))
layoutConstraints.append(
NSLayoutConstraint(item: actionView, attribute: .centerY, relatedBy: .equal,
toItem: self.contentView, attribute: .centerY, multiplier: 1, constant: 0))
self.contentView.addConstraints(layoutConstraints)
}
// MARK: Additional Helpers
private func getActionImage() -> UIImage? {
if contentItem?.action == ContentItem.ACTION_MORE {
return #imageLiteral(resourceName: "ic_more_horiz_white")
}
if contentItem?.action == ContentItem.ACTION_ADD {
return #imageLiteral(resourceName: "ic_add_circle_outline_white")
}
if contentItem?.action == ContentItem.ACTION_REMOVE {
return #imageLiteral(resourceName: "ic_remove_circle_outline_white")
}
return nil
}
}
最后我的数据源:
import UIKit
class ContentItemDataSource: NSObject, UITableViewDataSource {
var items = [ContentItem]()
init(items: [ContentItem]) {
self.items = items
}
// MARK: - Table view data source
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let item = items[indexPath.row]
guard let cell = tableView.dequeueReusableCell(withIdentifier: Config.CONTENT_ITEM_CELL, for: indexPath) as? ContentItemView else {
fatalError("The dequeued cell is not an instance of ContentItemView.")
}
cell.setContent(item: item)
return cell
}
}
我不知道为什么它不工作,可能是因为预期或指定数据源到TableView中的数据源不工作...
的CustomTableViewCell应该没有问题,因为它之前的工作原理,我更改了我的视图添加到self.contentView
的代码。
数据源定义为弱:
weak open var dataSource: UITableViewDataSource?
您的代码:
let dataSource = ContentItemDataSource(items: importantItems)
importantTableView.dataSource = dataSource
你做没有提供参考,因此方法结束后再次为零。
解决方案:定义一个类var并按需要保存它。
var dataSource: UITableViewDataSource!
和:
let dataSource = ContentItemDataSource(items: importantItems)
importantTableView.dataSource = dataSource
self.dataSource = dataSource
和顺便说一下:你不设置'importantTableView.delegate = self'。 – ObjectAlchemist
噢好点:D我有它在那里一段时间:)但我用了一个插座,因为我尝试了很多事情来让它工作,并认为这可能解决问题,因为我在其他项目中看到它。猜猜是什么:它没有 –
非常感谢,我甚至没有想到这个事实。你让我跳投我的房间,因为它终于为我解决:D –
你似乎是有意编码可重用的组件。也许这个链接是你感兴趣的:http://*.com/a/43426337/6595536 – ObjectAlchemist
这是一个非常有趣的方式来编写一个应用程序:D 我会记住我的下一个项目:) –