2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Delegateを使ったStoryboard要らずの画面遷移 Swift

Last updated at Posted at 2019-02-13

今回はインターンの復習も兼ねて、簡単なアプリを作成しました。
題して、Delegateを使ったStoryboard要らずの画面遷移。

仕組みはとてもシンプルでボタンが押されたとき画面遷移する。画面遷移したページにあるボタンを押すと元のページに戻るというものです。
インターンを初めて1、2ヶ月目の頃大苦戦した記憶があります。
とりあえず大まかなやったことを書きます。

Storyboardの消去

まずは当然Storyboardの消去から。
参考にしたのはこのページです。
https://qiita.com/rika-tawashi/items/d975c2d9f85e8bb4aef5

手順は以下の4つ。

  • プロジェクト作成
  • 「Main.storyboard」を削除
  • 「Info.plist」の「Main storyboard file base name」を「Main」→なし
  • 「AppDelegate.swift」にビューを定義する

AppDelegate.swiftで以下のコードを入力します。

window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = FirstViewController()
window?.makeKeyAndVisible()
return true

これによりFirstViewControllerが呼ばれます。

AutoLayoutの設定

次にAutoLayoutです。

let nextButton = UIButton()
view.addSubview(nextButton)
nextButton.translatesAutoresizingMaskIntoConstraints = false
nextButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
nextButton.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
nextButton.heightAnchor.constraint(equalToConstant: 150.0).isActive = true
nextButton.widthAnchor.constraint(equalToConstant: 200.0).isActive = true
  • addSubviewとはビューを追加するというものと自分は考えています。
    なのでview.addSubview(nextButton)となります。

  • AutoresizingMaskをAuto Layoutに変換しないよう、translatesAutoresizingMaskIntoConstraintsをfalseにします。

  • NSLayoutAnchorを使って制約をします。centerXAnchorは水平方向の制約、centerXAnchorは垂直方向の制約です。

##呼び出し

  • ボタンが押されたとき関数nextButtonTappedが呼ばれます。それによりプライベート関数のshowNextViewControllerが呼ばれます。

  • showNextViewControllerでNextViewControllerのdelegateを自分にセットします。

  • modalTransitionStyleはモーダルの画面の切り替わり方を設定するものです。
    参考にしたのはこのページです。
    https://qiita.com/osamu1203/items/6c203f3f048f9d7540f3

これより画面遷移されてNextViewControllerが呼ばれます。

    @objc func nextButtonTapped(_ sender: UIButton) {
        showNextViewController()
    }

    private func showNextViewController() {
        let nextVC = NextViewController()
        nextVC.delegate = self
        nextVC.modalTransitionStyle = UIModalTransitionStyle.flipHorizontal
        present(nextVC, animated: true, completion: nil)
    }

プロトコルの定義

  • NextViewControllerにdelegateのためのプロトコル定義します。
  • FirstViewControllerDelegateでdelegateを定義します。
  • backButtonが押されたとき呼ばれます。

protocol FirstViewControllerDelegate: class {
    func nextViewController(_ nextViewController: NextViewController, backButton button: UIButton)
}

extension

最後にextensionでクラスを拡張します。これによってNextViewControllerでbackButtonが押されたとき先ほどのdelegateが呼ばれて、画面遷移が起こり画面が戻ってきます。

extension FirstViewController: FirstViewControllerDelegate {
    func nextViewController(_ nextViewController: NextViewController, backButton button: UIButton) {
        dismiss(animated: true, completion: nil)
    }
}

最後に

今後もちょっとずつ成果物をQiita等に上げていきたいなと思います!
おかしなところ、無駄なところがあればご指摘お願いします!
以下完成したコードになります。

import UIKit

class FirstViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = UIColor.white

        let nextButton = UIButton()

        nextButton.setTitle("Tap!", for: .normal)
        nextButton.backgroundColor = UIColor.orange
        nextButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 30.0)
        nextButton.setTitleColor(UIColor.white, for: UIControl.State.normal)
        nextButton.addTarget(self, action: #selector(nextButtonTapped), for: .touchUpInside)
        view.backgroundColor = UIColor.white
        view.addSubview(nextButton)
        nextButton.translatesAutoresizingMaskIntoConstraints = false
        nextButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        nextButton.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        nextButton.heightAnchor.constraint(equalToConstant: 150.0).isActive = true
        nextButton.widthAnchor.constraint(equalToConstant: 200.0).isActive = true
    }

    @objc func nextButtonTapped(_ sender: UIButton) {
        showNextViewController()
    }

    private func showNextViewController() {
        let nextVC = NextViewController()
        nextVC.delegate = self
        nextVC.modalTransitionStyle = UIModalTransitionStyle.flipHorizontal
        present(nextVC, animated: true, completion: nil)
    }
}

extension FirstViewController: FirstViewControllerDelegate {
    func nextViewController(_ nextViewController: NextViewController, backButton button: UIButton) {
        dismiss(animated: true, completion: nil)
    }
}
import UIKit

protocol FirstViewControllerDelegate: class {
    func nextViewController(_ nextViewController: NextViewController, backButton button: UIButton)
}

class NextViewController: UIViewController {
    
    weak var delegate: FirstViewControllerDelegate?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = UIColor.orange
        
        let backButton = UIButton()

        backButton.setTitle("BACK", for: .normal)
        backButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 30.0)
        backButton.setTitleColor(UIColor.orange, for: UIControl.State.normal)
        backButton.backgroundColor = UIColor.white
        backButton.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside)
        view.backgroundColor = UIColor.orange
        view.addSubview(backButton)
        backButton.translatesAutoresizingMaskIntoConstraints = false
        backButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        backButton.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        backButton.heightAnchor.constraint(equalToConstant: 150.0).isActive = true
        backButton.widthAnchor.constraint(equalToConstant: 200.0).isActive = true
    }
    
    @objc func backButtonTapped(_ sender: UIButton) {
        delegate?.nextViewController(self, backButton: sender)
    }
}
import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?


    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        window = UIWindow(frame: UIScreen.main.bounds)
        window?.rootViewController = FirstViewController()
        window?.makeKeyAndVisible()
        return true
    }
}
スクリーンショット 2019-02-13 20.38.20.png スクリーンショット 2019-02-13 20.38.35.png
2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?