Ios 在Swift中使用以编程方式创建的UITableViewCell子类
我正在处理一个带有自定义单元格的表视图,该单元格是通过编程方式创建的,没有使用IB。我在Google上四处查看,在NSChat中四处询问,但我仍然无法让它工作。它只显示默认的表视图。提前谢谢 EventCell.swiftIos 在Swift中使用以编程方式创建的UITableViewCell子类,ios,uitableview,swift,Ios,Uitableview,Swift,我正在处理一个带有自定义单元格的表视图,该单元格是通过编程方式创建的,没有使用IB。我在Google上四处查看,在NSChat中四处询问,但我仍然无法让它工作。它只显示默认的表视图。提前谢谢 EventCell.swift import UIKit class EventCell: UITableViewCell { var eventName: UILabel = UILabel() var eventCity: UILabel = UILabel() var ev
import UIKit
class EventCell: UITableViewCell {
var eventName: UILabel = UILabel()
var eventCity: UILabel = UILabel()
var eventTime: UILabel = UILabel()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.contentView.addSubview(eventName)
self.contentView.addSubview(eventCity)
self.contentView.addSubview(eventTime)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func layoutSubviews() {
super.layoutSubviews()
eventName = UILabel(frame: CGRectMake(20, 10, self.bounds.size.width - 40, 25))
eventCity = UILabel(frame: CGRectMake(0, 0, 0, 0))
eventTime = UILabel(frame: CGRectMake(0, 0, 0, 0))
}
}
ViewController.swift
class ViewController: UITableViewController, UITableViewDelegate {
var events: Dictionary<String, [String]> = ["0": ["Monroe Family", "La Cañada", "8:30"]]
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self;
tableView.delegate = self;
tableView.registerClass(EventCell.self, forCellReuseIdentifier: "EventCell")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension;
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return events.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cellIdendifier: String = "EventCell"
var cell: EventCell = tableView.dequeueReusableCellWithIdentifier(cellIdendifier, forIndexPath: indexPath) as EventCell
cell = EventCell(style: .Default, reuseIdentifier: cellIdendifier)
if let i = events[String(indexPath.row)] {
cell.eventName.text = i[0]
cell.eventCity.text = i[1]
cell.eventTime.text = i[2]
}
cell.sizeToFit()
return cell
}
}
类ViewController:UITableViewController、UITableViewDelegate{
var事件:Dictionary=[“0”:[“门罗家族”、“拉卡尼亚达”、“8:30”]]
重写func viewDidLoad(){
super.viewDidLoad()
tableView.dataSource=self;
tableView.delegate=self;
注册表类(EventCell.self,forCellReuseIdentifier:“EventCell”)
}
重写函数didReceiveMemoryWarning(){
超级。我收到了记忆警告()
}
重写func tableView(tableView:UITableView,EstimatedHeightForrowatineXpath indexPath:NSIndexPath)->CGFloat{
返回UITableViewAutomaticDimension;
}
重写func tableView(tableView:UITableView,numberofrowsinssection:Int)->Int{
return events.count
}
重写func tableView(tableView:UITableView,cellForRowAtIndexPath:nsindepath)->UITableView单元格{
var-cellIdendifier:String=“EventCell”
var cell:EventCell=tableView.dequeueReusableCellWithIdentifier(CellIdIndifier,forIndexPath:indexPath)作为EventCell
cell=EventCell(样式:。默认,reuseIdentifier:cellIdentifier)
如果let i=events[String(indexPath.row)]{
cell.eventName.text=i[0]
cell.eventCity.text=i[1]
cell.eventTime.text=i[2]
}
cell.sizeToFit()
返回单元
}
}
好的,首先是一些重要的评论
首先,每次表视图请求一个单元格时,您都不需要创建自己的新单元格,而不是重用旧单元格。您应该删除此行:
cell = EventCell(style: .Default, reuseIdentifier: cellIdendifier)
这是不必要的,因为出列将根据您为给定标识符注册的类根据需要自动创建新单元
其次,在布局代码时不应使用主屏幕边界。如果您的表视图不是全宽,则会发生故障。相反,您可以使用self.bounds
,使其始终相对于单元格本身
第三个,您不应该调用setNeedsLayout或layoutIfNeeded,因为如果调用该方法,它已经在重新布置所有内容
第四个,您应该在设置表视图数据源之前注册表视图单元格类,以防UITableView在设置数据源时开始从数据源请求内容
第五个,您的两个子视图的大小为0,0,因此它们无论如何都不会显示
如果此代码确实在运行而没有崩溃,那么您正在创建EventCells,因为您正在根据
dequeueReusableCellWithIdentifier:forIndexPath
的结果进行强制强制强制转换。这意味着您只是有一个布局/显示/数据问题。您的特定代码无法工作,因为它正在EventCell.LayoutSubView中创建新的UILabel。只有初始UILabel被添加到视图树中,它们的大小可能为0'd
我猜您打算更新他们的帧,例如更新EventCell类方法:
override func layoutSubviews() {
super.layoutSubviews()
eventName.frame = CGRectMake(20, 10, self.bounds.size.width - 40, 25)
eventCity.frame = CGRectMake(<actual size>)
eventTime.frame = CGRectMake(<actual size>)
}
覆盖函数布局子视图(){
super.layoutSubviews()
eventName.frame=CGRectMake(20,10,self.bounds.size.width-40,25)
eventCity.frame=CGRectMake()
eventTime.frame=CGRectMake()
}
您可以在swift中使用惰性实例化,以避免陷入布局子视图/视图生命周期舞蹈
class EventCell: UITableViewCell {
lazy public var lblName = {
return UILabel (frame: CGRectMake(10, 0, self.bounds.size.width , 40))
}()
lazy public var lblCity = {
return UILabel (frame: CGRectMake(10, 40, self.bounds.size.width , 20))
}()
lazy public var lblTime = {
return UILabel (frame: CGRectMake(self.bounds.size.width - 80, 10, , 25))
}()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.contentView.addSubview(lblName)
self.contentView.addSubview(lblCity)
self.contentView.addSubview(lblTime)
}
}
我也有同样的问题。我在@drewag的回答中应用了这个建议,但还有一些额外的问题。下面是一个简单的概念验证示例,演示如何使用编程创建的
UITableViewCell
子类
下图是它应该是什么样子。黄色矩形是自定义单元格中的UILabel
子视图
代码
下面是UITableViewCell子类。它的工作是初始化单元格及其内容、添加子视图和布局子视图
import UIKit
class MyCustomCell: UITableViewCell {
var myLabel = UILabel()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
myLabel.backgroundColor = UIColor.yellowColor()
self.contentView.addSubview(myLabel)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func layoutSubviews() {
super.layoutSubviews()
myLabel.frame = CGRect(x: 20, y: 0, width: 70, height: 30)
}
}
这是视图控制器代码
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
let myArray = ["one", "two", "three", "four"]
let cellReuseIdendifier = "cell"
override func viewDidLoad() {
super.viewDidLoad()
tableView.registerClass(MyCustomCell.self, forCellReuseIdentifier: cellReuseIdendifier)
tableView.dataSource = self
tableView.delegate = self
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myArray.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(cellReuseIdendifier, forIndexPath: indexPath) as! MyCustomCell
cell.myLabel.text = myArray[indexPath.row]
return cell
}
}
笔记:
- 我使用了常规的
,而不是UIViewController
。如果使用UITableViewController
,请删除UITableViewController
和UITableViewDelegate
协议引用,因为它们对于UITableViewDataSource
是多余的。您也不需要UITableViewController
行李>@IBOutlet tableView
- 我在原始问题中发现的主要问题是
。相反,它应该是eventName=UILabel(frame:CGRectMake(…)
eventName.frame=CGRect(…)
init(style:reuseIdentifier:)
。然后你可以像平常一样将它出列。@drewag但是出列函数不会使用我的自定义函数,如果我手动初始化它,那么出列就不会做任何事情,因为我总是初始化它,对吗?有没有办法知道出列是在创建一个新单元(然后我可以使用我自己的init)还是在重用一个单元(然后我让它去做,我不做init)?。我