Buttons not highlighting on touch - objective-c

Im new to IOS development. I have a view with two buttons "create" and "cancel" but they are no highlighting. They appear on top of a pdf that allow longpress for copy/cup/paste). Actually "create" highlights really fast, but cancel does not change state at all. Any idea what might be causing this.
-(IBAction)create:(id)sender{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Name your object" message:#"" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Save",nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
[alert show];
}
-(IBAction)cancel:(id)sender{
[self.view removeFromSuperview];
[[NSNotificationCenter defaultCenter] postNotificationName:kExitAnnotationView object:nil ];
}

I you "create" action is mapped on the TouchDown you wont be able to see the Highlighted state of you button

In your cancel method you are removing the superview...Actually your cancel button is highlighting but You are not able to see that..If you want to see that you can perform the actions inside your cancel method a bit later using timer with a 1 second or less delay.
Same thing you can do in create method. Hope it will work...:)

Related

Stop NSPopover from closing if NSAlert dialog appears?

Hi I have a NSStatusItem that shows a popover when clicked. One option in the popover is to delete something; at this point I ask the user if they are sure.
The problem is that the Popover automatically closes as soon as the Alert appears.
I have tried all the different behavior settings like NSPopoverBehaviorSemitransient, NSPopoverBehaviorTransient and NSPopoverBehaviorApplicationDefined to no avail.
I also try catching it in - (BOOL)popoverShouldClose:(NSPopover *)popover but this isn't called when NSAlert appears.
Nothing seems to stop an NSAlert from closing a popover.
NSAlert *alert = [[NSAlert alloc] init];
[alert addButtonWithTitle:#"OK"];
[alert addButtonWithTitle:#"Cancel"];
[alert setMessageText:msg];
[alert setInformativeText:#"Warning, delete this folder?"];
[alert setAlertStyle:NSCriticalAlertStyle];
// Show the alert
if ([alert runModal] == NSAlertFirstButtonReturn) {
I also tried showing the alert as a sheet in the popover which kind of works but then the popover stays around no matter if I click outside it.

How to gather input from an alert when a window is closed to determine whether to save in an objective-c mac application?

I made it so that in an objective-c mac application developed in Xcode, an alert would appear asking the user whether they wish to save when they try and close the main window. How would I gather the user's input from this alert?
I know you can use this code to generate an alert with various options and text:
NSAlert *alert = [[NSAlert alloc] init];
[alert addButtonWithTitle:#"Save and Quit"];
[alert addButtonWithTitle:#"Quit"];
[alert setMessageText:#"Would you like to save before you quit?"];
[alert setInformativeText:#"You are about to quit. Would you like to save your progress?"];
[alert setAlertStyle:NSWarningAlertStyle];
[alert beginSheetModalForWindow:[self window] modalDelegate:self didEndSelector:#selector(null) contextInfo:nil];
And I know that you can use the
- (void)windowWillClose:(NSNotification *)notification
method to run when the main window is closed, but how would I gather the user's input from this alert?
NSAlert panels aren't really meant for gathering info but for alerting the user of some sort of state and then recording which button they pressed in response.
What I've had to do in the past is to create my own window/xib with it's window controller, textviews, and selectors and manage it all from there.
On the other hand if you were just talking about getting the state of which button was pressed, as shown from the link, something like this would work:
if ([alert runModal] == NSAlertFirstButtonReturn) {
// OK clicked, delete the record
[self deleteRecord:currentRec];
}

Why UIAlertView prevents my modal view controller from being displayed?

Let's say that when the user presses a button a message needs to be shown and then a modal view controller is displayed.
I would write something like that :
- (void)pickImageButtonPressed:(id)button {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Alert"
message:#"Some alert"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[[UIApplication sharedApplication].keyWindow.rootViewController
presentModalViewController:picker animated:YES];
[picker release];
}
With this code, the modal view controller is simply not displayed !
However, if I switch the two blocks of code (show modal first, then show the alert), the view controller is displayed modally and the alert shows up above it, exactly as I want.
My question is: why the alert prevents the modal view controller from being displayed ?
Please note that I do not want to wait for alert to be dismissed before calling presentModalViewController.
Update :
I figured out that my production code was a bit more complicated than what I first put. I updated the example code and then finally found a simple example to reproduce the problem.
Note that in my production code, the popup is displayed from a place where I don't have any reference to a view controller, that's why I use [UIApplication sharedApplication].keyWindow.rootViewController instead of a direct reference to a view controller
I finally found the answer. The issue really was on this line:
[[UIApplication sharedApplication].keyWindow.rootViewController
presentModalViewController:picker animated:YES];
When an alert is displayed, [UIApplication sharedApplication].keyWindow.rootViewController is nil !. That's why the picker was never displayed. And that's why it worked when I switched the two blocks.
Now I need to find a way to get the most relevant view controller to present the picker modally...

How can I show UIActionSheet to confirm moving back in Navigation View

Using Xcode I have View A that navigates to View B.
Upon pressing the Back UIBarButtonItem, I'm trying present the user with a UIActionSheet to confirm navigation to move back to View A.
What do I need to do in code to stop the view from navigating back and then (depending on user input) move back or stay on the current screen?
add a backbutton programmatically.
eg.
UIButton *backBtn= [[UIButton alloc] initWithFrame:CGRectMake(0,0,54,30)];
[backBtn addTarget:self action:#selector(backButtonPressed:)forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *backBarButton = [[UIBarButtonItem alloc] initWithCustomView:backBtn];
[backBtn release];
[[self navigationItem] setLeftBarButtonItem:backBarButton];
[backBarButton release];
//backButtonPressed is the selector for backBtn
Then present you ActionSheet from that selector and based on user either navigate to previous viewController or dont.
To navigate to previous page, use popViewMethod.
`
You should not present UIActionSheet for every other action.It would be better to use UIAlertView for this purpose. According to Apple UIActionsheet Guidelines :-
Provide alternate ways a task can be completed. An action sheet allows you to provide a range of choices that make sense in the context of the current task, without giving these choices a permanent place in the user interface.
Get confirmation before completing a potentially dangerous task. An action sheet prompts users to think about the potentially dangerous effects of the step they’re about to take and gives them some alternatives. This type of communication is particularly important on iOS-based devices because sometimes users tap controls without meaning to.
for UIAlertView :-
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Alert View"
message:#"Do You want to go back to previous screen?"
delegate:self
cancelButtonTitle:#"NO"
otherButtonTitles:#"YES",nil];
[alertView show];
[alertView release];
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0) {
NSLog(#"THE 'NO' BUTTON WAS PRESSED");
}
if (buttonIndex == 1) {
NSLog(#"THE 'YES' BUTTON WAS PRESSED");
}
}
Implement this on action of back button of UINavigationController.According to the buttons pressed "YES" or "NO" , you can allow navigation.Also conform to UIAlerrtVIewDelegate protocol.

iPad UIActionSheet - Not displaying the last added button

I'm trying to display a UIActionSheet from my iPad. Here's the code that I'm using:
-(void) presentMenu {
UIActionSheet *popupMenu = [[UIActionSheet alloc] initWithTitle:#"Menu" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:nil];
for (NSString *option in _menuItems) {
[popupMenu addButtonWithTitle:option];
}
popupMenu.actionSheetStyle = UIActionSheetStyleBlackOpaque;
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
[popupMenu showFromTabBar:_appDelegate.tabBar.tabBar];
}
else if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
[popupMenu showFromBarButtonItem:self.navigationItem.rightBarButtonItem animated:YES];
}
[popupMenu release];
return;
}
The iPhone version of the program displays all the buttons in _menuItems, but the iPad version just ignores the last item from that array. Does anyone know why this might be happening?
Thanks,
Teja.
Found the answer as soon as I typed out this post. Somehow removing the "Cancel" button causes both the buttons to come up. Weird.
EDIT: Although, this is really annoying because all my button indices change between the iPhone and the iPad versions (The iPhone still needs the cancel button). How do I handle this?
I think what iOS is doing is it's expecting the last button to be the cancel button (regardless of whether it is or not) and is removing it, but maybe only for iPads. This is probably because a user can tap outside the action sheet to dismiss it. The problem I have with Apple's design choice is that it may not always be evident that the dialog can or should be dismissed in that way.
For example, I am showing my action sheet by calling [actionSheet showInView:self.view]; This causes the entire view to be grayed with the action sheet displaying in the middle of the device. Users are going to--rightly, in my opinion--assume that they have to choose one of the buttons.
I understand there are other action sheet display mechanisms--like the one that displays it as a bubble attached to a bar button item--where a cancel button is obviously redundant. It would be nice if Apple allowed for more flexibility here. For my app, I am probably going to have to add a dummy button to the end of the array I'm passing into my custom constructor, knowing that iOS will hide it. If the behavior changes in a future release of iOS... well, I'll just have to address it at that time.
In your case, I recommend not using the constructor that takes cancelButtonTitle and destructiveButtonTitle. Instead, subclass UIActionSheet and add buttons manually using the method above. Then, set cancelButtonIndex and destructiveButtonIndex to the desired indices. Remember that you don't have to set those two properties; they default to -1 (no button). Also, remember to abide by the HIG regarding the position of your buttons.
Here's one of my subclass' constructors (edited for brevity), just to give you an idea:
- (instancetype)initWithTitle:(NSString *)title
buttonTitles:(NSArray *)buttonTitles
cancelButtonIndex:(NSInteger)cancelButtonIndex
destructiveButtonIndex:(NSInteger)destructiveButtonIndex
{
self = [super initWithTitle:title delegate:nil cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
if (self)
{
if (buttonTitles)
{
[buttonTitles enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
{
[self addButtonWithTitle:obj];
}];
}
self.cancelButtonIndex = cancelButtonIndex;
self.destructiveButtonIndex = destructiveButtonIndex;
if (self.cancelButtonIndex > -1)
{
[self addButtonWithTitle:#""];
}
}
return self;
}