I have an app which main framework was developed using uikit, and some of its pages were written by SwiftUI and embedded into uikit for display through UIHostingController. Now there is a Swiftui page with TextField, and I want to listen for changes in FocusState to facilitate some operations.
The window init code is as bellow:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
let vc1 = ViewController()
// vc2 is the vc I want, but can not get the change of FocusState
let vc2 = UINavigationController(rootViewController: ViewController())
let vc3 = UINavigationController(rootViewController: UIHostingController(rootView: ContentView()))
let tabBarVC = UITabBarController()
tabBarVC.viewControllers = [vc1, vc2, vc3]
if let tabbarItems = tabBarVC.tabBar.items {
for i in 0..<tabbarItems.count {
let item = tabbarItems[i]
item.title = "Tab\(i+1)"
}
}
window?.rootViewController = tabBarVC
window?.makeKeyAndVisible()
return true
}
Then is the UIKit vc:
import UIKit
import SwiftUI
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let contentView = ContentView()
let hostVC = UIHostingController(rootView: contentView)
guard let hostView = hostVC.view else {
return
}
view.addSubview(hostView)
hostView.frame = view.frame
// Do any additional setup after loading the view.
}
}
And this is the SwiftUI View:
struct ContentView: View {
@State var inputText: String = ""
@FocusState var isFocused: Bool
var body: some View {
VStack {
TextField("Input Textfield", text: $inputText)
.focused($isFocused)
.onChange(of: isFocused) { newValue in
// <- here to get the change of focus flag, only vc1 and vc3 print here , vc2 did nothing
print("focused is \(isFocused)")
}
.padding(50)
Button(action: {
// after click button ,only vc1 and vc3 and focus in TextField
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute:
{
self.isFocused = true
})
}) {
Text("Focus")
}
}
}
}
What I expect is that when TextField enters or exits the editing state, FocusState can change, but in reality, only FocusStates in vc1 and vc3 can be listened to, while FocusStates in vc2 cannot. Due to some business reasons, I must use vc2 type to display the page here, and cannot use vc1 or vc3 type to display the page. Is there a way to listen for changes in FocusState in vc2?