In my content view i have function that detects whenever a user copies a website address
ContentView
@State private var detectedurl = ""
.................
.onAppear {
urlclipboardwatcher()
}
func urlclipboardwatcher() {
let pasteboard = NSPasteboard.general
var changeCount = NSPasteboard.general.changeCount
Timer.scheduledTimer(withTimeInterval: 0.2, repeats: true) { _ in
if let copiedString = pasteboard.string(forType: .string) {
...............
if copiedString.starts(with: "https://") {
detectedurl = copiedString
}
}
}
}
I want to pass this value to the textfield in my NewBookmark View. How do i update the textfield with any changes that happen with the pasteboard?
struct NewBookmark: View {
@Binding var detectedurl: String
@ObservedObject private var vm: AddNewBookmarkViewModel
init(vm: AddNewBookmarkViewModel, detectedurl: Binding<String>) {
self.vm = vm
self._detectedurl = detectedurl
}
TextField("Enter a URL", text: $vm.url)
// i want the detected url to automatically populate this textfield
Button("Save") {
vm.save()
}.disabled(vm.url.isEmpty)
AddBookMarkViewModel
class AddNewBookmarkViewModel: ObservableObject {
@Published var url: String = ""
.............
func save() {
do {
let myBM = MyBookmark(context: context)
myBM.url = url
try myBM.save()
} catch {
print(error)
}
}
}
CodePudding user response:
Tbh, I am not really sure how the code which you posted works. But I did something similar in the past. Maybe it helps.
What I basically did is, one viewModel with two views. Both views hold on to the viewModel PasteboardViewModel. PasteboardViewModel is a StateObject which is passed on two the second view via. environmentObject. And url variable in the viewModel is bound to the PasteboardView. So every time this Publisher changes the TextField does it too.
struct ContentView: View {
@StateObject var viewModel: PasteboardViewModel = .init()
var body: some View {
VStack {
.....
PasteboardView()
.environmentObject(viewModel)
}
.onAppear {
viewModel.watchPasteboard()
}
.padding()
}
}
struct PasteboardView: View {
@EnvironmentObject var viewModel: PasteboardViewModel
var body: some View {
TextField(text: $viewModel.url) {
Text("Test")
}
}
}
class PasteboardViewModel: ObservableObject {
@Published var url: String = ""
func watchPasteboard() {
let pasteboard = UIPasteboard.general
var changeCount = UIPasteboard.general.changeCount
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in
if let copiedString = pasteboard.string {
if pasteboard.changeCount != changeCount {
self.url = copiedString
changeCount = pasteboard.changeCount
}
}
}
}
}
