Certainly! When working with SwiftUI, you might need to interact with functions from a UIViewController
. Let’s explore a few approaches to achieve this:
-
Using ObservableObject and Coordinator:
- Create an
ObservableObject
(let’s call itVCLink
) to act as a bridge between your SwiftUI view and theUIViewController
. - Define an enum (e.g.,
LinkAction
) to represent the actions you want to perform. - In your SwiftUI view, use
@StateObject
to hold an instance ofVCLink
. - Use the
.sheet(isPresented:content:)
modifier to present theUIViewController
(your new view) when a button is pressed. - Inside the
UIViewController
, handle the action based on the enum value. - Here’s a simplified example
- Create an
import SwiftUI
import Combine
enum LinkAction {
case takePhoto
}
class VCLink: ObservableObject {
@Published var action: LinkAction?
func takePhoto() {
action = .takePhoto
}
}
class CustomVC: UIViewController {
func action(_ action: LinkAction) {
switch action {
case .takePhoto:
print("Taking a photo!")
// Implement your logic here
}
}
}
struct VCRepresented: UIViewControllerRepresentable {
var vcLink: VCLink
class Coordinator {
var vcLink: VCLink? {
didSet {
cancelable = vcLink?.$action.sink { action in
guard let action = action else { return }
self.viewController?.action(action)
}
}
}
var viewController: CustomVC?
private var cancelable: AnyCancellable?
}
func makeCoordinator() -> Coordinator {
Coordinator()
}
func makeUIViewController(context: Context) -> CustomVC {
CustomVC()
}
func updateUIViewController(_ uiViewController: CustomVC, context: Context) {
context.coordinator.viewController = uiViewController
context.coordinator.vcLink = vcLink
}
}
struct ContentView: View {
@StateObject var vcLink = VCLink()
var body: some View {
VStack {
Text("Main View")
.font(.largeTitle)
.padding()
Button("Take Photo") {
vcLink.takePhoto()
}
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
VCRepresented(vcLink: vcLink)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
-
Using NavigationView and NavigationLink:
- Wrap your main view in a
NavigationView
. - Use a
NavigationLink
to navigate to the new view when a button is pressed. - You can hide the navigation bar if needed.
- Example:
- Wrap your main view in a
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
VStack {
Text("Main View")
.font(.largeTitle)
.padding()
NavigationLink(destination: NewView()) {
Text("Show New View")
}
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
}
.navigationBarTitle("") // Hide the navigation bar title
.navigationBarHidden(true) // Hide the navigation bar
}
}
}
struct NewView: View {
var body: some View {
Text("New View")
.font(.title)
.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}