0
1

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.

SwiftUIビューのUIViewControllerにアクセスする

0
Posted at

適当なUIViewControllerRepresentableビューコントローラーを作り追加して他のビューコントローラーへアクセスするコードです。多少強引で黒魔術っぽい方法だろうけど、どうしてもそうしたい時に。

import SwiftUI

public struct ControllerRepresenterView: UIViewControllerRepresentable {
    public typealias UIViewControllerType = UIViewController
    
    private final class ViewController: UIViewController {
        var willAppear: (UIViewController) -> Void = { _ in }
        var didAppear: (UIViewController) -> Void = { _ in }
        override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
            willAppear(self)
        }
        override func viewDidAppear(_ animated: Bool) {
            super.viewDidAppear(animated)
            didAppear(self)
        }
    }
    
    private let viewController = ViewController()
    
    public init(
        willAppear: @escaping (UIViewController) -> Void,
        didAppear: @escaping (UIViewController) -> Void
    ) {
        viewController.willAppear = willAppear
        viewController.didAppear = didAppear
    }
    
    public func makeUIViewController(context: Context) -> UIViewControllerType {
        viewController
    }
    
    public func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
        //
    }
}

使用例

import SafariServices

struct ContentView: View {
    func doNothing(uiViewController: UIViewController) {}
    
    func example(uiViewController: UIViewController) {
        // contentへアクセスする為に
        guard let viewController = uiViewController.parent else { return }
        // ex1: 黄色から青色へ
        viewController.view.subviews.last?.backgroundColor = UIColor.systemBlue
        // ex2: 1秒後にフルスクリーンモーダル表示
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
            let a = "https://www.apple.com/"
            guard let u = URL(string: a) else { return }
            let c = SFSafariViewController(url: u)
            c.modalPresentationStyle = .overFullScreen
            viewController.present(c, animated: true, completion: nil)
        }
    }
    
    var content: some View {
        Color.yellow
    }
    
    var body: some View {
        Group {
            content
        }
        .background(
            ControllerRepresenterView(willAppear: doNothing, didAppear: example)
        )
    }
}
0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?