Skip to content

Instantly share code, notes, and snippets.

@KentarouKanno
Last active June 10, 2018 08:38
Show Gist options
  • Save KentarouKanno/512a0ca00f806f209fe2fdc41fdd2b43 to your computer and use it in GitHub Desktop.
Save KentarouKanno/512a0ca00f806f209fe2fdc41fdd2b43 to your computer and use it in GitHub Desktop.

画面間の値渡し(Swift4)

Delegateによる値渡し

ViewController.swift

import UIKit

// 遷移元画面
class ViewController: UIViewController {

    // 遷移先画面からの値を表示するラベル
    @IBOutlet weak var label: UILabel!
    
    // ボタン押下時に画面遷移
    @IBAction func pushNext(_ sender: UIButton) {
        // Segueにより画面遷移
        performSegue(withIdentifier: "Next", sender: nil)
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let next = segue.destination as? NextViewController {
            // Delegateを自分に設定
            next.delegate = self
        }
    }
}

// Extensionでプロトコルを実装
extension ViewController: NextViewControllerDelegate {
    
    // Delegateメソッド
    func setText(_ text: String) {
        // ラベルに値を設定
        label.text = text
    }
}

NextViewController.swift

// Protocol
protocol NextViewControllerDelegate: class {
    func setText(_ text: String)
}

// 遷移先画面
class NextViewController: UIViewController {
    
    weak var delegate: NextViewControllerDelegate?
    
    // ボタン押下時に遷移前画面に値を渡す
    @IBAction func pushBack(_ sender: UIButton) {
        // Delegate呼び出し
        delegate?.setText("NextViewController -> ViewController")
        
        // 遷移前画面に戻る
        navigationController?.popViewController(animated: true)
    }
}

通知(Notification)による値渡し

ViewController.swift

import UIKit

extension NSNotification.Name {
    // 通知名を定義
    static var nextViewNotification = NSNotification.Name(rawValue: "NextViewNotification")
}

// 遷移元画面
class ViewController: UIViewController {

    // 遷移先画面からの値を表示するラベル
    @IBOutlet weak var label: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 通知を登録
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(nextViewControllerCall(notification:)),
                                               name: NSNotification.Name.nextViewNotification,
                                               object: nil)
    }
    
    // 通知から呼ばれる
    @objc func nextViewControllerCall(notification: Notification) {
        
        // 通知から渡された値を取り出す
        if let text = notification.object as? String {
            // ラベルに値を設定
            label.text = text
        }
    }
    
    // ボタン押下時に画面遷移
    @IBAction func pushNext(_ sender: UIButton) {
        // Segueにより画面遷移
        performSegue(withIdentifier: "Next", sender: nil)
    }
}

NextViewController.swift

// 遷移先画面
class NextViewController: UIViewController {
    
    // ボタン押下時に遷移前画面に値を渡す
    @IBAction func pushBack(_ sender: UIButton) {
        // 通知呼び出し
        NotificationCenter.default.post(name: Notification.Name.nextViewNotification,
                                        object: "NextViewController -> ViewController")
        
        // 遷移前画面に戻る
        navigationController?.popViewController(animated: true)
    }
}

Closureによる値渡し

ViewController.swift

import UIKit

// 遷移元画面
class ViewController: UIViewController {

    // 遷移先画面からの値を表示するラベル
    @IBOutlet weak var label: UILabel!
    
    // ボタン押下時に画面遷移
    @IBAction func pushNext(_ sender: UIButton) {
        // Segueにより画面遷移
        performSegue(withIdentifier: "Next", sender: nil)
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let next = segue.destination as? NextViewController {
            // クロージャーを設定
            next.closure = { (text) in
                self.label.text = text
            }
        }
    }
}

NextViewController.swift

// 遷移先画面
class NextViewController: UIViewController {
    
    // クロージャープロパティ
    var closure: ((String) -> Void)?
    
    // ボタン押下時に遷移前画面に値を渡す
    @IBAction func pushBack(_ sender: UIButton) {
        // クロージャー呼び出し
        closure?("NextViewController -> ViewController")
        
        // 遷移前画面に戻る
        navigationController?.popViewController(animated: true)
    }
}

Unwind Seguesによる値渡し

  • 受け取る方法が2種類ある
    • ① 遷移元画面に値を渡す
    • ② 遷移先画面から値を取得する

ViewController.swift

import UIKit

// 遷移元画面
class ViewController: UIViewController {

    // 遷移先画面からの値を表示するラベル
    @IBOutlet weak var label: UILabel!
    
    // ボタン押下時に画面遷移
    @IBAction func pushNext(_ sender: UIButton) {
        // Segueにより画面遷移
        performSegue(withIdentifier: "Next", sender: nil)
    }
    
    // ②遷移先画面から値を取得する
    @IBAction func backToNextViewController(segue: UIStoryboardSegue) {
        
        if let next = segue.source as? NextViewController {
            self.label.text = next.text
        }
    }
}

NextViewController.swift

// 遷移先画面
class NextViewController: UIViewController {
    
    // 値渡しの為のプロパティ
    var text: String = ""
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        text = "NextViewController -> ViewController"
    }
    
    // ①遷移元画面に値を渡す
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let vc = segue.destination as? ViewController {
            vc.label.text = text
        }
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment