OSX NSTextView becomes uneditable after showing NSAlert,NSOpenPanel - swift

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:
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

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.

Related

How to give the focus to the text field?

Very simple setting: I have a ViewController scene with a TextField on it. The ViewController is the text field's delegate.
I would like to have the following behavior: When the user enters the text field (i.e., taps on it), I would like to display a modal alert box with an OK button. After the users presses OK, the TextField should get the focus (i.e., cursor blinking inside it).
I can't get this working. I react on the user tapping in the text field by textFieldShouldBeginEditing(). This works in the sense that I can display the message box there. But after the user (in this case it's me ;o)) taps the OK button, the text field doesn't have the focus, and when I tap it again, the message box appears again.
How can I get rid of this?
Do you really want the modal dialog to show every time the text field is clicked? Bear in mind that putting the activation in textFieldShouldBeginEditing() will mean that re-activating the field after dismissing the dialog will re-show the dialog.
Maybe you just need to show the dialog once? In which case a simple boolean flag that is set on first showing will fix the issue. I.e. at view controller scope:
var hasShownWarningDialog = false
and then implement instead (after comments):
func textFieldShouldBeginEditing(textField: UITextField) -> Bool
{
if !hasShownWarningDialog
{
hasShownWarningDialog = true
// Create dialog here
self.present(alert, animated: true, completion: {self.textField.becomeFirstResponder()})
return false
}
else
{
return true
}
}

Hide TableView when cancel button clicked

i’m trying to realize a search bar with a TableView. Everything is working like this: when i touch the search bar for add text the TabeView(before hidden) compare with the auto compilator and there i write. What i’m trying to do is hide the TableView when i tap the button cancel and hide again the tableView but is not working correct because after that i tap cancel and my table hide as i want then i can’t TableView is not working. I tried using "tableview is hidden when cancel button clicked" but my table doesn't work later. How can i do? Do you have some ideas? Thank you guys
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searching = false
searchBar.text = ""
TableVieww.reloadData()
TableVieww.isHidden = true
}
Try:
TableVieww.layer.alpha = 0.0

Is it possible use different instance of UIMenuController for UITextField in Swift?

According to link we should use a singleton UIMenuController instance which is referred to the editing menu.
The problem is I want to show extra items in different situations. For instance, I want to just show "copy" item when keyboard is up. and show "copy" and "reply" when tapping on a tableview row.
When I add "reply" to the UIMenuController instance it is shown when tapping on UITextField too. therefore, I added these codes:
func textViewDidBeginEditing(_ textView: UITextView) {
var nonReplyMenuItems: [UIMenuItem] = []
if let allMenuItems = UIMenuController.shared.menuItems {
for menuItem in allMenuItems {
if menuItem.title != "reply".localized {
nonReplyMenuItems.append(menuItem)
}
}
}
UIMenuController.shared.menuItems = nonReplyMenuItems
UIMenuController.shared.setMenuVisible(true, animated: true)
}
It fixed the problem in most situations, but not all.
when keyboard is up and tapping on a row in tableview "reply" will be added. Then when I tap on UITextView the reply will be shown there too.
It seems your scenario is like it:
tap on textfield ----> shows copy
tap on tableview ---> shows copy and reply
tab on textfield ----> shows copy and reply (you want only copy shows)
As I know the textViewDidBeginEditing calls when your text filed is not editing and you tap on that; So if you have two textfileds by switching on that method calls every time but when you are switching between a text filed and another action base object your text field is editing and its state has not changed.
When you touch on tableview you must call textfield.resignFirstResponder() so when you tap on text field again the textViewDidBeginEditing calls again, the problem of this is hiding keyboard; The better way I preferو is adding function to touch down of text field or on gesture to do what you write on textViewDidBeginEditing method

Button text not staying changed when editing table

I have a tableview controller with dynamic cells. One of the cells has a button to toggle editing the table, so that the user is less likely to delete something and has to actively enable editing.
When they press the button it is supposed to toggle editing the table and the text of the button. Editing the table works, but the text for the button just flashes then goes back to the original text.
#IBAction func deleteTouched(sender: UIButton) {
editing = !editing
let indexPath = NSIndexPath(forRow: 1, inSection: 0)
let cell = tableView.cellForRowAtIndexPath(indexPath) as! FieldInfoCell
cell.deleteButton.titleLabel?.text = editing ? "Done" : "Delete Estimates"
}
I first tried referencing the sender instead of the button in the cell
#IBAction func deleteTouched(sender: UIButton) {
editing = !editing
sender.titleLabel?.text = editing ? "Done" : "Delete Estimates"
}
Why does the text flash to Done and then back to Delete Estimates when I enable editing?
Instead of setting text button's title label use setTitle method like
button.setTitle("<#your title#>", forState: .Normal)
Because button needs title, titleColor, image, backgroundImage, attributedTitle etc for each state(.Normal,.Selected,.Highlighted etc). Each time button changes its state these properties get refreshed based on the state - even if you set titleLabel.text or imageView?.image. You can set font,layer properties for titleLabel and imageView

Adding long press gesture recognizer to UITextView

I'm trying to let the user move a text view around the screen as he presses down on it. The issue I'm getting is my gesture recognizer isn't getting called and instead the text is being selected when I press down on it. How can I disable this? I can't just disable user interaction because a tap should still let the user edit the text. My code is below
let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: "longPressed:")
text.addGestureRecognizer(longPressRecognizer)
func longPressed(sender : UITextView) {
println("long press")
}
Try adding this tiny piece of code. Sometimes it makes magic happen ;)
text.userInteractionEnabled = true