ios button doesn't tap - noob issue - ios

So I'm a new ios developer and am working on my first app. I have a 3d game in unity that I exported as an xcode project and my goal is to add an ios menu before accessing the game. Suffice it to say, I'm struggling with this. I've watch some of the stanford tutorials (great!), and read some tutorials I thought was applicable, but I'm stuck. Here's what I've got:
I hijacked the main.m file to load myAppDelegate (instead of the one Unity made). myAppDelegate then loads an instance of myViewController and adds it as a subview to the window. In the myViewController, I have:
-(IBAction) displayView:(id) sender{
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Button Pressed"
message:#"You have pressed the Button view."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
I'm just trying to issue an alert on a button click. I have the function defined in the .h file with -(IBAction) displayView:(id) sender;
On the view side of things, I added an entry to my plist file I have Main Nib File Base Name set to MainWindow.
Then in the Interface Builder, in MainWindow.xib, I had added from the Library, myAppDelegate and myViewController. For myAppDelegate, I added myViewController as the viewController delegate, window is Window, and the reference outlet is the file owner. For myViewController, the referencing outlet is the myAppDelegate. (To be honest, this part confuses me. It doesn't have much of a corollary to my php web app background.)
In myViewController.xib, the File Owner is myViewController. Received action shows a link from my function (displayView) to a button. Then for the view, I opened that up, painted it red and littered it with general ios widgets (buttons, datepickers, etc). I hooked up one of the buttons to have a touch up inside of displayView.
So that's all that I've done, I load up the app on my device and I see exactly what I laid out on view. But nothing is intractable. I expect taping my button to show the alert defined above. But that doesn't happen. In fact nothing happens. So I suspect the hooking of all of this up is incorrect. But the button doesn't even depress? I would expect the white button to flash blue (down state) when I tap it. Further, I would expect the date picker (not hooked up to function), to spin as I interact with it.
It's as if my touches aren't getting sent to the view. Does anybody have any idea what I might be doing wrong? Thanks in advance for your help!

Try this code:
-(IBAction) displayView:(id) sender{
UIAlertView * myAlert;
myAlert = [[UIAlertView alloc]initWithTitle:#"Button Pressed"
message:#"You have pressed the Button view."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[myAlert show];
/* And make sure to have this action connected to your button in xib
file */
}

Related

iPad ViewController segues not working within UIActionSheet

I have an app originally developed for iPhone, with a MapViewController as the main screen, and a Help screen and Tutorial screen both called from within a UI ActionSheet. Works fine for the iPhone.
When run on an iPad, I can't get to the Help screen and get the following runtime error:
Warning: Attempt to present <HelpViewController: 0x177076c0> on <MapViewController: 0x177d7060> which is already presenting <UIAlertController: 0x17732620>
If I add the following line of code
[self dismissViewControllerAnimated:YES completion:nil];
then I do get to the Help screen, but with the following error:
Warning: Attempt to dismiss from view controller <MapViewController: 0x17d75660> while a presentation or dismiss is in progress!
When I exit the Help screen, the MapView does not come up, however selection a new baseMap brings it back to life.
So, the code runs fine on an iPhone. On the iPad I get an error that says
1) Don't open a new view with the UIAlertController active, or
2) Don't dismiss the view, because a dismiss is already in progress...
Sure seems like a timing problem to me, I've tried both a "sleep" statement and some code to provide a short delay, neither have helped.
Anyone have any ideas?
you have to set action sheet for iPad like below..
UIActionSheet *popup = [[UIActionSheet alloc] initWithTitle:#"Some Title" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:nil,nil];
if(!IS_IPad){
[popup showInView:[UIApplication sharedApplication].keyWindow];
}else{
[popup showFromRect:CGRectMake((CGRectGetWidth(self.view.frame)-200)/2, self.imgLogo.frame.origin.y,200, 200) inView:self.view animated:YES];
}
Surly your action sheet working in both.
This warning comes when you are trying to present/dismiss a view with animation while another animation is still in progress. This might be because while making a selection from UIActionsheet it animates and fades away and at the same time another viewcontroller is appearing with animation. It might help if you dismiss the view controller after delay of 0.2 seconds

View Controllers and code completion

My app takes a picture and then needs to ask the user what they want to name their image.
I've tried using UIAlertView, but I'm having this issue where the string itself isn't collected on time because the code doesn't pause to wait for user input.
What I want to try now is to make a new view controller that just has a text field for the user to input their PDF file's name. What I want to know is how exactly it would conceptually work (or if it would work at all).
Pseudo code:
1. The user clicks on a take picture button, which runs a method that captures the image.
2. After the image is in memory, the View Controller that has the text field is presented.
3. The user inputs the information into the text field
4. The view is dismissed
5. The code in the method that captures the image continues.
Is this how view controllers work? If I present a view controller in from a button, and then dismiss the presented view controller from another button in the new view controller, does the code in the original method continue executing where it left off?
No. The code in the original method executes immediately after presenting the UIAlertView (or UIActionSheet, or any other thing). It doesn't wait for the dismissal.
To handle event of dismissing the UIAlertView, for example there is mechanism called Delegation. It works like this:
You create the UIAlertView in View Controller.
You set UIAlertView's .delegate property to some object. Typically the View Controller itself. That object should implement several methods, that UIAlertViewDelegate defines.
You present the Alert and your code continues immediately.
When user click on some button, the UIAlertView calls one of the defined methods on its Delegate. In our case, the View Controller, which brings us back to our code.
In your delegate method, you “continue” what you wanted to do before Alert was presented.
Example code:
- (void)presentAlert {
// 1
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Hello!"
message:nil
delegate:self // 2
cancelButtonTitle:#"Eh?"
otherButtonTitles:#"Hello!", #"Hi!", #"Aloha!" nil];
[alert show]; // 3
NSLog(#"Did present alert"); // immediately executed
}
// Between these method calls may pass several seconds, minutes or eternity.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
// 4, 5
NSLog(#"Did click button %#", [alertView buttonTitleAtIndex:buttonIndex]);
}
In addition, you will have to declare UIAlertViewDelegate protocol on your View Controller:
#interface YourViewController : UIViewController <UIAlertViewDelegate>
I believe you are misunderstanding Viewcontrollers quite a bit. But i cannot explain all the issues here, or this post would turn into a book. So heres a very helpful link (that i hope you already did read) and a few hints:
https://developer.apple.com/library/ios/featuredarticles/viewcontrollerpgforiphoneos/Introduction/Introduction.html
Viewcontrollers are presented either modally (stacked on top of each other) or in a common ParentViewController (such as a NavigationController or a SlideViewController). The presenting controller will always either keep the controller running in the background or finish the Viewcontrollers logic before presenting a new one. So the shortest possible answr to your question is no.
Pay special attention to the Viewcontroller lifecycle. ViewControllers have special callback methods that get invoked under certain circumstances. Look out for the viewDidLoad and viewDidAppear - methods, this will clear your confusion quite a bit.
Last, not least, look into the delegate pattern. Delegates are a way of sending messages between viewcontrollers. So you could make the ViewController that takes the name send a message with the chosen name to the viewController that took the picture.
Heres a link to the delegate programming guide:
https://developer.apple.com/library/ios/documentation/general/conceptual/CocoaEncyclopedia/DelegatesandDataSources/DelegatesandDataSources.html
i hope that gets you started

How to disable navigation bar back button when some activity is loading in iOS?

I have two ViewControllers.
In second view controller, When I click on search button action (activity started, like web service is executing).After getting data from web service, It will show UIAlertview.
My problem is, When I pressed search button(activity start), now I clicked on back button on Navigation Bar. Now, I am on previous view(First view controller). I have now response of search button activity with UIAlertview.
Obviously, My app will crash on OK button of alert view.
So, In that case
How can I disable navigation bar back button? (when I click on search)
OR
How to prevent UIAlerview to display when I click on back button?
Update :
I tried all methods to hide back bar button. :-)
Only hiding button or disabling user interaction is not the best practice cause the user won't know what's happening with the app, in case of longer process the user will thing that the app is frozen and will terminate it. Good practice in these cases are HUDs, progress indicators that block user interactions. In this case the user will see that something is happening in background and will wait for it to finish, and if he tires to go back the HUD wont let him. I usually use this one:
https://github.com/jdg/MBProgressHUD
, the implementation is very easy and it looks quite nice, but you can always program one of your own.
save reference of your UIAlertView as property
#property (strong, nonatomic) UIAlertView *alert;
show alert
self.alert = [[UIAlertView alloc] initWithTitle:#"title" message:#"message" delegate:self cancelButtonTitle:#"cancel" otherButtonTitles: nil];
[self.alert show];
in case of "risk", remove the delegate
self.alert.delegate = nil;
When risk finished, reset delegate
self.alert.delegate = self;

What is the user interface class of slide up menus?

I'm wondering if there is a specific UI class that slides up to allow user to make a choice, like the "More" button on the safari or the interface confirming iDevice shut down. Both looks like UIToolBars but they seemed to be rendered so well (the button and the toolbar background) that I am starting to suspect it is a separate class designed specifically for such slide-up choices.
Or are they actually different UIViews with designed background that slides up using animateWithDuration:animations: and the background is a translucent mask? How did apple do it?
UIActionSheet. Here is the code:
UIActionSheet *actionSheet = [[UIActionSheet alloc]initWithTitle:#"Share" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"E-Mail",#"SMS", nil];
[actionSheet showInView:self.view];
i think what you are looking for is an action sheet
You mean UIActionSheet?
If so, yea its a separate class under UIView !
UIActionSheet

iPad crash with UIActionSheet displayed from child view controller

I apologize if this has been asked but I can't seem to find it anywhere. I even recreated my issue in a demo project in case any of you want to see it first-hand, although I don't know where I should post it.
I have a xibless UINavigationController based app. Some of my child ViewControllers have a button on the right side at the top that then displays a UIActionSheet. My app is designed for iPhone and iPad, so when I get ready to display the UIActionSheet I do:
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:[NSString stringWithFormat:#"%# Menu", [self title]] delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Email", #"Print", nil];
[actionSheet setActionSheetStyle:UIActionSheetStyleDefault];
if ([actionSheet respondsToSelector:#selector(showFromBarButtonItem:animated:)])
[actionSheet showFromBarButtonItem:[[self navigationItem] rightBarButtonItem] animated:YES];
else [actionSheet showInView:[self view]];
[actionSheet release];
On iPad, I'm trying to show the UIActionSheet attached to the right bar button and on iPhone it should slide in from the bottom. All of this works beautifully.
Unfortunately, if you tap the button and show the menu on iPad, but then tap the back button on the top left side of the app, the menu doesn't dismiss. Instead UINavigationController dutifully pops back and the UIActionSheet is still there. If you try to tap something on the menu you of course get a crash. If the user would have tapped anything else on the screen instead of the Back button, the menu properly dismisses.
If you try this test on iPhone, everything works as expected. There is no issue.
My demo project has an AppDelegate and a ViewController and that's about it. The AppDelegate builds an NSDictionary of NSDictionaries just so I have a model I can recurse through to demonstrate the issue. The ViewController shows all of the keys of the dictionary and if the corresponding value is an NSDictionary, you can tap it to drill down.
This is an interesting problem. Here's what the UIActionSheet Class Reference has to say.
On iPad, this method presents the action sheet in a popover and adds
the toolbar that owns the button to the popover’s list of passthrough
views. Thus, taps in the toolbar result in the action methods of the
corresponding toolbar items being called. If you want the popover to
be dismissed when a different toolbar item is tapped, you must
implement that behavior in your action handler methods.
So when you display the action sheet, it's automatically creating a UIPopoverController and set the containing toolbar (or navigation bar) as the popover's passthrough views, allowing touch events to continue. I think the best bet is to create an instance variable for your action sheet and to force it to dismiss if it is visible in -viewWillDisappear:.
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
if (self.actionSheet.window) // If action sheet is on screen, window is non-nil
[self.actionSheet dismissWithClickedButtonIndex:self.actionSheet.cancelButtonIndex animated:animated];
}
Have you tried force-dismissing the ActionSheet on viewWillDisappear?
Try this:
// In MyViewController.m
- (void)viewWillDisappear:(BOOL)animated {
[actionSheet dismissWithClickedButtonIndex:nil animated:animated];
}
*The crash sounds like a possible EXC_BAD_ACCESS. You might be losing your pointer reference to 'actionSheet' when you change views due to your release. Might be good to hang on to a reference to actionSheet in your .h file and manage the timing of your release.
*Also see the docs for info about the dismiss message: http://developer.apple.com/library/ios/#documentation/uikit/reference/UIActionSheet_Class/Reference/Reference.html

Resources