5

My code is as follows:

class EditorWindow: NSWindow {
    @Binding var keycode : Int

    override func keyDown(with event : NSEvent) {
        super.keyDown(with: event)
        
        print("before", self.keycode, Int(event.keyCode))
        self.keycode = Int(event.keyCode)
        print("after",  self.keycode, Int(event.keyCode))
    }

    init(keycode : Binding<Int>){
        self._keycode = keycode
        super.init(contentRect: NSRect(x: 0, y: 0, width: 480, height: 300),
                   styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
                   backing: .buffered, defer: false)   
    }
}

for detecting key-presses in a macOS app. It detects the key-presses, but for some reason it doesn't set the keycode @Binding variable , i.e. the value doesn't change in the 'before' and 'after' print statements. How can this be possible?

Edit:

For clarification, the keycode variable I am passing in during init is a @State variable:

struct ContentView: View {
    
    @State var keycode : Int = 0
    ...
}

...

class AppDelegate: NSObject, NSApplicationDelegate {

    var window: NSWindow!
    ...

    func applicationDidFinishLaunching(_ aNotification: Notification) {
        
        let contentView = ContentView(userData: UserData(text:""))
        window = EditorWindow(keycode: contentView.$keycode)
        ....
    }
}
1
  • Probably it would be better in your case the approach based on ObservableObject as @EnvironmentObject for ContentView and pass its reference into EditorWindow. Commented Dec 29, 2019 at 7:28

1 Answer 1

4

The @Binding variable must be bound to something (eg. @State), like

struct TestNSWindowBinding: View {
    @State var keyCode: Int = 0
    var body: some View {
        Text("Current key: \(keyCode)")
            .onAppear {
                let window = EditorWindow(keycode: self.$keyCode)
                window.makeKeyAndOrderFront(nil)
            }
    }
}

If it is not bound it just provide own initial state, consider it as external storage, so if no bound then no place to store value, so only default can be returned.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the help! Though, my @ Binding variable is bound to a @ State variable - I edited my question to show how it is bound (in a potentially problematic way?)
You are not allowed to use @State outside of View (Apple recommends always mark it as private to avoid temptation to use it in wrong way), so your initialization must be reversed somehow (eg. as shown).

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.