Ash*_*lls 12 ios uistoryboard swift ibsegueaction
感谢AD Progress出色的研究和下面的回答,我终于弄清楚了IBSegueActions是怎么回事。
如果您将rootViewControllersegue(或任何其他类型,大概)连接到IBSegueActionin 中UINavigationContoller,但在那里找不到它,它将查看响应者链上的下一个视图控制器,直到找到IBSegueAction具有正确签名的 。如果它没有找到一个,它会叫init(with coder: NSCoder)的rootViewController。如果只是在某处记录了这一点……
笔记
注意:这是一个说明问题的最小示例 - 如何在UINavigationController使用IBSegueAction. 我知道这不是您通常呈现详细视图的方式。
注 2:我知道如何将 segues 与prepare(for segue: UIStoryboardSegue). 我想知道如何初始化一个视图控制器时,如何通过非可选参数包含在一个模式UINavigationController使用IBSegueAction
注 3:我知道如何将 anIBSegueAction用于未包含在 a 中的视图控制器UINavigationController(例如推送导航堆栈)
原始问题
我有以下设置…
中的人员列表UITableViewController。轻敲 aPersonCell呈现 aPersonViewController内 aUINavigationController
为了避免在 中有一个可选Person的PersonViewController,我试图使用IBSegueActions。
我首先想到的是,我需要一个用于之间的SEGUEPeopleViewController和PersonNavController,和之间的SEGUEPersonNavController和PersonViewController如下...
class PeopleViewController: UITableViewController {
// Table view delegate methods here
@IBSegueAction func showPerson(_ coder: NSCoder, sender: Any?) -> PersonNavController? {
guard let cell = sender as? PersonCell else { return nil }
return PersonNavController(coder: coder, person: cell.person)
}
}
Run Code Online (Sandbox Code Playgroud)
class PersonNavController: UINavigationController {
private let person: Person
required init?(coder: NSCoder, person: Person) {
self.person = person
super.init(coder: coder)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@IBSegueAction func root(_ coder: NSCoder) -> PersonViewController? {
return PersonViewController(coder: coder, person: person)
}
}
Run Code Online (Sandbox Code Playgroud)
class PersonViewController: UIViewController {
@IBOutlet private weak var name: UILabel!
private let person: Person
required init?(coder: NSCoder, person: Person) {
self.person = person
super.init(coder: coder)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
name.text = person.firstName
}
}
Run Code Online (Sandbox Code Playgroud)
事实证明,这里的问题是,即使您可以将 segue 操作连接到 aUINavigationController和 its之间的 segue rootViewController,它也不会像上面的示例中的super.init(coder: coder)inPersonNavController调用 那样被触发PersonViewController.init(coder: NSCoder)(未实现) .
关于如何让这个工作的任何想法?
AD *_*ess 10
为了达到你想要的结果,我重新创建了一个简单的项目,我将在我的 GitHub 上链接它。
首先,您需要摆脱为导航控制器创建的 segue 并重新创建它。
接下来选择present Modally并用标识符命名你的segue
接下来你需要在你的第一个 ViewController 中定义 IBSegueAction
视图控制器.swift
import UIKit
class ViewController: UITableViewController {
let persons = ["Robert", "Peter", "Dave"]
var selectedPerson = 0
override func viewDidLoad() {
super.viewDidLoad()
}
@IBSegueAction
private func showPerson(coder: NSCoder, sender: Any?, segueIdentifier: String?)
-> PersonViewController? {
return PersonViewController(coder: coder, personDetails: persons[selectedPerson])
}
//MARK:- TableView Methods
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return persons.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "personCell", for: indexPath)
cell.textLabel?.text = persons[indexPath.row]
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedPerson = indexPath.row
performSegue(withIdentifier: "ShowPerson", sender: self)
}
}
Run Code Online (Sandbox Code Playgroud)
然后init?(coder: NSCoder, personDetails: String)在PersonViewController中添加的实现如下。Xcode 会大喊你需要实现required init?(coder: NSCoder)
Just tap fix。
PersonViewController.swift
import UIKit
class PersonViewController: UIViewController {
//Your data passed in below as non optional constant
let personDetails: String
//The received data gets initialized below
init?(coder: NSCoder, personDetails: String) {
self.personDetails = personDetails
super.init(coder: coder)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@IBOutlet weak var personLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
personLabel.text = personDetails
}
}
Run Code Online (Sandbox Code Playgroud)
下一步是在情节提要中选择 ViewController 的顶部,以便您可以看到三个图标。
之后,您必须选择从第二个 UINavigationController 到目标 ViewController 的 Segue 在这里 PersonViewController 并从 segue 拖回您想要从中发送信息的 ViewController 的第一个黄色图标,如下面的屏幕截图所示。Xcode 将自动识别您在代码中创建的 IBSegueAction 名称。
就是这样。
一旦你点击第一个视图控制器中的任何单元格,你应该得到这样的结果
这是示例项目GitHub
我还在这里找到了有关 IBSegueAction 的更多信息
| 归档时间: |
|
| 查看次数: |
1893 次 |
| 最近记录: |