为什么在nib文件(加载并添加到堆栈中)中的UITableViewCell在viewDidAppear中为零,但它在viewDidLoad中可用?

为什么在nib文件(加载并添加到堆栈中)中的UITableViewCell在viewDidAppear中为零,但它在viewDidLoad中可用?

问题描述:

我在我的ViewController堆栈,我想加载nib文件(其中包含实现代码如下),并把它添加到堆栈中。当我在viewDidLoad添加它,是没有问题的,但是当我把它放在viewDidAppear应用程序崩溃和得到这个错误:为什么在nib文件(加载并添加到堆栈中)中的UITableViewCell在viewDidAppear中为零,但它在viewDidLoad中可用?

fatal error: unexpectedly found nil while unwrapping an Optional value 

有一些UITableViewCell这是我在基于行cellForRowAt函数返回它们。看起来nib文件在它们加载并加入viewDidAppear时无效!

这里是我的代码:

class MyOrdersViewController: UIViewController { 

@IBOutlet weak var stack: UIStackView! 
override func viewDidLoad() { 
    super.viewDidLoad() 
    //setCards() 
} 

override func viewDidAppear(_ animated: Bool) { 
    super.viewDidAppear(animated) 
    setCards() 
} 


func setCards(){ 
     let orderCard = NibLoader.loadViewFromNib(name: "MyOrdersView", selfInstance: self, nibType: MyOrdersView.self) as! MyOrdersView 
     stack.addArrangedSubview(orderCard) 
} 
} 


class MyOrdersView: UIView,UITableViewDelegate,UITableViewDataSource { 

@IBOutlet weak var tableView: UITableView! 

@IBOutlet weak var seprator: UITableViewCell! 

@IBOutlet weak var date: UILabel! 
@IBOutlet weak var firstCell: UITableViewCell! 
@IBOutlet weak var code: UILabel! 

@IBOutlet weak var secondCell: UITableViewCell! 
@IBOutlet weak var price: UILabel! 

@IBOutlet weak var thirdCell: UITableViewCell! 
@IBOutlet weak var orderStep: UILabel! 

@IBOutlet weak var payModel: UILabel! 
@IBOutlet weak var cancelBtn: UIButton! 
@IBOutlet weak var fourthCell: UITableViewCell! 

override func awakeFromNib() { 
    tableView.delegate = self 
    tableView.dataSource = self 
    UIFunctions.setBordersStyle(view: cancelBtn, radius: 5, width: 1, color: UIColor.red) 
} 

func setValue(order:Order){ 
    self.date.text = order.order_date 
    self.code.text = String(describing: order.order_code ?? 0) 
} 

// MARK: - Table view data source 

func numberOfSections(in tableView: UITableView) -> Int { 
    return 1 
} 

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return 5 
} 

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

    var cell=UITableViewCell() 

    switch indexPath.row { 
    case 0: 
     cell = seprator 
    case 1: 
     cell = firstCell 
     cell.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0) 
    case 2: 
     cell = secondCell 
     cell.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0) 
    case 3: 
     cell = thirdCell 
     cell.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0) 
    case 4: 
     cell = fourthCell 
    default: 
     break 
    } 

    return cell 
} 

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 

    var height = 0 
    switch indexPath.row { 
    case 0: 
     height = 25 
    case 4: 
     height = 70 
    default: 
     height = 50 
    } 

    return CGFloat(height) 
} 
} 
+0

,你在哪里分配'firstCell','secondCell'等等? –

+0

我榫文件创建它们(从对象库中拖拽的tableview细胞) –

The reason seems that since viewDidLoad is the first method to be called in the view life cycle, adding nib reference there makes sure that when the views are drawn(your tables), they are available to locate in cellForRow .

But if you put the same code in viewDidAppear , the views are already loaded by that time, and your table view is not referenced yet referenced from Nib . Hence the nil error.

This link讨论了各种观点的生命周期方法和详细的调用顺序。

+0

所以,我怎么能添加视图(包含实现代码如下)堆栈在运行时? –

+0

你想动态地添加MyOrdersView吗? –

+0

是啊,我送请求到服务器并返回项目(和数组的数组) –