storyboad的拖拽关联给我们开发带来了很大的便利,但是在目前的很多公司进行IOS开发时是禁止员工使用storyboard的,纯代码的实现方式仍然是主流,对于Swift这样一门新兴语言,加强语言的使用,使用纯代码来实现,不仅迎合了目前公司的用人要求,也更有利于我们深入理解Swift语法。本话不会有什么新的功能展示,主要目的是用纯代码来实现之前的tableviewcell。
首先要做的第一步就是取消之前storyboard中的所有设置,取消我们拖拽的那些关联,还有类型的关联,恢复默认值。如下图所示
先从viewConroller开始修改。修改方法viewDidLoad,修改如下:
override func viewDidLoad() {
super.viewDidLoad()
var tableView = UITableView(frame: CGRectMake(0, 0, 320, 568), style: UITableViewStyle.Plain)//定义一个tableview
self.view.addSubview(tableView)//不添加看不到
tableView.dataSource = self
tableView.delegate = self //之前是在storyboard中设置的,现在改为手动设置
// Do any additional setup after loading the view, typically from a nib.
}
写一个设置行高的代理方法,把行高定为80:
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 80
}
关于tableview的设置都完成了,剩下的就是关于cell的设置。我们在上一话中自定义了一个cell的类customTableViewCell,现在回到这个类中进行修改,因为不使用storyboard了,所以不能再把属性定义成IBOutlet,添加init方法,init方法中首先调用父类的init方法,并且子类的init方法需要复写,并且会提示你添加另一个方法,直接添加就好。修改后的customTableViewCell类如下:
class CustomTableViewCell: UITableViewCell {
var nameLabel: UILabel!
var locationLabel: UILabel!
var typeLabel: UILabel!
var thumbnailImageView: UIImageView!
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
现在需要设定cell中组件的属性,参考如下:
func setupUI(){
var subFrame = CGRectZero
//image
subFrame.origin.x = 15
subFrame.origin.y = 10
subFrame.size.width = 60
subFrame.size.height = 60
thumbnailImageView = UIImageView(frame: subFrame)
self.contentView.addSubview(thumbnailImageView)
//name label
subFrame.origin.x = 86
subFrame.origin.y = 9
subFrame.size.width = 205
subFrame.size.height = 21
nameLabel = UILabel(frame: subFrame)
self.contentView.addSubview(nameLabel)
//location label
subFrame.origin.x = 86
subFrame.origin.y = 30
locationLabel = UILabel(frame: subFrame)
self.contentView.addSubview(locationLabel)
//type label
subFrame.origin.x = 86
subFrame.origin.y = 54
typeLabel = UILabel(frame: subFrame)
self.contentView.addSubview(typeLabel)
}
别忘了在init中调用setupUI方法。之后回到ViewController类中,在cell的代理方法中,增加一个判断语句,给予cell初始化,代码如下:
if cell == nil {
cell = CustomTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: identiString)
}
我们会发现虽然以上的逻辑很简单,但是在添加以后报错了,大部分教材都在推崇storyboard的方式,所以网上能找到的纠错方法真的很少,Swift是个很严谨的语言,尤其是?和!的使用,让博主到现在都有点摸不着头脑。下面来说说如何消去错误。首先if语句中的cell不能用CustomTableViewCell的构造方法,而需要用原始的UItableViewCell构造,转型成CustomTableViewCell代码如下:
let cell = tableView.dequeueReusableCellWithIdentifier(identiString,forIndexPath : indexPath) as? CustomTableViewCell
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: identiString) as? CustomTableViewCell
}
这样下面的属性赋值也不能用了,因为原始的UITableView不会有我们所自定义的属性,统统报错,如图:
我们需要做的是删掉这些代码,回到我们自定义的CustomTableViewCell中,添加调用的方法如下:
func initWith(thubnailImage: String, restName: String, restLocation: String, restType: String){
thumbnailImageView.image = UIImage(named: thubnailImage)
nameLabel.text = restName
locationLabel.text = restLocation
typeLabel.text = restType
}
再回到ViewConler中(快晕了),修改cell的代理方法如下:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let identiString = "Cell" //代码复用
var cell = tableView.dequeueReusableCellWithIdentifier(identiString,forIndexPath : indexPath) as? CustomTableViewCell
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: identiString) as? CustomTableViewCell
}
var restName = restaurantNames[indexPath.row]
var restLocation = "Hello"
var imageName = restaurantImages[indexPath.row]
var restType = "World"
cell?.initWith(imageName, restName: restName, restLocation: restLocation, restType: restType)
return cell!
}
是不是以为大功告成了?运行看看,报错了吧,错误提示没找到我们复用的那个“Cell”。这里需要把Cell注册一下,回到viewDidLoad方法中,添加如下方法:
tableView.registerClass(CustomTableViewCell.self, forCellReuseIdentifier: "Cell")
再次运行,终于见到了我们久违的界面