我在视图VC1中有一个表视图,当 Select 一个项目时,我想以模式转到VC2,在那里可以编辑所选的项目.当我通过"Back"按钮以编程方式关闭VC2时,我如何通知VC1,以便它可以重新加载()TableView并显示编辑后的数据?

我可以通过以下方式在VC1中提取VC2刷卡取消服务:

dismiss(animated flag: Bool, completion: (() -> Void)?)

对我的应用程序来说,这相当于"取消",即不采取任何行动.然而,我想在VC1中确定什么时候以编程方式关闭该模式.我认为我需要使用完成处理程序,但我正在努力理解需要什么.

推荐答案

下面是一些示例代码,显示了将数据从呈现的视图控制器(VC2)传递到呈现的视图控制器(VC1)的一种方法.

VC2定义了var callback: (() -> Void)?,这是一种函数类型.它定义了一个没有参数且不返回任何内容的函数.VC1中的Prepare(for Segue:)将回调函数作为代码块提供给VC2.该回调更新Vc1‘S数据,并重新加载Vc1’S表视图.

在VC2中,当 Select Done时,它会在解除之前调用回调函数.

class VC1: UIViewController, UITableViewDataSource {
    
    var data = [1, 2, 3, 4, 5, 6, 7]

    @IBOutlet weak var tableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.dataSource = self
    }
    
    // MARK: - TableViewDataSource

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        cell.textLabel?.text = "\(data[indexPath.row])"
        return cell
    }

    // MARK: - Navigation

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "Show Number" {
            if let cell = sender as? UITableViewCell {
                let indexPath = tableView.indexPath(for: cell)
                if let vc2 = segue.destination as? VC2 {
                    vc2.number = data[indexPath!.row]
                    vc2.callback = {
                        self.data[indexPath!.row] = vc2.number
                        self.tableView.reloadData()
                    }
                }
            }
        }
    }
}
class VC2: UIViewController {

    var number = 0
    var callback: (() -> Void)?
    
    @IBOutlet weak var numberLabel: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        numberLabel.text = "\(number)"
    }
    
    @IBAction func add100Selected(_ sender: UIButton) {
        number += 100
        numberLabel.text = "\(number)"
    }
    
    @IBAction func doneSelected(_ sender: UIButton) {
        callback?()
        dismiss(animated: true)
    }
}

Full Screen Modal Segway

使用全屏模式段时,您必须使用Done按钮,该按钮将始终保存更改.

Full Screen Modal Segway

Page Sheet Modal Segway (swipeable)

使用页面工作表模式段,如果您滑动VC2,更改将不会保存.如果无论如何取消VC2,都希望保存更改,则必须在修改数据后立即调用回调函数(在我的示例中,在add100Selected的末尾).

Page Sheet Modal Segway

我对每个视频都使用了相同的VC代码(只是在界面生成器中更改了Segue表示).

Interface Builder

下面是我如何在界面生成器中设置这两个VC的.我在图像中 Select 了分段,因此您可以在属性判断器中看到其设置.

Interface Builder

Swift相关问答推荐

Swift Tree实现中的弱var

TabView中的视频播放器意外播放

为什么我的引用类型对象在初始化后有3个强引用?

Swift C外部实现的Task / Future类类型

如何异步返回视图?什么?

如何在 Vapor 中制作可选的查询过滤器

我需要一些关于 SwiftUI 动画的帮助

有没有办法让文本字段以不同的 colored颜色 显示而不影响半透明背景?

CardStack 和 Lottie

如何从 Swift 中隐藏 Objective-C 类接口的一部分?

RxSwift 提高性能

Swift 5.0 编译器无法导入使用 Swift 4.2.1 编译的模块

如何更改弹出框的大小

是 swift 中另一个日期的同一周、月、年的日期

Swift 中的可选数组与空数组

Swift 2.0 按属性对对象数组进行排序

SwiftUI:将多个 BindableObjects 放入环境

键盘显示时Tableview滚动内容

Swift 中的单元测试致命错误

通过单击表格视图中的单元格打开新的视图控制器 - Swift iOS