ios - 如何从多个 Storyboard 源 View Controller 中呈现给定的 View Controller ?

标签 ios swift3 xcode8 uistoryboard

我正在制作 Storyboard,因此我需要展示一个数据输入 View Controller 。数据输入 vc 需要一个保存按钮和一个取消按钮。我需要显示来自其他两个 View Controller 的数据条目 vc。

我想通过 Storyboard 来配置它,以便我的 Storyboard 确实“讲述故事”。如果我对数据输入 VC 进行显示转场,则后退按钮将使我返回到正确的源 Controller (VC1 或 VC2)。我想我可以使用后退按钮来触发取消操作(嗯……),但是保存操作呢?如果我通过中间导航 Controller 以模态方式呈现数据输入 VC,那么我可以添加保存和取消栏按钮项目并将展开 segues 附加到它们,但似乎没有办法有条件地展开回正确的源( VC1 或 VC2)。

我确定的是:

  1. VC1 和 VC2 将在没有导航 Controller 介入的情况下以模态方式呈现数据输入 VC(即,数据输入 VC 没有导航项)。
  2. 数据输入 vc 将有两个 UIButtons,保存和取消。这两个按钮将触发数据输入 VC 中的操作,这将关闭它。
  3. VC1(VC2) 会将目标添加到数据输入 VC 的按钮,以便 VC1(VC2) 可以采取适当的操作(包括删除目标)。

请参阅下面的代码和 Storyboard。 (注意:这些不是来 self 的实际应用程序。它们来 self 用来试验的项目)。

所以,我的作品。但是,我不禁觉得还有更优雅的技巧。我真正想要的是重用数据输入 View 及其 Controller 。从所有者是数据条目 vc 的 nib 加载 View 是否有效?也许是一个 UIContainerView?有更多经验的人会告诉我吗(即使要确认我所拥有的也差不多)?谢谢!

VC1和VC2中的相关代码:

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

    func setupButtons(_ view: UIView) {
        view.subviews.forEach() { view in
            if let button = view as? UIButton, let title = button.title(for: .normal) {
                switch title {
                case "Save":
                    button.addTarget(self, action: #selector(save(sender:)), for: .touchUpInside)
                case "Cancel":
                    button.addTarget(self, action: #selector(cancel(sender:)), for: .touchUpInside)
                default:
                    break
                }

            }
            else {
                setupButtons(view)
            }
        }
    }

    if let vc = segue.destination as? DataEntryViewController {
        setupButtons(vc.view)
    }

}

func cancel(sender: UIButton) {
    process(button: sender, save: false)
}

func save(sender: UIButton) {
    process(button: sender, save: true)
}

private func process(button: UIButton, save: Bool) {
    let title = button.title(for: .normal) ?? "<unknown>"
    print("The \(title) button was pressed")

    if save {
        if let vc = button.viewController as? DataEntryViewController {
            print("The data is \(vc.data)")
        }
        else {
            print("Cannot get the \(title) button's VC")
        }
    }

    button.removeTarget(self, action: nil, for: .touchUpInside)
}

数据录入 Controller 中的相关代码:

@IBAction func cancel(_ sender: UIButton) {
    self.dismiss(animated: true, completion: nil)
}

@IBAction func save(_ sender: UIButton) {
    self.dismiss(animated: true, completion: nil)
}

enter image description here

最佳答案

根据我对 unwind segues 的了解,这应该可以正常工作。参见 Technical Note TN2298 “Unwind Segue 如何确定其目标 View Controller ”部分。您是否真的尝试过在 VC1 和 VC2 中实现相同的展开操作 并将按钮连接到 Interface Builder 中相应的展开操作?

作为旁注,您在查找 View 时可能应该使用标签,而不是将按钮标题与固定字符串(国际化和所有)进行比较。

编辑:

我刚刚创建了一个完全符合我描述的测试项目。该应用程序是一个带有两个 View Controller (FirstViewControllerSecondViewController)的选项卡栏 Controller ,这两个 View Controller 都提供一个带有取消按钮和保存按钮的数据输入 View Controller 。它们分别连接到展开操作 unwindToCancel:unwindToSave:

Storyboard

Unwind to Cancel

class FirstViewController: UIViewController
{
    @IBAction func unwindToSave(_ segue: UIStoryboardSegue)
    {
        print("FirstViewController unwindToSave")
    }

    @IBAction func unwindToCancel(_ segue: UIStoryboardSegue)
    {
        print("FirstViewController unwindToCancel")
    }
}

class SecondViewController: UIViewController
{
    @IBAction func unwindToSave(_ segue: UIStoryboardSegue)
    {
        print("SecondViewController unwindToSave")
    }

    @IBAction func unwindToCancel(_ segue: UIStoryboardSegue)
    {
        print("SecondViewController unwindToCancel")
    }
}

根据我来自哪个 View Controller ,当我点击取消或保存时会打印正确的消息。

关于ios - 如何从多个 Storyboard 源 View Controller 中呈现给定的 View Controller ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42846501/

相关文章:

ios - 即使在 DispatchQueue.main.async Swift 3 中设置后,数组仍然为空

ios - 如何在新行将 JSON 数组数据打印到 Swift3 中的 UILabel

ios - iOS 10 中的错误 : Unable to copy asset information from https://mesu. apple.com/assets/对于 Assets 类型

xcode8 - Xcode 8 不会下载所有配置文件

ios - 从 iOS 8 开始,如何获取浏览器 UserAgent 字符串?

ios - 添加新授权过程后 MapKit 崩溃

android - 使用 Kotlin 作为 Android 和 iOS 的 RestAPI 解析器

ios - Cocoa:命令/usr/bin/ditto 失败,退出代码为 1

ios - UIScrollView 大小问题

ios - Xcode 8,iOS 8 模拟器崩溃 : "dyld: lazy symbol binding failed: Symbol not found: _objc_unsafeClaimAutoreleasedReturnValue"