【问题标题】:Prepare for segue data not being loaded为未加载的 segue 数据做准备
【发布时间】:2017-06-15 18:09:47
【问题描述】:

我有一个轮播,每个轮播项目都包含一个独特的表格视图。当您点击添加按钮时,它会将您带到一个新的视图控制器,以便您可以为表格视图命名并关联要在每个单元格中显示的项目。现在,当我点击保存按钮时,它会执行 segue 回到轮播的视图控制器。我的prepareforsegue 看起来像这样:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    let destinationVC = segue.destination as! BillSplittersViewController
    let passedBill: NSManagedObject = bill as NSManagedObject

    destinationVC.allBillSplitters = getUpdatedSplitters()
    print(2)            
    print(destinationVC.allBillSplitters)
    destinationVC.billName = billName
    destinationVC.bill = passedBill
}

当显示轮播视图控制器时,它不会显示从allBillSplitters 数组加载的轮播中添加的项目。如果我尝试在viewdidloadviewwillappearview willlayoutsubviews 中重新加载轮播,则没有任何变化。如果我在 viewdidlayoutsubviews 中执行此操作,它确实会更新,但您会看到这种情况并不好。

为了调试,我尝试在prepareforsegue 中打印数组,然后在viewdidload 中打印数组,它在prepareforsegue 中打印数组而没有添加项目,并且在viewdidload 中执行相同的操作——但随后它会打印它们再次使用添加的项目 - 但我在加载的视图中看不到它。

如果有帮助,我正在使用iCarousel。我是新手,不确定发生了什么,所以我不知道要使用什么代码。我为两个视图控制器使用故事板,并且 segue 附加到视图而不是按钮本身。任何帮助都会很棒。谢谢!

更多信息:

@IBAction func saveButtonWasPressed() {

    let managedContext = bill.managedObjectContext

    if let splitter = splitter {
        splitter.mutableSetValue(forKey: "items").removeAllObjects()
        setBillSplitterValues(splitter)
        setSelectedItemsToBillSplitter(splitter)
    } else {
        let entity =  NSEntityDescription.entity(forEntityName: "BillSplitter", in: managedContext!)
        let newBillSplitter = NSManagedObject(entity: entity!, insertInto: managedContext)

        setBillSplitterValues(newBillSplitter)
        setSelectedItemsToBillSplitter(newBillSplitter)
    }

    do {
        try managedContext!.save()
    }
    catch let error as NSError {
        print("Core Data save failed: \(error)")
    }

    self.performSegue(withIdentifier: "segueToBillSplitters", sender: self)
}

检索新的 billSplitters:

func getUpdatedSplitters() -> [BillSplitter] {
    var allBillSplitters = [BillSplitter]()

    let managedContext = bill.managedObjectContext
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "BillSplitter")
    let predicate = NSPredicate(format: "ANY bills == %@", bill)

    fetchRequest.predicate = predicate

    do {
        let results =
            try managedContext!.fetch(fetchRequest)
        allBillSplitters = results as! [BillSplitter]
    } catch let error as NSError {
        print("Could not fetch \(error), \(error.userInfo)")
    }
    return allBillSplitters
}

所以当按下保存时,它要么将现有的“billSplitter”更新到 coredata,要么添加一个新的,然后调用performSegue。在prepareForSegue 中,它会从 CoreData 中获取所有的 'billSplitters' 并将它们传递给目标视图控制器。

我认为 NSManagedObjectContextDidSave 观察者可能会有所帮助,如果它在收到通知后调用 performSegue 但没有任何改变。

更新:

我在saveButtonWasPressed 方法中尝试了以下方法。当视图控制器加载时,它会快速显示旧的轮播然后闪烁并显示更新的轮播。我不知道从这里去哪里。

@IBAction func saveButtonWasPressed() {

    DispatchQueue.global(qos: .background).async { [weak weakSelf = self] in
        let managedContext = weakSelf?.bill.managedObjectContext

        if let splitter = weakSelf?.splitter {
            splitter.mutableSetValue(forKey: "items").removeAllObjects()
            weakSelf?.setBillSplitterValues(splitter)
            weakSelf?.setSelectedItemsToBillSplitter(splitter)
        } else {
            let entity =  NSEntityDescription.entity(forEntityName: "BillSplitter", in: managedContext!)
            let newBillSplitter = NSManagedObject(entity: entity!, insertInto: managedContext)

            weakSelf?.setBillSplitterValues(newBillSplitter)
            weakSelf?.setSelectedItemsToBillSplitter(newBillSplitter)
        }

        do {
            try managedContext!.save()
        }
        catch let error as NSError {
            print("Core Data save failed: \(error)")
        }

        DispatchQueue.main.async { [weak weakSelf = self] in
            guard let weakSelf = weakSelf else { return }
            weakSelf.performSegue(withIdentifier: "segueToBillSplitters", sender: self)
        }
    }

}

【问题讨论】:

  • 你有没有在数据发生变化的表视图上尝试tableView.reloadData()
  • 这不是我遇到问题的表格视图,而是它们所在的轮播。重新加载轮播不起作用。
  • 如果您可以发布其余的相关代码,将会有所帮助。通过使用 GCD 库将 UI 更新分派到主线程和/或分派主线程的其他工作以防止其被阻塞,可以轻松修复 UI 未更新
  • @MikeG 道歉,我不知道有什么帮助。我已经添加了更多。我以前从未使用过 GCD 库或调度,所以任何提示都会很棒。我会像往常一样用谷歌搜索它。感谢您的帮助

标签: swift swift3 icarousel


【解决方案1】:

我可能不明白你到底在问什么,但我唯一的意见是,当我使用 prepare for segue 时,我总是使用 segue 标识符

 var valueToPass
 override func prepare(for segue: UIStoryboardSegue, sender: Any?){
    if (segue.identifier == "yourSegue") {
        let viewController = segue.destination as! ViewController
        viewController.passedValue = valueToPass as String
 }

您在情节提要中声明您的标识符,同时确保您的 segue 是一个 action segue

【讨论】:

  • 这对我没有帮助。不过谢谢
猜你喜欢
  • 1970-01-01
  • 2017-03-05
  • 1970-01-01
  • 2017-10-21
  • 2014-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多