Xamarin Mac minimize to tray on close button - macos

I want change behavior of standard close button of window. When user clicked on it then minimize to tray, not close window. How can I do this?
P.S Here is a small video example of this behavior on Slack application. I want do same.

Override the applicationShouldTerminateAfterLastWindowClosed method in appdelegate like:
public override bool ApplicationShouldTerminateAfterLastWindowClosed(NSApplication sender)
{
return false;
}

Related

Open infinite window of Preferences Pane in Cocoa app when using segue

I want to open a preference pane in my Cocoa app when an user taps the Preferences... menu or typing ⌘+,. So I connected from the preferences menu item to the window controller in storyboard as a show segue.
However, while this opens the preference pane when an user taps Preferences..., if the user taps the menu item again before closing the pane, another pane is going to be launched and displayed on the screen.
I want to have only one preference pane in my screen but how can I do that? I want to set it up only on storyboard and avoid coding that makes the nest of nest of boring menu items...
In order to prevent the windows from being launched multiple times, you select Single from the Window Controller's Attribute Inspector on Storyboard.
The default value is Multiple, causing the infinite windows to be launched.
Alternatively, if you want to use the code, here is something I will do in AppDelegate.swift.
extension AppDelegate: NSSeguePerforming {
func shouldPerformSegueWithIdentifier(identifier: String, sender: AnyObject?) -> Bool {
if identifier == OpenPreferencesIdentifier {
let windows = NSApp.windows
for window in windows {
if window.windowController?.className == MyPreferencesWindowController.className() {
return false
}
}
}
return true
}
}
Also do NOT forget to set the appropriate segue identifier on Storyboard.

How to close a Full-Screen mode NSWindow programmatically?

My application has two windows(main and video) and both can enter the Full-Screen mode independently. And the main window has a button to toggle the video window's visibility. When the video window is visible, the button simply sends close message like this:
[theVideoWindow close];
It works perfectly when the video window is not in the Full-Screen mode.
But when the video window is running in the Full-Screen mode, the window looks like being ordered out (closed), but it is still alive (like an invisible window) and accepts mouse event. The user cannot interact with other applications because the invisible window eats up all the mouse events and cannot close it because the title bar and menu are gone.
Are there any best practices to close a Full-Screen mode window programmatically other than exiting from the Full-Screen mode first and then closing it in NSWindowDidExitFullScreenNotification notification handler?
Thanks in advance.
It seems to be my mistake. The other developer, explicitly send orderFront: in the NSWindowDidExitFullScreenNotification notification handler to make the window visible just after exiting from the Full-Screen mode and it made the window was still alive.
On my app, I check if window is on Fullscreen and then I use ToogleFullScreen method
- (BOOL)isFullScreen {
return ((self.window.styleMask & NSFullScreenWindowMask) == NSFullScreenWindowMask);
}
if([self isFullscreen]) {
[self.window toggleFullScreen:nil];
}
#Saul's solution in Swift 4:
func isFullScreen() -> Bool {
guard let window = view.window else { return false }
return window.styleMask.contains(.fullScreen)
}
if isFullscreen() {
view.window?.toggleFullScreen(nil)
}

No keyboard capture without title bar

I am trying to build an animation using spriteKit and that could be controlled via keyboard (arrow keys to speed up, slow down, rewind the animation).
Also I need this application to have a completely transparent background, this I managed using :
scene?.backgroundColor = NSColor.clearColor()
as well as :
self.window.opaque = false
Up until now everything is working fine and I am able to control my animation. But as soon as I try to remove the title bar in Interface Builder by unchecking the box for my window on the right panel the keyboard capture stops working.
keyDown: is not called anymore and I get that 'dong' sound characteristic of when your mac tells you that keyboard input is not an option. Even though I still have the name of my app on the menu bar.
Is there any way to still be able to receive keyboard input when the title is off ?
By default NSWindow instances return false from canBecomeKeyWindow if the window has no title bar. The following quote is from the relevant section in the NSWindow class reference.
Attempts to make the window the key window are abandoned if this method returns false. The NSWindow implementation returns true if the window has a title bar or a resize bar, or false otherwise.
So, to get the behaviour you're after you need to subclass NSWindow, and return true from canBecomeKeyWindow.
As pointed out by Paul Pattersion (accepted answer) the trick was to subclass NSWindow in order to return true for canBecomeKeyWindow. For anyone wondering how to do that, here is the code:
import Cocoa
class CustomWindow: NSWindow {
override var canBecomeKeyWindow: Bool {
get { return true }
}
}

Stopping a popover window becoming the key window

I am trying to write a Mac application which runs in the menubar, which when clicked, displays an iOS-like popover. Similar to Flexibit's Fantastical, or The Iconfactory's Take Five.
I am using INPopoverController which seems to work great.
My problem is that when the user clicks on anything in the popover view, the popover becomes the key window. Is there a way to stop this from happening?
In INPopoverWindow:
- (BOOL)canBecomeKeyWindow
{
return YES;
}
means that the popover can become a key window. You can either change it to return NO, or subclass INPopoverWindow and override that method to return NO.

