NSSavePanel cancel confirmation - cocoa

I have a NSSavePanel and I want to handle the "Cancel" button action to prevent closing the sheet. A want to show the confirmation alert above the savePanel sheet like it is done if you want to overwrite file when saving.
What is the best way to implement this?
Thanks

Some thing like this should work for you-
- (IBAction)showSavePanel:(id)sender
{
NSSavePanel *mySavePanel = [NSSavePanel savePanel];
if ([mySavePanel runModal] == NSOKButton) {
NSLog(#"OK selected");
}
else { // cancel button selected
NSBeginAlertSheet(#"Are you sure", #"Yes", nil, #"No", mySavePanel, self, #selector(sheetDidEndShouldDelete:returnCode:contextInfo:), NULL, sender , #"Your custom message");
}
}
For additional details you can go through this document - Introduction to Sheets

Related

How to create a action for UIReturnKeyType.Done in UITextView in xamarin iOS

I am trying to change the UITextView keyboard return button in to Done button.
I need to close the keyboard when I press the Done button.
I have create a UITextView and change the return button in to Done button.
This is my code
PhotoTitle = new UITextView
{
TranslatesAutoresizingMaskIntoConstraints = false, Editable = true, AccessibilityIdentifier = "PhotoTitle",
ReturnKeyType = UIReturnKeyType.Done
}
The keyboard showing Done button successfully. if I press it just behave like return button.
And I can not find a particuler event for fire when tap on Done button.
First of all you have to keep remember that, UITexiView is a scrollable UI widget. So, when you change the keyboard's default Return key in to Done button, you are hiding the opportunity of go to new line inside your UITextView. Therefore my suggestion is, if you are using a UITextView and you need a Done button by keeping the default keyboard, you should add a UIToolBar on top of the keyboard where you can place the Done button.
Since I'm not aware of your real need, which may do not need go to a new line and just need to exit the keyboard when user tap on the Return/Done button, here how you need to do it.
public override void ViewDidLoad()
{
base.ViewDidLoad();
TextView.WeakDelegate = this;
}
[Export("textView:shouldChangeTextInRange:replacementText:")]
public bool ShouldChangeText(UITextView textView, NSRange range, string text)
{
if (text.Equals("\n"))
{
TextView.ResignFirstResponder();
return false;
}
return true;
}
That is quite easy actually subscribe to the ShouldReturn event of the UITextField with a delegate or anonymous method that will call ResignFirstResponder on the field.
You can check this example project that shows how to do it
this.txtDefault.ShouldReturn += (textField) => {
textField.ResignFirstResponder();
return true;
};

Prevent an UIAlertView from closing on PositiveButton click

I am developing mobile application using Xamarin.Forms. I have requirement of getting input in the dialog box. So, i have used UIAlertView for getting text input as like below.
I need to prevent an UIAlertView from closing on button click. I need to retain the UIAlertView dialog box even after the action initiated.
Can anyone please help me on this?
Regards,
Karthikeyan
You could create a custom UIView for this using a Xib file, however if you have no objection to the dialog closing and reopening should it encounter a validation issue then the following would work fine.
EDIT: Adjusted to allow you to pass back the validation message, as the primary message on the UIAlertView.
private string message = string.Empty();
public void recursiveDialog()
{
string input = string.Empty();
if(message == string.Empty()) { message = "Please enter the view name"}
var alert = UIAlertController.Create ("Save View", message, UIAlertControllerStyle.Alert);
alert.AddTextField ((field) => {
field.Placeholder = "view name";});
alert.AddAction (UIAlertAction.Create ("Cancel", UIAlertActionStyle.Cancel, null));
alert.AddAction (UIAlertAction.Create ("Save", UIAlertActionStyle.Default, action => {
input = alert.TextFields[0].Text
}));
if (alert.PopoverPresentationController != null)
alert.PopoverPresentationController.BarButtonItem = myItem;
PresentViewController (alert, animated: true,
action => {
// when a dialog is selected and returns, run validation
if(input == [whatever you want to use to validate it against])
{
// it failed because it already exists for example so change our message
message = "That view name already exists, try again.";
// already exists, so re-run method.
recursiveDialog();
}
else
{
// doesn't alread exist so carry on with whatever you want to do with the name provided.
// clear your message variable
message = string.Empty();
}
});
}

NSSavePanel get cancel button object

I want to show a popover relative to the "cancel" button of my NSSavePanel but this seem not possible. This is a sample code that explain what I need to do:
// the save panel is called when the _window3 get closed..
[panel beginSheetModalForWindow:_window3 completionHandler:^(NSInteger result)
{
if (result == NSFileHandlingPanelOKButton)
{
// ok, saving my file! (also the app get closed)
}
else
{
/* (the app get closed w/o saving anything ATM)
but... you are really sure????
Since you have done a long job with this app you can also push the button by mistake.. (OMG)
Nice should be to add a Popover relative to the cancel button rect, where the user can see and push
on a "go back" and the "Exit w/o saving" buttons
*/
// normally I call a popover this way:
[_goBackOrExitPopover showRelativeToRect:[cancelBtn bounds] ofView:cancelBtn preferredEdge:NSMinYEdge];
// ... but how to intercept the cancel button (cancelBtn)??
}
}];
How can I find the cancel button object?

Xamarin UIAlertView clicked - Opens new View

just wondering basically i have an Azure authentication system that opens when clicking on a facebook button or twitter button it then asks to authenticate the app and once logged in displays a UIalertview with the options to click "OK" or "Cancel".
I was wondering how once they clicked ok i could get it to display the next View?
I know my uialertview is called alert - so was thinking it would alert.Clicked (); then something in there but not sure what.
Here is the method that is processing the login and the alertview if someone can get back to me fast.
private void DoLogin(MobileServiceAuthenticationProvider provider)
{
var task = this.client.LoginAsync(this, provider).ContinueWith(t => {
MobileServiceUser user = t.Result;
this.BeginInvokeOnMainThread(() => {
UIAlertView alert = new UIAlertView("Logged In!", string.Format ("Hello user {0}", user.UserId),
null, "OK", new string[] {"Cancel"});
alert.Clicked();
alert.Show ();
});
});
}
Thanks
For example you could do this:
alert.Clicked += (sender, args) =>
{
// check if the user NOT pressed the cancel button
if (args.ButtonIndex != alert.CancelButtonIndex)
{
// present your next UIViewController, something like this
NavigationController.PushViewController(new YourNextViewController(), true);
}
};
For more information about UIAlertView check out it's documentation:
https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIAlertView_Class/index.html

NSApp Sheets question in cocoa

Here's what I am trying to do. I need to prompt the user for a password prompt and until he enters the password and hits, say the Enter button on the sheet, I want to prevent the code being parsed in the background.
Here's the code to run the sheet and when the user enters the password and hits Enter, endSpeedSheet is run. I am calling all of this from my Main() function.
What I am noticing is that the when the main function runs, the sheet shows up, the user is prompted for a password. But in the background, I already see " Code gets here" has been run. This means the code has already run in the background. What I need is the code to wait at the password prompt and then use this password after the Sheet has been dismissed. Any idea's on what I am missing here ? ( And thanks in advance :))
- (IBAction) showSpeedSheet:(id)sender
{
[NSApp beginSheet:speedSheet
modalForWindow:(NSWindow *)window
modalDelegate:nil
didEndSelector:nil
contextInfo:nil];
}
-(IBAction)endSpeedSheet:(id)sender
{
joinPassword = [joinPasswordLabel stringValue];
[NSApp endSheet:speedSheet];
[speedSheet orderOut:sender];
}
-(IBAction)main:(id)sender
{
[self showSpeedSheet:(id)sender];
// More Code here
NSLog(#" Code gets here");
}
The answer is simple: don't put the code that needs to run after the sheet completes directly after you call -showSpeedSheet:. Sheets are asynchronous, so you must factor your code so that it is only called once the sheet completes.
That's what the didEndSelector parameter in the ‑beginSheet:modalForWindow:modalDelegate:didEndSelector:contextInfo: method is for. You pass in a selector to be called when the sheet is closed. In the modal delegate object, you implement this selector and do whatever processing needs to be done once the sheet completes.
- (IBAction) showSpeedSheet:(id)sender
{
[NSApp beginSheet:speedSheet
modalForWindow:self.window
modalDelegate:self
didEndSelector:#selector(speedSheetDidEnd:returnCode:contextInfo:)
contextInfo:nil];
}
- (IBAction)endSpeedSheet:(id)sender
{
self.joinPassword = [joinPasswordLabel stringValue];
[NSApp endSheet:speedSheet];
[speedSheet orderOut:sender];
}
- (void)speedSheetDidEnd:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo
{
if(sheet == speedSheet)
{
//the sheet has ended, so do something
}
}

Resources