2017-02-20 38 views
0

我努力让自己在一个UITableViewController的MVVM整合,但我不断收到。MVVM的UITableViewCell返回nil

怎么回事?我猜它是与:

cell.menuItemViewModel = SideMenuViewModel(menuItem: item)

,因为没有错误,如果我删除此行?在sideMenuController

设定数据源

func setupDatasource() { 

    let sections = [ 
     SectionModel(model: "menu", items: menuItems) 
    ] 

    dataSource.configureCell = { (ds, tv, ip, item) in 
     let cell: MenuCell = tv.dequeueReusableCell(withIdentifier: self.reuseIdentifier, for: ip) as! MenuCell 
     cell.menuItemViewModel = SideMenuViewModel(menuItem: item) 


     return cell 
    } 


    Observable.just(sections) 
     .bindTo(tableView.rx.items(dataSource: dataSource)) 
     .addDisposableTo(disposeBag) 
} 

菜单项模型

struct MenuItem { 

    var title: String 
    var image: Asset 
    var imageSelected: Asset 
    var controller: UINavigationController 

    init(title: String, image: Asset, imageSelected: Asset, controller: UINavigationController) { 
     self.title = title 
     self.image = image 
     self.imageSelected = imageSelected 
     self.controller = controller 
    } 


} 

视图模型

struct SideMenuViewModel { 

    let title: String 
    let image: UIImage 
    let imageSelected: UIImage 


    init(menuItem: MenuItem) { 
     self.title = menuItem.title 
     self.image = UIImage(asset: menuItem.image) 
     self.imageSelected = UIImage(asset: menuItem.imageSelected) 
    } 

} 

MenuCell

class MenuCell: UITableViewCell { 

    var titleLabel: UILabel! 
    var iconImageView: UIImageView! 

    var menuItemViewModel: SideMenuViewModel! { 
     didSet { 
      //Set title 
      self.titleLabel.text = menuItemViewModel.title 

      //Set image 
      self.iconImageView.image = menuItemViewModel.image 

     } 
    } 


    override init(style: UITableViewCellStyle, reuseIdentifier: String?) { 
     super.init(style: style, reuseIdentifier: reuseIdentifier) 


     setupUI() 
     setupConstraints() 

    } 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
    } 

    func setupUI() { 

     //Add titleLabel 
     self.titleLabel = UILabel() 
     self.addSubview(self.titleLabel) 

     //Add iconImageView 
     self.iconImageView = UIImageView() 
     self.addSubview(self.iconImageView) 

     //Customize titleLabel 
     self.titleLabel.font = FontFamily.Avenir.Regular.font(size: 26) 
     self.titleLabel.textColor = UIColor.white.withAlphaComponent(0.6) 

     //Customize iconImageView 
     self.iconImageView.contentMode = .scaleAspectFit 

     //Customize cell 
     self.selectionStyle = .none 
     self.backgroundColor = UIColor.clear 
    } 

    func setupConstraints() { 

     //titleLabel constraints 
     self.titleLabel.snp.makeConstraints({ make in 
      make.left.equalTo(self.iconImageView.snp.right).offset(-20) 
      make.centerY.equalTo(self) 
      make.height.equalTo(50) 
      make.width.equalTo(100) 
     }) 

     //iconImageView constraints 
     self.iconImageView.snp.makeConstraints({ make in 
      make.left.equalTo(80) 
      make.centerY.equalTo(self) 
      make.height.equalTo(50) 
      make.width.equalTo(50) 
      make.right.equalTo(self.titleLabel.snp.left).offset(20) 
     }) 

    } 


} 
+0

首先:调试并找出'nil'。如果它在'override init(style :, reuseIdentifier :))中,就像你说的那样,它必须是'reuseIdentifier',因为它是唯一可选的afaics。但是你不打开它,这很奇怪。这条线对我来说更加可疑:'let cell:MenuCell = tv.dequeueReusableCell(withIdentifier:self.reuseIdentifier,for:ip)as! MenuCell' – shallowThought

+0

@shallowThought它看起来像'menuItemViewModel'为零。 –

+0

请用您的发现更新您的问题。究竟是什么确切的错误出现,你已经发现了什么。也许可以打印调试结果来向我们展示确切的'menuItemViewModel'为'nil'的情况,并解释为什么你认为它不应该是'nil'。 – shallowThought

回答

0

你已经注册的小区?

tableView.register(MenuCell, forCellReuseIdentifier: self.reuseIdentifier) 

如果使用Storyboard将该类添加到单元格中,则不需要注册它,并且您不应该注册。

另外,如果您输错了reuseIdentifier,则会发生错误。

+0

是忘了提及我注册了'tableView.register(MenuCell.self,forCellReuseIdentifier:self.reuseIdentifier)'in'viewDidLoad' –

+0

@PeterPik我认为这可能是你的reuseidentifier然后,确保100%你的self.reuseIdentifier返回EXACT与注册单元格的字符串相同。我更新了我的答案 – 2017-02-20 14:37:25

+0

为什么他们应该在'register'和'cellAtIndexPath'都改变时访问'fileprivate let reuseIdentifier =“MenuTableCell”' –