Reputation: 784
I have an ImageEditView
that contains an ImageCanvasView
and an ImageCaptureButton
.
Ideally, I want ImageCaptureButton
to call a method on ImageCanvasView
called takeScreenshot
.
How do I achieve this in SwiftUI? I've been thinking of trying to save ImageCanvasView
into a variable in ImageEditView
so that my ImageCaptureButton
can then call its method, but SwiftUI's declarative nature means this isn't possible.
----- EDIT below -----
The flow is as follows:
The following is ImageEditView
import SwiftUI
struct ImageEditView: View {
@State var selectedImage: Image
@State private var isNavLinkPresented = false
@State private var imageSnapshot: UIImage = UIImage()
var canvasView: ImageCanvasView = ImageCanvasView(selectedImage: $selectedImage)
// this won't work: Cannot use instance member '$selectedImage' within property initializer; property initializers run before 'self' is available
var body: some View {
VStack {
canvasView
Spacer()
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
NavigationLink(destination: ImageShareView(imageToShare: $imageSnapshot), isActive: $isNavLinkPresented) {
Text("Next")
.onTapGesture {
imageSnapshot = canvasView.takeScreenshot()
isNavLinkPresented = true
}
}
}
}
.navigationBarTitle(Text("Edit image"))
}
}
Upvotes: 0
Views: 2372
Reputation: 18894
You are in the right direction. By creating var of the view, you can call the function. Here is the example demo
struct ImageEditView: View {
var canvasView: ImageCanvasView = ImageCanvasView()
var body: some View {
VStack {
Text("ImageEditView")
canvasView
Button("ImageCaptureButton") {
canvasView.takeScreenshot()
}
}
}
}
struct ImageCanvasView: View {
var body: some View {
Text("ImageCanvasView")
}
func takeScreenshot() {
print(#function + " Tapped ")
}
}
You can also use computed property to pass data
struct ImageEditView: View {
var data: String = ""
var canvasView: ImageCanvasView {
ImageCanvasView(data: data)
}
// Body code
}
struct ImageCanvasView: View {
var data: String
var body: some View {
Text("ImageCanvasView")
}
func takeScreenshot() {
print(#function + " Tapped ")
}
}
EDIT Use init to use the same instance of ImageCanvasView.
struct ImageEditView: View {
@State var selectedImage: Image
@State private var isNavLinkPresented = false
@State private var imageSnapshot: UIImage = UIImage()
var canvasView: ImageCanvasView!
init(selectedImage: Image) {
self.selectedImage = selectedImage
canvasView = ImageCanvasView(selectedImage: $selectedImage)
}
// Other code
Upvotes: 2