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")
再次运行,终于见到了我们久违的界面