到目前为止,我一直在以编程方式创建我的Swift项目。我创建了详细的导航控制器和表视图控制器,但没有触及StoryBoard( SB )一次。我已经到了一个点,我想将数据从TableViewCell点击传递到另一个ViewController,但是,我相信我需要使用segue并在SB内创建/识别它。由于这个应用程序随着时间的推移变得相当复杂,模仿SB内部的所有视图控制器变得非常困难,并且在SB内部创建任何更改都不会反映模拟器上视图内部的任何更改(我有将SB内部的视图与其各自的类配对,但没有任何工作。甚至当标识符匹配时,也不识别segue)。因此,我有几个问题。
是否可以通过编程方式执行segue?换句话说,是否可以在不触及故事板的情况下将数据从一个视图控制器传递到另一个视图控制器?
是否有一个简单的指南或技术可以遵循以模仿StoryBoard中的代码?通过简单的应用程序,它不应该太困难。但是,如果某人已经完全以编程方式创建应用程序,是否还有其他方法可以在StoryBoard中描绘应用程序?
答案 0 :(得分:2)
Interface Builder(IB)只是程序化开发的GUI;因此,你可以在IB中做的任何事情你都可以通过编程方式完成(但不是你可以用IB编程完成的所有事情,显然)。
segue
只是IB术语。在iOS中,您只能通过三种方式显示视图控制器:push
(通过UINavigationController
),present
(通过演示文稿对象供应商UIViewControllerTransitioningDelegate
)或{{1} }(即peek和pop可以使用show
来执行pop)。
真正快速,因为您是程序化iOS的新手:
show
向前传递数据是基本的。实例化视图控制器,为其中一个属性赋值,然后推送,显示或显示它。这是class ProgrammaticViewController: UIViewController {
override func loadView() {
// do NOT call super.loadView() when programmatically creating a view controller
// do all of your basic setup here in loadView
setView()
}
override func viewDidLoad() {
super.viewDidLoad()
// do call super.viewDidLoad() however
// do post-basic setup stuff here in viewDidLoad
// viewDidLoad is called after the entire view controller has been
// loaded into memory so consider that
}
// other lifecycle events that come after viewDidLoad where you can do some
// last-second touches include viewDidLayoutSubviews(), viewDidAppear(), etc.
deinit {
// do any cleanup here like deactivating timers, removing observers, etc.
}
// MARK: Methods
// if you're creating your view controller programmatically, you must create
// the controller's view property in loadView
func setView() {
view = UIView()
view.frame = UIScreen.main.bounds
view.backgroundColor = UIColor.white
}
}
UITableView
didSelectRowAt
代表的样子:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let p = indexPath.row
let detailViewController = SomeDetailViewController()
detailViewController.dataObject = searchResults[p]
navigationController?.pushViewController(detailViewController, animated: true)
}
这显然是可行的,因为您已在该视图控制器中创建了该属性。
class SomeDetailViewController: UIViewController {
var dataObject: SomeType?
}
答案 1 :(得分:1)
是否可以通过编程方式执行segue?
不确定。 UIStoryboardSegue
具有可用于创建segue的初始化程序,并且它具有perform()
方法,您可以调用该方法使segue执行此操作。但是segue主要是一种工具,可以更容易地在故事板中的场景之间进行转换,因此如果您不首先使用故事板,那么没有什么理由想要这样做。
换句话说,是否可以在不触及故事板的情况下将数据从一个视图控制器传递到另一个视图控制器?
再次,是的。在iOS 5之前,故事板甚至不存在,你可以打赌人们在此之前就已经在视图控制器之间编写了具有转换的应用程序。你已经得到的关于如何做到这一点的答案很好。但更一般地说,视图控制器只是对象,而需要向另一个人发送信息的所有内容都是对目标控制器的有效引用。
但是,有没有其他方法可以在StoryBoard中描绘应用程序,如果某人已经完全以编程方式创建它?
如果您的意思是要切换到使用故事板,那么是的,有一些很好的方法可以做到这一点。如果你的意思是你想以某种方式表示你的应用程序在故事板中以编程方式进行的操作,但继续以编程方式执行所有操作,那么不,那就没有办法做到这一点(而且实际上没有意义)。
过渡到故事板并不一定是全部或全部。您可以在故事板中仅为一个视图控制器建模并使用init(name:bundle:)
(初始化故事板本身)和instantiateViewController(withIdentifier:)
(以加载特定视图控制器)根据需要加载它,然后只使用该视图控制器就像你现在一样。然后,您可以删除用于设置该视图控制器及其视图层次结构的所有代码,因为您现在正在从故事板中加载它。一旦它正常工作,重复其他视图控制器的过程,扩展故事板并根据需要删除设置代码。