我正在尝试创建一个UITableTableView单元格,该界面可以在Interface Builder上看到,并调用prepareForInterfaceBuilder()。我想要实现的功能是能够编辑单元格并在IB上实时查看结果并检查单元格大小是否正确,而不必继续在手机上运行它们进行检查。
我创建了一个名为TestCell的简单单元,该单元具有两个标签。当我在手机上运行此程序时,它按预期出现。但是,在“界面构建器”上,当我在ViewController上显示tableView时,该单元格未显示UILabel。我认为问题在于两个UILabel。起初,我收到“代理崩溃”错误消息。当我检查这些值是否为零时,IB不会崩溃,但也不会显示UILabels。下面是我正在使用的代码。 UILabels不显示在IB中是有原因的吗?我在做我做不到的事情吗?我知道单元格正在被调用,因为我将背景色设置为绿色并且确实显示在IB上。
class ViewController: UIViewController {
@IBOutlet weak var viewWithTableView: ViewWithTableView!
var fakeData:FakeData!
override func viewDidLoad() {
super.viewDidLoad()
let a = Information(text: "Lorem", number: 5)
let b = Information(text: "Ipsum", number: 10)
let c = Information(text: "Dolar", number: 1)
let d = Information(text: "Sit", number: 2)
let e = Information(text: "Amet", number: 7)
fakeData = FakeData(info: [a,b,c,d,e])
self.viewWithTableView.tableView.dataSource = self
}
}
//This is the coded called by phone which is working as expected
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let fakeData = self.fakeData {
return fakeData.info.count
}
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TestCell") as! TestCell
if let fakeData = self.fakeData {
let info = fakeData.info[indexPath.row]
cell.configureCell(info: info)
}
return cell
}
}
@IBDesignable class ViewWithTableView: UIView, NibLoadable {
@IBOutlet weak var tableView: TestUITableView!
var fakeData:FakeData!
public override init(frame: CGRect) {
super.init(frame: frame)
self.setupFromNib()
self.commonInit()
}
public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setupFromNib()
self.commonInit()
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
self.commonInit()
let a = Information(text: "apple", number: 5)
let b = Information(text: "orange", number: 10)
let c = Information(text: "pear", number: 1)
let d = Information(text: "banana", number: 2)
let e = Information(text: "strawberry", number: 7)
fakeData = FakeData(info: [a,b,c,d,e]
)
self.tableView.dataSource = self
self.tableView.reloadData()
}
func commonInit() {
tableView.registerCells(nibNames: [.TestCell])
tableView.backgroundColor = .yellow
}
}
//This is how I'm trying to get the cells to appear live on interface builder.
extension ViewWithTableView: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let fakeData = self.fakeData {
return fakeData.info.count
}
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = TestCell(style: .default, reuseIdentifier: "TestCell")
cell.backgroundColor = .green
//This line causes 'The agent crashed' error message, presumabbly because the UILabel is nil for some reason?
//cell.infoLabel.text = "hello world"
return cell
}
//When I try to dequeueReusableCell it doesn't return a cell as box storyboard remains a blank white colour.
// func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//
// let cell = tableView.dequeueReusableCell(withIdentifier: "TestCell") as! TestCell
//
// if let fakeData = self.fakeData {
// let info = fakeData.info[indexPath.row]
// cell.configureCell(info: info)
// }
//
// return cell
// }
}
@IBDesignable class TestCell: UITableViewCell {
@IBOutlet weak var infoLabel: UILabel!
@IBOutlet weak var numberLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
self.preservesSuperviewLayoutMargins = false
self.separatorInset = UIEdgeInsets.zero
self.layoutMargins = UIEdgeInsets.zero
self.selectionStyle = .none
}
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
func configureCell(info:Information) {
// Having to check here is infoLabel != nil as this seems to be the error. If I don't do this check I get
if infoLabel != nil {
infoLabel.text = info.text
}
if numberLabel != nil {
numberLabel.text = "\(info.number)"
}
}
}