1

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)
        }

    }
    
}

1 Answer 1

3

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
                }
            }
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.