2つのView Controllerを作成しました。データを渡すために、最初から2番目のセグエを作成しました。次に、2番目のView Controllerから最初のView Controllerにデータを渡します。私は多くの同様の質問を経験しましたが、巻き戻しがどのように機能するかに関する知識が不足しているため、それらを実装することはできません。
ViewController.Swift
class ViewController: UIViewController
{
var dataRecieved: String?
@IBOutlet weak var labelOne: UILabel!
@IBAction func buttonOne(sender: UIButton)
{
performSegueWithIdentifier("viewNext", sender: self)
}
override func prepareForSegue(segue: (UIStoryboardSegue!), sender: AnyObject!)
{
var svc: viewControllerB = segue.destinationViewController as! viewControllerB
svc.dataPassed = labelOne.text
}
}
これにより、データがView Controller「viewControllerB」のdataPassedに渡されます。たとえば、viewControllerBのデータをViewControllerのdataRecievedに渡したいとします。デリゲートを使用せずに、セグエをほどくだけでこれを行うにはどうすればよいですか。私はSwiftを初めて使用しますが、詳細な説明をお願いします。
ØyvindHaugeが同じ解決策メソッドに私を打ち負かしましたが、より詳細な答えですでに始めていたので、それも追加します。
2つのView Controllerの名前が次のようになっているとします。
ViewController
(vcA)
ViewControllerB
(vcB)
例で行ったように、(vcA) -> (vcB)
からセグエを設定します
/* in ViewController.Swift */
// ...
// segue ViewController -> ViewControllerB
override func prepareForSegue(segue: (UIStoryboardSegue!), sender: AnyObject!)
{
if segue.identifier == "viewNext" {
let viewControllerB = segue.destinationViewController as! ViewControllerB
viewControllerB.dataPassed = labelOne.text
}
}
次にやや厄介なステップは、このメソッドを使用して、データを戻すために使用されるセグエfrom(vcB)
to(vcA)
はalso(vcA)
のソースに@IBAction
メソッドとして(予想されるようにではなく、 (vcB)
)のソース。
/* in ViewController.Swift */
// ...
// segue ViewControllerB -> ViewController
@IBAction func unwindToThisView(sender: UIStoryboardSegue) {
if let sourceViewController = sender.sourceViewController as? ViewControllerB {
dataRecieved = sourceViewController.dataPassed
}
}
その後、(vcB)
の手動のExit
segueを介して、(vcA)
のボタンを(vcB)
のこの巻き戻しアクションに接続します。
以下は、(vcA)
から(vcB)
にテキストを渡す完全な例です。 (おそらく)UITextField
を介してそのテキストを変更し、最終的に(おそらく)変更されたテキストを(vcA)
に返します。
(vcA)
ソース:
/* ViewController.Swift: Initial view controller */
import UIKit
class ViewController: UIViewController {
var dataRecieved: String? {
willSet {
labelOne.text = newValue
}
}
@IBOutlet weak var labelOne: UILabel!
@IBAction func buttonOne(sender: UIButton) {
performSegueWithIdentifier("viewNext", sender: self)
}
// set default labelOne text
override func viewDidLoad() {
super.viewDidLoad()
labelOne.text = "Default passed data"
}
// segue ViewController -> ViewControllerB
override func prepareForSegue(segue: (UIStoryboardSegue!), sender: AnyObject!)
{
if segue.identifier == "viewNext" {
let viewControllerB = segue.destinationViewController as! ViewControllerB
viewControllerB.dataPassed = labelOne.text
}
}
// segue ViewControllerB -> ViewController
@IBAction func unwindToThisView(sender: UIStoryboardSegue) {
if let sourceViewController = sender.sourceViewController as? ViewControllerB {
dataRecieved = sourceViewController.dataPassed
}
}
}
(vcB)
ソース(ここのUITextFieldDelegate
デリゲートは、(vcA)
に返され、後者のdataPassed
プロパティに割り当てられるdataRecieved
プロパティの値を「ローカルに」変更するためにのみ使用されることに注意してください)
/* ViewControllerB.Swift */
import UIKit
class ViewControllerB: UIViewController, UITextFieldDelegate {
var dataPassed : String?
@IBOutlet weak var textField: UITextField!
// set default textField text to the data passed from previous view.
override func viewDidLoad() {
super.viewDidLoad()
textField.text = dataPassed
// Handle the user input in the text field through delegate callbacks
textField.delegate = self
}
// UITextFieldDelegate
func textFieldShouldReturn(textField: UITextField) -> Bool {
// User finished typing (hit return): hide the keyboard.
textField.resignFirstResponder()
return true
}
func textFieldDidEndEditing(textField: UITextField) {
dataPassed = textField.text
}
}
実行例:
これは私がそれをする方法です:
次のように、View Controller 1でアウトレットを作成します。
@IBAction func unwindToViewController1(segue: UIStoryboardSegue) {
let foo = segue.sourceViewController.foo
// TODO: Use foo in view controller 1
}
以下に示すように、View Controller 2(巻き戻し元のVC)を接続します。 vc2の黄色の円から「終了」までドラッグします。 View Controller 1からのIBActionがポップアップするはずです。選択してください。
これで、View Controller 2から巻き戻されるたびに、View Controller 1のunwindToViewController1:
メソッドが呼び出されます。
これは、View Controller 2から必要なプロパティを取得する場所です。正しいプロパティを取得するには、segue.sourceViewController
をカスタムView Controllerサブクラスにキャストする必要があることに注意してください。
アプリがiOS 9以降をサポートしている場合、prepareForSegueとほぼ同じデータを渡すことができます。 sender プロパティを持つ UIStoryboardUnwindSegueSourceprepare(for:segue:UIStoryboardSegue、sender:Any?) のsender
プロパティとまったく同じです。
それの使い方:
注:unwindToメソッドの接続は、回答で説明した@ØyvindHaugeと@dfriと同じです。
fromViewController
が元のタイプかどうかを確認しますsender
プロパティを送信したタイプにキャストし、trueを返します。コードの切り取り(Swift 4.0):
@IBAction func unwindToMyFirstViewController(segue: UIStoryboardSegue) {}
override func canPerformUnwindSegueAction(_ action: Selector, from fromViewController: UIViewController, withSender sender: Any) -> Bool {
if fromViewController is MyCustomViewController,
let customType = sender as? MyCustomType {
return true
}
return false
}