resignFirstResponder not hiding keyboard on textFieldShouldReturn

I have a view with a UITextField which should hide the keyboard when return is pressed.
My function is this:
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
if ( textField == userPassword ) {
[textField resignFirstResponder];
}
return YES;
}
Normally the keyboard should be hidden but it stays on the screen. resignFirstResponder is correctly called. What am I missing?
I see you have the iPad tag on this. Do you happen to be presenting a modal view using UIModalPresentationFormSheet? If so, it looks like this is a limitation of the FormSheet modal presentation (either Apple is doing it intentionally for some reason, or it is a bug). See these other questions for more details:
Modal Dialog Does Not Dismiss Keyboard
Modal View Controller with keyboard on landscape iPad changes location when dismissed
There is this helpful method which allows you to dismiss the keyboard when presenting the Modal Dialog:
- (BOOL)disablesAutomaticKeyboardDismissal { return NO; }
This will override the default behavior of the modal dialog set by Apple and allow you dismiss the keyboard. It is in the UIViewController Class.
I hope this helps someone!
If you are using the Interface Builder, look if your UITextField has the delegated linked with your class.
-Select your UITextField and in your Connections look if exits one connection in Outlets->delegate. If not, conect with you File's Owner Class.
This need to be linked with your File's Owner Class. This delegate tell where to search for a method. If your are overriding a method, you need to tell where the object will search for that.
This solution worked for me after none of the above did. after calling resignFirstResponder i added a modal view & removed it.
[myTextField resignFirstResponder];
UIViewController *dummyController = [[UIViewController alloc] init];
UIView *dummy = [[UIView alloc] initWithFrame:CGRectMake(-1, -1,1,1)];
[dummyController setView:dummy];
[self presentModalViewController:dummyController animated:NO];
[dummyController dismissModalViewControllerAnimated:NO];
To deal with the bug mentioned by Brandon, you can try closing and re-opening your modal view controller as long as you still have a reference to it.
[textField resignFirstResponder];
[self dismissModalViewControllerAnimated:NO];
[self presentModalViewController:yourModalViewControllerReference animated:NO];
(where "self" should be the controller you used to originally open the modal view controller)
I was having the same problem. I realized that after connecting the delegate to the File's Owner in Interface Builder, I neglected to save in Interface Builder. Once I saved, I recompiled and the keyboard disappears correctly when hitting return.
xcode 4.5.1
Simply click control then on the textfield drag and release on the .h file
(control key+ drag)
then in the pop up menu select
connection=acton;
name= any name;
type=id;
event=did end on exit;
arguments=sender;
then click connect button
Did you remember to implement the UITextFieldDelegate protocol?
I have read so many articles about this issue, where the onscreen keyboard refuses to hide when you call resignFirstResponder, but none of the suggestions worked for me.
I'm using XCode 5 (iOS 7) and have a iPhone screen containing a couple of controls which require the onscreen keyboard, but if the user clicks on the UIButton, then I want the keyboard to disappear.
I probably wasted one full day experimenting with resignFirstResponder and adding disablesAutomaticKeyboardDismissal functions to return NO, but nothing worked. Once the onscreen keyboard appeared, I could never get it to disappear again.
But then I had a small brainwave (as I only have a small brain).
Now, when the user clicks on my UIButton, I simply disable the UITextField and UITextView controls.
- (IBAction)btnDate_Tapped:(id)sender {
// The user has clicked on the "Date" button.
self.tbClientName.enabled = NO;
self.tbComments.editable = NO;
And suddenly, the app finds it has no editable text fields needing an onscreen keyboard, and it neatly slides the keyboard out of sight.
(Relieved sigh.)
My UIButton actually makes a popup dialog appear. When the user dismisses the popup, I re-enable these two controls, so if the user taps in one of them, the keyboard will appear again.
-(void)popoverControllerDidDismissPopover:(UIPopoverController *) popoverController {
// The user has closed our popup dialog.
// We need to make our UITextField and UITextView editable again.
self.tbClientName.enabled = YES;
self.tbComments.editable = YES;
... etc...
}
Simple, isn't it !
And surprisingly, this workaround even works on UIViewControllers which appear in Modal style.
I hope this helps other XCode victims out there.
Based on your comment that it looks like focus has shifted, then I think what may be happening is that the keyboard is staying open for the next text input field. If your return key is a "Next" key, then returning YES for textFieldShouldReturn: will make the next textField the first responder, and keep the keyboard visible.
The easiest way is:
Go to your user interface builder,
select UITextField and "Control-Drag" to "Detail View Controller-Detail" and release.
The window will pop-up. Then under "Outlets" select "Delegate".
That's it. It worked for me.
if you are in UIModalPresentationFormSheet just call
- (BOOL)disablesAutomaticKeyboardDismissal
{
return NO;
}
Swift 3.0:
override var disablesAutomaticKeyboardDismissal: Bool {
get{
return false
}
set {
self.disablesAutomaticKeyboardDismissal = false
}
}
Swift 3.0
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
if textField == addressTextField {
textField.resignFirstResponder()
return false
}
return true
}

Resources