LoginSignup
1
5

More than 3 years have passed since last update.

UIViewControllerRepresentableのライフサイクルについて

Posted at

ふと気になったのでPlayground作って試してみた。

作ったPlaygroundはGitHubにも公開しているので良かったら見てみてください。

ソース

import SwiftUI
import UIKit
import PlaygroundSupport

struct SampleView: UIViewControllerRepresentable {
    typealias UIViewControllerType = SampleUIViewController

    func makeUIViewController(context: UIViewControllerRepresentableContext<SampleView>) -> SampleUIViewController {
        print(#function)
        return .init()
    }

    func updateUIViewController(_ uiViewController: SampleUIViewController, context: UIViewControllerRepresentableContext<SampleView>) {
        print(#function)
    }

    func makeCoordinator() -> Coordinator {
        print(#function)
        return .init()
    }
}

extension SampleView {
    class Coordinator: NSObject {
        override init() {
            super.init()
            print(self, #function)
        }
        deinit {
            print(self, #function)
        }
    }
}

class SampleUIViewController: UIViewController {
    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        print(self, #function)
    }

    init() {
        super.init(nibName: nil, bundle: nil)
        print(self, #function)
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        print(self, #function)
    }

    override func loadView() {
        print(self, #function)
        super.loadView()

        let label = UILabel()
        label.text = "Hello world!"

        label.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(label)
        NSLayoutConstraint.activate([
            label.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            label.centerYAnchor.constraint(equalTo: view.centerYAnchor)
        ])
    }

    override func viewDidLoad() {
        print(self, #function)
        super.viewDidLoad()
    }

    override func viewWillAppear(_ animated: Bool) {
        print(self, #function)
        super.viewWillAppear(animated)
    }

    override func viewWillLayoutSubviews() {
        print(self, #function)
        super.viewWillLayoutSubviews()
    }

    override func viewDidLayoutSubviews() {
        print(self, #function)
        super.viewDidLayoutSubviews()
    }

    override func viewDidAppear(_ animated: Bool) {
        print(self, #function)
        super.viewDidAppear(animated)
    }

    override func viewWillDisappear(_ animated: Bool) {
        print(self, #function)
        super.viewWillDisappear(animated)
    }

    override func viewDidDisappear(_ animated: Bool) {
        print(self, #function)
        super.viewDidDisappear(animated)
    }

    deinit {
        print(self, #function)
    }
}

do {
    let view = SampleView()
    print()
    PlaygroundPage.current.setLiveView(view)
    print()
}

let semaphore = DispatchSemaphore(value: 0)
DispatchQueue.global().async {
    sleep(5)
    semaphore.signal()
}
semaphore.wait()
PlaygroundPage.current.liveView = nil

結果

makeCoordinator()
<_TtCV14__lldb_expr_9010SampleView11Coordinator: 0x60000323fa90> init()
makeUIViewController(context:)
<__lldb_expr_90.SampleUIViewController: 0x7f88daee0370> init()
<__lldb_expr_90.SampleUIViewController: 0x7f88daee0370> loadView()
<__lldb_expr_90.SampleUIViewController: 0x7f88daee0370> viewDidLoad()
updateUIViewController(_:context:)
updateUIViewController(_:context:)
<__lldb_expr_90.SampleUIViewController: 0x7f88daee0370> viewWillAppear(_:)
<__lldb_expr_90.SampleUIViewController: 0x7f88daee0370> viewWillLayoutSubviews()
<__lldb_expr_90.SampleUIViewController: 0x7f88daee0370> viewDidLayoutSubviews()
<__lldb_expr_90.SampleUIViewController: 0x7f88daee0370> viewWillDisappear(_:)

makeCoordinator()
<_TtCV14__lldb_expr_9010SampleView11Coordinator: 0x60000323ff00> init()
makeUIViewController(context:)
<__lldb_expr_90.SampleUIViewController: 0x7f88daee4c30> init()
<__lldb_expr_90.SampleUIViewController: 0x7f88daee4c30> loadView()
<__lldb_expr_90.SampleUIViewController: 0x7f88daee4c30> viewWillAppear(_:)
<__lldb_expr_90.SampleUIViewController: 0x7f88daee4c30> viewWillLayoutSubviews()
<__lldb_expr_90.SampleUIViewController: 0x7f88daee4c30> viewDidLayoutSubviews()
<__lldb_expr_90.SampleUIViewController: 0x7f88daee4c30> viewWillDisappear(_:)
<__lldb_expr_90.SampleUIViewController: 0x7f88daee4c30> viewDidLoad()
updateUIViewController(_:context:)
<__lldb_expr_90.SampleUIViewController: 0x7f88daee4c30> viewWillLayoutSubviews()
<__lldb_expr_90.SampleUIViewController: 0x7f88daee4c30> viewDidLayoutSubviews()

<__lldb_expr_90.SampleUIViewController: 0x7f88daee0370> viewDidDisappear(_:)
<__lldb_expr_90.SampleUIViewController: 0x7f88daee0370> viewDidAppear(_:)
<__lldb_expr_90.SampleUIViewController: 0x7f88daee4c30> viewDidDisappear(_:)
updateUIViewController(_:context:)
<_TtCV14__lldb_expr_9010SampleView11Coordinator: 0x60000323fa90> deinit
<__lldb_expr_90.SampleUIViewController: 0x7f88daee0370> deinit
<__lldb_expr_90.SampleUIViewController: 0x7f88daee4c30> viewDidAppear(_:)
<__lldb_expr_90.SampleUIViewController: 0x7f88daee4c30> viewWillDisappear(_:)
<__lldb_expr_90.SampleUIViewController: 0x7f88daee4c30> viewDidDisappear(_:)
<_TtCV14__lldb_expr_9010SampleView11Coordinator: 0x60000323ff00> deinit
<__lldb_expr_90.SampleUIViewController: 0x7f88daee4c30> deinit

Playgroundでやったからなのかもしれないけど今までのライフサイクルと違う呼ばれ方をしてるのでほーんという感じ😇
気になったのはstructの生成時とliveViewへのセット時でmakeUIViewController()が2回呼ばれていたこと。
画面によっては切り替えの度にmakeUIViewControllerが呼ばれてVCが生成されまくるんじゃなかろうか🤔

参考

UIViewControllerのライフサイクル

1
5
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
1
5