How to grab parent sender for UIMenuController - iphone

Context:
I have added my custom menu item to the UIMenuController. Everything works just fine, the canPerformAction is called as expected when the custom item is tapped.
Here is my problem:
within the view where the menu is displayed I have a few textview.
I want to be able to grab the current selected text from the current textview
when the custom menu is tapped.
I can’t because the sender is not the object that is hosting/showing the menu but the menucontroller itself.
How do I find the sender/UI_control (parent?) where the menu has been shown?

The way is supposed to work is:
You add a custom menu in the usual fashion.
In the canPerformAction you filter which action you want to enable/show
When the action occurs you check the current responder and there you apply your logic.
The canPerformAction withSender never returns you the current control that is visually hosting the custom menu.
You can find out who is the first responder looping all the views and check the isFirstResponder property. Or if you have just a couple if you can do a quick check for those two.
// called by canPerformAction
if ([myTextBox isFirstResponder]) {
NSLog(#"Found it!", nil);
}

Related

iPad when dismissing keyboard right nav button wont trigger action

I have a a view controller to create an item within my app, once the required text field in the view has been completed you can press the save icon in right hand navigation button.
The UIBarButtonItem is created as a property of the view controller thus:
let add = UIBarButtonItem(title: "Save", style: .done, target: self, action: #selector(save))
The action simply saves the item to Core Date and pops the view from the navigation controller.
The add button is programmatically added to the UINavigationItem and setup in viewDidLoad.
One of the fields is a required text field so I have the following code to determine if its possible to save the item:
#IBAction func editingChanged(_ sender: UITextField) {
add.isEnabled = sender.hasText
}
If the required field is populated the add button is enabled, otherwise it is not.
When testing on an iPad (iOS 15) after typing some text in to the text field and dismissing the keyboard, although the add button shows as active it actually wont execute the given selector to save the item until the keyboard is displayed again.
All of the other items in the view, such as scroll wheels and segmented controls continue to work as expected when the keyboard is dismissed.
Is there a known reason that dismissing the keyboard would disable the right nav button without setting its state to disabled? or that would prevent it from executing its associated action?
Or have I simple set something up incorrectly?
For reference I am not "moving" or adjusting the view or controls in the view to accommodate the keyboard.
The App targets iOS version 12.
Update
The left navigation button works as expect, it displays the previous view in the navigation stack.
The right navigation button looks as though it is responding to taps, just not executing its attached action.
Why would the present or absence of the keyboard impact the right navigation button performing its associated action?

How to detect a click from an NSToolbarItem inside an NSWindowController?

I have a toolbar on my macOS app, developed in Swift. The toolbarItem is dragable onto the NSWindowController, and I can setup an IABAction function, I just have a print in the function at the moment. And when I click on the button nothing happen the click does not seem to be recognised as an action ?
I had a few more line of code in the function but deleted it and now have just the print("test") line.
#IBAction func exportCsvClicked(_ sender: NSToolbarItem) {
print("test") }
No output observed, so I'd love to get "test" in the console when I click on this button.
Here is a list of the connections associated with the toolbarItem.
I found a way to get around the fact that the IBAction from an NSToolbarItem does not recognise the click on this item:
1/I made a customSegue from the item to the main window controller (it can go anywhere)
2/The prepare for segue function posts a notification to the notification saying that the item has been clicked.
3/The main view controller observes the notification and presents, either has a popup or a sheet (I got two buttons), the view that I have setup in the storyboard (referencing with the storyboardID). I found that you need to pass on all the necessary variable to setup the view from the main view Controller, and that there was issue of code in the viewDidLoad function of the sheet/popup view not running, I am suspecting that they might be different instances.

How to make the system menu a toggle button than a dropdown

So I made this simple Cocoa app. I’m a beginner to Swift and was just experimenting with it. This app toggles between hide/show desktop icons by clicking the menu item from the status bar item’s dropdown. I don’t want such a dropdown to happen and rather just directly toggle between show/hide desktop states on clicking it. How can I achieve this using Swift?
A hacky solution that worked for me: Implement the NSMenu delegate method menuNeedsUpdate(menu: NSMenu) to detect the click, remove all menu items and do your click action within this method.
func menuNeedsUpdate(menu: NSMenu) {
menu.removeAllItems()
NSLog("menu clicked !")
}
Don't forget to set the menu's delegate in the same class so that your method will be called.
statusMenu.delegate = self

how to delete tablerow using uiactionsheet?

I have a tableview of items and when i click one row, I use uiactionsheet with 3 button: edit, remove and cancel. When I click button edit, I will open a modal view, so how can I do this ? what is the code to delete tablerow ?
If you want to delete a row from a UITableView, use the method named deleteRowsAtIndexPaths:withRowAnimation:. You can find all the details on the UITableView Class Reference page.
Also don't forget to remove the corresponding item from your model!
UIActionSheet has a delegate property. Add the UIActionSheetDelegate protocol to your view controller and set yourself as the delegate to the action sheet before you display it.
The action sheet will call
– actionSheet:clickedButtonAtIndex:
on it's delegate when the user selects and action.
In your implementation of this, you can do what you want, such as delete the row as fguchelaar described.
This method doesn't directly know which row the action sheet was called for, so you can either subclass UIActionSheet so it can store the indexPath, store the indexPath in your viewController, or pass the information in some other way.

iOS - Change a ViewController with the keyboard "next" button?

I've noticed it's possible to trigger actions and to move through text fields using the done/next/return key in the bottom right of the iOS keyboard. Would it be possible to maybe change a view or trigger a segue with that button?
For example, it would be cool to be able to type something into a UITextField, and then just tap "Next" to move onto the next viewController instead of having to use a separate button, or navigation item.
May be a stupid question, but something that I've been wondering if it was possible for a while.
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
//Next button was pressed
//Push some viewcontroller here
return YES;
}
make sure you set the delegate of the UITextField to self
It is possible. If it's a UITextField, you can implement textFieldShouldReturn:. If it's a UITextView, you implement textView:shouldChangeTextInRange:replacementText:, and look for \n in the replacement text.
In either case, you can then perform a segue, do a navigation or modal push, etc.