Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SwiftUI using #155

Open
Spettacolo83 opened this issue Dec 3, 2021 · 6 comments
Open

SwiftUI using #155

Spettacolo83 opened this issue Dec 3, 2021 · 6 comments

Comments

@Spettacolo83
Copy link

Hello there!
I really like your library and I would like to use it on my SwiftUI app.
Can you expose a method to pass to setTargetView a View instead of a UIView?
I'm trying to achieve it using a UIHostingController in this way:

let showcase = MaterialShowcase()
let hc = UIHostingController(rootView: mySwiftUIView)
hc.view.frame = CGRect(x: 100, y: 200, width: 200, height: 100)
showcase.setTargetView(view: hc.view)
showcase.show(completion: {
    print("Showcase completion!")
})

But would be very useful if you can expose that method!
Thanks!

@Spettacolo83
Copy link
Author

Spettacolo83 commented Dec 6, 2021

If someone is interested, I reached that goal in this way:

....

@State private var rect = CGRect.zero

var body: some View {
    ....
    // Component you want to showcase
    HStack {
        ...
    }
    .overlay(
        Color.clear.modifier(GeometryGetterMod(rect: $rect))
    )
    ...
}

func startShowcase(_ rect: CGRect) {
    // Start Help Tour
    let showcase = MaterialShowcase()
    let uiview = UIView()
    uiview.frame = rect
    uiview.layer.cornerRadius = 45
    showcase.setTargetView(view: uiview)
    showcase.show(completion: {
        print("Showcase completion!")
    })
}

....

// Modifier to get the frame of your component
struct GeometryGetterMod: ViewModifier {
    @Binding var rect: CGRect
    func body(content: Content) -> some View {
        return GeometryReader { (g) -> Color in
            DispatchQueue.main.async { // to avoid warning
                self.rect = g.frame(in: .global)
            }
            return Color.clear
        }
    }
}

You can apply an overlay with a transparent color and a GeometryGetterMod in order to save the frame of your component in a @State variable for every component you want to showcase.
Just call startShowcase method passing the right variable like this:

startShowcase(rect)

Feel free to improve this method or comment on Stackoverflow:
https://stackoverflow.com/a/70242413/3677384

@Husseinhj
Copy link
Contributor

Thanks @Spettacolo83, please update the StackOverflow URL, it is incorrect

@Spettacolo83
Copy link
Author

Done! Thank you @Husseinhj

@MuhammadAarfeen
Copy link

@Spettacolo83 hey can you please tell where to call startShowcase(rect) func in swiftUI code?

@Spettacolo83
Copy link
Author

Hey @MuhammadAarfeen, you can call it .onAppear function for example:

var body: some View {
    List {
        ...
    }
    .onAppear {
        startShowcase(rect)
    }
}

@MuhammadAarfeen
Copy link

MuhammadAarfeen commented Sep 2, 2022

@Spettacolo83 Ok great! thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants