ios 如何在SwiftUI中检测TextField的实时更改?

kmb7vmvb  于 12个月前  发布在  iOS
关注(0)|答案(6)|浏览(182)

我有一个简单的TextField,它像这样绑定到状态'location',

TextField("Search Location", text: $location)

字符串
我想在每次这个字段改变时调用一个函数,类似这样:

TextField("Search Location", text: $location) {
   self.autocomplete(location)
}


我知道有回调函数,onEditingChanged -但是这似乎只在字段被聚焦时被触发。
如何让这个函数在每次更新字段时调用?

flseospp

flseospp1#

SwiftUI 2.0

从iOS 14,macOS 11或任何其他包含SwiftUI 2.0的操作系统中,有一个名为.onChange的新修改器可以检测给定state的任何更改:

struct ContentView: View {
    @State var location: String = ""

    var body: some View {
        TextField("Your Location", text: $location)
            .onChange(of: location) {
                print($0) // You can do anything due to the change here.
                // self.autocomplete($0) // like this
            }
    }
}

字符串

SwiftUI 1.0

对于较旧的iOS和其他SwiftUI 1.0平台,您可以使用onReceive

.onReceive(location.publisher) { 
    print($0)
}

注意,它返回的是更改而不是整个值。如果你需要和onChange一样的行为,可以使用合并,按照@pawello2222提供的答案操作。

owfi6suc

owfi6suc2#

你可以创建一个带有自定义闭包的绑定,像这样:

struct ContentView: View {
    @State var location: String = ""

    var body: some View {
        let binding = Binding<String>(get: {
            self.location
        }, set: {
            self.location = $0
            // do whatever you want here
        })

        return VStack {
            Text("Current location: \(location)")
            TextField("Search Location", text: binding)
        }

    }
}

字符串

wmvff8tz

wmvff8tz3#

如果您需要使用ViewModel,另一种解决方案可能是:

import SwiftUI
import Combine

class ViewModel: ObservableObject {
    @Published var location = "" {
        didSet {
            print("set")
            //do whatever you want
        }
    }
}

struct ContentView: View {
    @ObservedObject var viewModel = ViewModel()

    var body: some View {
        TextField("Search Location", text: $viewModel.location)
    }
}

字符串

nx7onnlm

nx7onnlm4#

iOS 13+

使用onReceive

import Combine
import SwiftUI

struct ContentView: View {
    @State var location: String = ""

    var body: some View {
        TextField("Search Location", text: $location)
            .onReceive(Just(location)) { location in
                // print(location)
            }
    }
}

字符串

pw9qyyiw

pw9qyyiw5#

虽然其他答案可能会起作用,但这一个对我来说是有效的,我需要倾听文本的变化并对其做出React。
第一步创建一个扩展函数

extension Binding {
    func onChange(_ handler: @escaping (Value) -> Void) -> Binding<Value> {
        Binding(
            get: { self.wrappedValue },
            set: { newValue in
                self.wrappedValue = newValue
                handler(newValue)
            }
        )
    }
}

字符串
现在在TextField中对绑定调用change,如下所示。

TextField("hint", text: $text.onChange({ (value) in
      //do something here
  }))


来源:HackingWithSwift

5lwkijsr

5lwkijsr6#

我发现最有用的是TextField有一个名为onEditingChanged的属性,当编辑开始和编辑完成时都会调用它。

TextField("Enter song title", text: self.$userData.songs[self.songIndex].name, onEditingChanged: { (changed) in
    if changed {
        print("text edit has begun")
    } else {
        print("committed the change")
        saveSongs(self.userData.songs)
    }
})
    .textFieldStyle(RoundedBorderTextFieldStyle())
    .font(.largeTitle)

字符串

相关问题