可以在不使用StoryBoard的情况下执行segue吗?

use*_*442 3 xcode storyboard ios segue swift

到目前为止,我一直在完全以编程方式创建我的 Swift 项目。我已经创建了详细的导航控制器和表视图控制器,而没有接触过故事板(SB)一次。我已经到了这样的地步:我想将数据从 TableViewCell 单击传递到另一个 ViewController,但是,我相信我需要使用 segue 并在 SB 内部创建/识别它。由于这个应用程序随着时间的推移变得相当复杂,模仿 SB 内部的所有视图控制器变得相当困难,并且在 SB 内部创建任何更改并不会反映模拟器上视图内部的任何更改(我有将 SB 内部的视图与各自的类配对,但没有任何效果。当标识符匹配时,甚至连 segue 也无法被识别)。因此,我有几个问题。

  1. 是否可以以编程方式执行segue?换句话说,是否可以在不接触故事板的情况下将数据从一个视图控制器传递到另一个视图控制器?

  2. 是否有一个简单的指南或技术可供人们遵循,以便在 StoryBoard 中模仿他们的代码?通过一个简单的应用程序,应该不会太困难。但是,如果有人完全以编程方式创建应用程序,是否还有其他方法可以在故事板中描绘该应用程序?

bso*_*sod 5

Interface Builder (IB) 只是一个用于编程开发​​的 GUI。你在 IB 中能做的任何事情都可以通过编程方式完成,但并不是所有你可以通过编程方式完成的事情都可以在 IB 中完成,因为 IB 只是用于界面构建 \xe2\x80\x94 并且只是一些界面构建,而不是全部。

\n\n

segue只是IB术语。在 iOS 中,您只能通过三种方式显示视图控制器:(push通过UINavigationController)、present(通过演示对象供应商UIViewControllerTransitioningDelegate)或show(显示视图控制器的更通用方法)。

\n\n

由于您是编程式 iOS 开发的新手(我认为这是最好的一种),请快速完成 101 操作:

\n\n
class ProgrammaticViewController: UIViewController {\n\n    override func loadView() {\n\n        // do not call super.loadView()\n        // most IB developers don't even know this method exists\n        //   because this is where IB does its work\n        // add all of your view objects here (scroll views,\n        //   table views, buttons, everything)\n\n        setView()\n        addTableView()\n        ...\n\n    }\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n\n        // do call super.viewDidLoad(), however\n        // do your post-view setup here, like adding observers\n        //   or fetching data\n        // this method is called after the entire view\n        //   has been loaded into memory so consider that\n\n    }\n\n    // other lifecycle events that come after viewDidLoad where you\n    //   can perform last-second work include viewDidLayoutSubviews(),\n    //   viewWillAppear(), viewDidAppear(), etc.\n\n    deinit {\n        // do any cleanup here like deactivating timers, removing\n        //   observers, etc.\n    }\n\n    // MARK: Methods\n\n    func setView() {\n\n        // if you're creating your view controller programmatically,\n        //   you must create the view controller's actual view property\n        //   and it must be done before adding any subviews to the\n        //   view controller's view\n\n        view = UIView()\n        view.frame = UIScreen.main.bounds\n        view.backgroundColor = UIColor.white\n\n    }\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果您使用自动布局(并且您可能应该这样做),则并不总是需要使用 显式设置视图的框架view.frame = UIScreen.main.bounds。如果它是应用程序的根视图控制器,则不需要\xe2\x80\x94窗口拥有该视图控制器,它将设置框架。如果您随后将 a 放在UINavigationController根目录中并且使用自动布局,则您推送到的视图控制器也不需要它们的框架集。因此,唯一实时需要使用类似的方法显式设置视图的框架view.frame = UIScreen.main.bounds是当您以模态方式呈现视图控制器时。这是因为模态呈现的视图控制器不属于窗口或导航控制器;它暂时存在于瞬态容器视图中。在这种情况下,您必须设置其框架。

\n\n

以编程方式转发数据比 IB 开发人员更简单。只需实例化一个视图控制器,将一个值注入其(非私有)属性之一,然后推送、呈现或显示它。这是UITableView代表的用途didSelectRowAt所示:

\n\n
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {\n\n    let p = indexPath.row\n    let detailViewController = SomeDetailViewController()\n\n    detailViewController.someProperty = searchResults[p]\n    navigationController?.pushViewController(detailViewController, animated: true)\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这显然是可行的,因为您已经在该视图控制器中创建了该属性,并且没有为其指定私有访问修饰符。

\n\n
class SomeDetailViewController: UIViewController {\n\n    var dataObject: SomeType? // injectable\n    private var notInjectable: SomeType?\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

更新:随着 SwiftUI(另一种以编程方式开发 iOS 的方式)的推出,对于 Apple 而言,IB 显然不是 iOS 开发的未来。就我个人而言,我讨厌 GUI 编程,并且很高兴看到它慢慢被淘汰。

\n