Check for "real" view behind AnyView

Viewed 693

Given the following code

import SwiftUI

struct Foo: View {
    var body: some View {
        Text("Hello World")
    }
}

let anyViewFoo = AnyView(Foo())

debugPrint(anyViewFoo)

Is it possible to check foo for the "real" type or e.g. cast to Foo? So something (which obviously doesn't work) like the following would be awesome:

let foo: Foo? = anyViewFoo as? Foo

Does something like this exist?

1 Answers

SwiftUI AnyView does not give access to original view, but we can use our custom to store it and then access.

Note: pay attention - all views are structs, so accessing original view you get a copy (as everywhere in SwiftUI)

Here is a possible approach:

struct AnyMyView: View {

    private let internalView: AnyView
    let originalView: Any

    init<V: View>(_ view: V) {
        internalView = AnyView(view)
        originalView = view
    }
    
    var body: some View {
        internalView
    }
}

and now a demo of usage based on your original code

struct DemoAnyMyView: View {

    let anyViewFoo = AnyMyView(Foo())

    var body: some View {
        VStack {
            // erased type view
            anyViewFoo

            Divider()

            // restored type view
            if let foo = anyViewFoo.originalView as? Foo {
                foo
            }
        }
    }
}

demo

Prepared & tested with Xcode 12.1 / iOS 14.1

Related