Swift:关闭 ViewController 时更新 ViewController 的布局和内容

Swift: Update Layout and Content of ViewController when dismissing presented ViewController

我有一个 UIView,它显示一些信息,例如用户名等,包括所有从我的数据库中提取的对象列表。这很好用。

但是,我现在有一个 ViewController 显示在当前 ViewController 之上。在此呈现的 ViewController 中,我将数据添加到我的数据库中。关闭该视图时,我希望原始 ViewController 更新其所有内容以保持最新。

现在,我所有的视图都在 ViewDidLoad 中进行布局,这意味着它们只真正加载一次,以后不会重新加载。我已经通过调用 self.view.layoutIfNeeded() 设法更新布局,但如果我理解正确,这只会更新约束。当然,我可以调用我原来的视图控制器的新初始化。这会使它重新加载,但我想避免这种情况。

我的另一个想法是在 ViewWillAppear 中设置我的所有内容,然后在我的视图控制器即将可见时更新它。但是,我不知道该怎么做。我可以将所有设置代码移动到 viewWillAppear 吗?这有什么缺点吗?

TLDR:有没有一种方法可以使用新元素更新堆栈视图,而无需通过 ViewWillAppear 重新加载完整 ViewController?

UITableView 元素处理数据库数据非常顺畅。如果您在第一个视图控制器中从 viewDidLoad 中的数据库中获取数据,并将其存储在一个数组中,则 UITableView(如果您正确设置了它的数据源)将自动使用第二个视图控制器中的新值填充 table视图控制器。有了这个方法,就完全不用ViewWillAppear了

听起来您现在正在使用视图(在 VStack 中)?显示数据库中的单个对象。如果您想保留视图中使用的任何自定义 style/layout,可以通过定义 UITableViewCell 的自定义子类并选择“同时创建 XIB 文件”选项来实现。 XIB 文件可让您自定义 UITableView 中单元格的外观。

这里是一个简单的例子,显示第一个视图控制器中的数据库值自动更新。我没有包括自定义 XIB 文件(这些都是默认的 UITableViewCells),以保持其精简。

第一视图控制器

import UIKit
import CoreData

class ViewController: UIViewController {
    @IBOutlet weak var dataTable: UITableView!
    
    var tableRows: [DataItem] = []
    
    func loadData() {
        let request: NSFetchRequest<DataItem> = DataItem.fetchRequest()
        do {
            tableRows = try Global_Context.fetch(request)
        } catch {
            print("Error loading data: \(error)")
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        dataTable.dataSource = self
        loadData()
    }


    @IBAction func goForward(_ sender: UIButton) {
        self.performSegue(withIdentifier: "toSecond", sender: self)
    }
}

extension ViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return tableRows.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "dataTableCell", for: indexPath)
        cell.textLabel?.text = tableRows[indexPath.row].name
        return cell
    }
}

let Global_Context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
func saveContext () {
    if Global_Context.hasChanges {
        do {
            try Global_Context.save()
        } catch {
            let nserror = error as NSError
            print("Error saving database context: \(nserror), \(nserror.userInfo)")
        }
    }
}

第二个视图控制器:

import UIKit
import CoreData

class AddViewController: UIViewController {
    @IBOutlet weak var itemEntry: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        itemEntry.delegate = self
    }
    
    @IBAction func addNewItem(_ sender: UIButton) {
        let newDataItem = DataItem(context: Global_Context)
        newDataItem.name = itemEntry.text
        saveContext()
    }
    
    @IBAction func goBack(_ sender: UIButton) {
        self.performSegue(withIdentifier: "toFirst", sender: self)
    }
}

extension AddViewController: UITextFieldDelegate {
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.endEditing(true)
        return true
    }
}

Main.storyboard:

一旦您将视图控制器设置为 UITableViewDataSource(如示例代码中所示),table 视图应该会消除任何手动管理单个视图的需要,从而使事情变得更简单。

这是您正在寻找的功能吗? (注意示例:它是在 Xcode 中设置的,启用了“使用核心数据”。)

这是官方文档的link: https://developer.apple.com/documentation/uikit/uitableview