Search code examples
swiftxcodemacosnsalert

OSX NSTextView becomes uneditable after showing NSAlert,NSOpenPanel


I've got a NSTextView in my view that works as it should, but when I show a NSAlert and close it, it becomes uneditable (with text still selectable). The NSAlert is a save/cancel alert that updates the textView's string when the user selects save, the string is not updated when the user presses cancel. In both cases the textView was uneditable, the alert is shown when the users has made changes and wants to change the tableView selection.

It feels like the textView refuses first responder but when breaking and checking in the console its "true", I also checked some other values after the view was uneditable:

  • isEditable was True
  • isSelectable was True
  • canBecomeKeyView was True
  • acceptsFirstResponder was True
  • acceptsTouchEvents was False, tested True but did not work

My "test" setup: Setup

Video, same when triggering the popup from a tableview selection change and a button : video

My popup code

func dialogOKCancel(question: String, text: String) -> Bool {
        let myPopup: NSAlert = NSAlert()
        myPopup.messageText = question
        myPopup.informativeText = text
        myPopup.alertStyle = NSAlertStyle.warning
        myPopup.addButton(withTitle: "OK")
        myPopup.addButton(withTitle: "Cancel")

        return myPopup.runModal() == NSAlertFirstButtonReturn
    }

let answer = self.dialogOKCancel(question: "Ok?", text: "Choose your answer.")

also tried:

        let a = NSAlert()
        a.messageText = "Delete the document?"
        a.informativeText = "Are you sure you would like to delete the document?"
        a.addButton(withTitle: "Delete")
        a.addButton(withTitle: "Cancel")
        a.alertStyle = NSAlertStyle.critical

        a.beginSheetModal(for: self.view.window!, completionHandler: { (modalResponse) -> Void in
            if modalResponse == NSAlertFirstButtonReturn {
                print("Document deleted")
            }
        })

Stuff I tried:

  • Remove any textView updates, showing the alert still breaks it
  • Dragging a new "untouched" textView in my storyboard but now both textViews became uneditable
  • I tried showing the NSAlert when clicking a button instead of when changing the tableView's selection. Here the textView I was editing stays first responder but as soon as Ieave the textView, its uneditable again.
  • I tried triggering just an animation instead of the NSAlert, here the textView keeps working
  • I Tried replacing the NSAlert with a overlay View that had a title/description/buttons. when showing this dialog, the textView also became uneditable

I'm stuck on this for a long time and any help is greatly appreciated, Thanks


Solution

  • After long time of debugging, I found this line to be the one that broke the textfields, I will leave this post online in case someone else stumbles upon this weird problem

    window?.styleMask = NSFullSizeContentViewWindowMask
    

    removing this line fixed the problem.