xcode 如何在Swift中的ViewDidLoad之前进行委托?

ldfqzlk8  于 2023-08-07  发布在  Swift
关注(0)|答案(2)|浏览(156)

我想从firebase firestore中获取数据,并将其放入一个新视图中的tableview,但当tableview获取数据时,它是空的,我得到了像这张图片screenshot of unwrapping error的解包错误
这是我的tableview代码:

class ParcelViewController:UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    let tableCell = ParcelTableViewCell()
    var parcelDataModel = MainViewModel()
    
    @IBOutlet weak var parcelTable: UITableView!
    
    override func viewDidLoad() {
        
       self.parcelDataModel.vc = self
        view.backgroundColor = .white
        parcelDataModel.getCollectionData()
        print("Hi")
    }
    
    var selectionDelegate : ParcelSelectionDelegate!
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if parcelDataModel.parcels.count > 0 {
            return self.parcelDataModel.parcels.count
        } else {
            return 0
        }
    }
        
        
        
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = parcelTable.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! ParcelTableViewCell
            let current = self.parcelDataModel.parcels[indexPath.row]
            cell.parcelTitleLabel.text = current.parcel_type
            cell.parcelImage.image = UIImage(named: current.parcel_img_url)
            cell.parcelWeightlabel.text = "\(current.parcel_min_weight)  -  \(current.parcel_max_weight)"
            cell.parcelDescriptionLabel.text = current.parcel_description
            return cell
            
        }
        
        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            let selected = self.parcelDataModel.parcels[indexPath.row]
            selectionDelegate.parcelDidSelect(parcelType: selected.parcel_type)
        }
    }

字符串
我想这个代码self.parcelDataModel.vc = self出现在viewdidload之前
我在loadView中尝试过,但它没有工作。

qltillow

qltillow1#

正如评论中所提到的,在这种情况下,将生命周期接入点定位于比viewDidLoad()更早的接入点不太可能有帮助:几乎可以肯定视图控制器的生命周期将在Firebase请求返回之前完成。
考虑到这一点,对视图控制器负载UX的修改是答案。这里有两种主要的方法:
1.在新的视图控制器中有一个“未加载/正在加载”的UX,在那里发出Firebase请求,并在Firebase返回响应时更新UI。
1.在前面的视图控制器中发出Firebase请求,然后用任何返回的数据加载新的视图控制器(假设该请求没有返回错误)。
选项1可能类似于:

class NewViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    var model: DataModel?   // Must be optional because we'll load initially with it nil

    override func viewDidAppear() {
        super.viewDidAppear()
        
        // Show loading UI

        requestData()
    }
    
    func requestData() {
        // I don't know the Firebase request signature, so here's a placeholder
        Firebase.requestData(completion: { result in
             switch result {
             case .success(let data):
                 self.model = data
                 // Then update your UI for data
                 
             case .error(let error):
                 // Show error UI
             }
        })
    }
    
    // UITableViewDataSource
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // This depends on the design of your table view
        if let model = model {
            return model.things.count
            
        } else {
            // `model` is nil
            return 0
        }
    }
}

字符串
选项2可能类似于:

class PrecedingViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    // UITableViewDelegate
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        // Show loading UI
        
        Firebase.requestData(completion: { result in
             switch result {
             case .success(let data):
                 // We have data, NOW load the New View Controller
                 let newViewController = NewViewController(model: data)
                 navigationController?.pushViewController(newViewController, animated: true)
                 
             case .error(let error):
                 // Show error UI
             }
        })
    }
}


然后又道:

class NewViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    let model: DataModel   // Non-optional, as we know we have a model
    
    init(model: DataModel) {
        self.model = model
        super.init(style: .grouped)
    }
    
    // UITableViewDataSource
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // This depends on the design of your table view
        return model.things.count
    }
}

hgc7kmma

hgc7kmma2#

我只需要像下面这样更改numberOfRowsInSection中的if语句

if parcelDataModel.parcels != nil {
        return parcelDataModel.parcels.count
        } else {
        return 0
    }

字符串
现在它起作用了

相关问题