简体   繁体   中英

Update inputAccessoryView in SwiftUI (UIViewRepresentable)

I want to display search results above the keyboard with SwiftUI. For this, I made a UIViewRepresentable for UITextField and set the inputAccessoryView accordingly.

Everything is displayed correctly, but the inputAccessoryView is not updating.

 struct V_ToolbarTextField<Content: View>: UIViewRepresentable {
    
    var title: String
    @Binding var text: String
    var keyType: UIKeyboardType
    
    var toolbarContent: Content
        
    init(_ title: String,
         text: Binding<String>,
         keyType: UIKeyboardType = .alphabet,
         toolbarContent: Content) {
        self.title = title
        self._text = text
        self.keyType = keyType
        self.toolbarContent = toolbarContent
    }
    
    
    func makeUIView(context: Context) -> UITextField {
        let textfield = UITextField()
        textfield.keyboardType = keyType
        textfield.placeholder = title

        let textUIKit = UIHostingController(rootView: toolbarContent)
        textUIKit.view.frame = CGRect(x: 0, y: 0, width: 800, height: 60)

        textfield.inputAccessoryView = textUIKit.view
        return textfield
    }
    
    func updateUIView(_ uiView: UITextField, context: Context) {
        uiView.text = text
    }
}

This is how I am passing the inputAccessoryView 's content:

 V_ToolbarTextField("Title",
                    text: $gameNameFilter, 
                    toolbarContent: 
                     viewContainingSearchResults())

I've tried binding toolbarContent and setting the inputAccessoryView in updateUIView() . I've also tried creating a Coordinator class and setting the UITextField 's delegate to it, hoping to use a UITextFieldDelegate function to update it, but I don't know which one and I wasn't able to set the delegate correctly.

I couldn't get it to work and ditched the inputAccessoryView for a VStack with the ToolBar at the bottom. I hide it when the keyboard is shown.

@State var keyboardOpen = false

VStack {
    
    // everything else...
    
    if (keyboardOpen) {
        V_FilteredGameList(filter: vm.gameName, action: { game in
            vm.setExistingGame(game: game)
            hideKeyboard()
        })
    }
}
.onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillShowNotification)) { _ in
        keyboardOpen = true
}
.onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillHideNotification)) { _ in
        keyboardOpen = false
}

Try calling reloadInputViews() on your textfield. Most likely you want to do it on updateUIView function.

open func reloadInputViews() by Apple documentation: // If called while object is first responder, reloads inputView, inputAccessoryView, and textInputMode. Otherwise ignored

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM