i need to reset the first view with a button press - iphone

on an app that i am creating, you need to slide a square through a maze and if it touches the wall, it goes to another screen telling you that you lose. However, when you hit the reset button, it goes back, and the square is in the exact same spot as where it touched the walls. Is there any way that i can press the button and have the square go back to start at the same time? Any feed back is appreciated! Thanks. (By the way, i am using Xcode.)
Here is the code for the button in the .h file:
- (IBAction)retry:(id)sender;
and here is the code for the .m:
- (IBAction)retry:(id)sender {
[self dismissModalViewControllerAnimated:YES];
}

Use viewWillAppear to reset your views
-(void) viewWillAppear: (BOOL) animated {
}

Call your initial method on buttonPressEvent.
- (IBAction)retry:(id)sender {
[self viewDidLoad];
}

Related

iphone - the order of the touch (tap) event

I have a UIView and a UIWebView.
The UIWebView is a child view of the UIView.
The UIWebView contains a youtube video and is set as to let the video fit to the UIWebView.
I have a UITapGesture associated with the parent UIView for single tap, say, if a user single tap the whole view, it will invoke A.
So, when the UIWebView loads the youtube video, there is a button on top of the video waiting for users to click to play. But now if I click the button, the youtube is played, but also the A is invoked too. This is what I don't want.
How should I solve it?
I thought the touch/tap event should be in a order and if the button is clicked, it should absorb the event and not give the UIView any more.
I also tried to add another UIView under the UIWebView, and attach that gesture to the underlying view. However, it still doesn't work.
How can I do to let the button over the youtube video independent?
thanks
Try add this code in your view's .m file (if you are using UIView, subclass it):
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
CGPoint p = [self convertPoint:point toView:webView];
if ([webView pointInside:p withEvent:event]) {
return [webView hitTest:p withEvent:event];
}
return [super hitTest:point withEvent:event];
}
Since I did not try this code, tell me if it doesn't work. There are still many ways to deal with the situation. :)

iPhone app entering back into foreground shifts the view back to its origins and keyboard is still visible

I'm currently working on an iPhone 4 app with a registration view. The users can focus into a UITextField and I have code that will shift the view upwards to prevent the keyboard from covering up the textfield. But if the app is backgrounded and brought back into the foreground again, the keyboard is still up, the textfield is still in focus, but the view is now shifted back down in its original state. This covers up the textfield.
What's going on? How do I either make the view stay put or hide the keyboard when the app is brought back into the foreground?
UPDATE:
-Any changes for this on the new iOS5?
you could try doing something in applicationDidEnterBackground in your app delegate like
NSLog(#"%#", [self.viewController.YOURTEXTFIELD isFirstResponder]);
if ([self.viewController.YOURTEXTFIELD isFirstResponder]) {
[self.viewController.YOURTEXTFIELD resignFirstResponder];
}
the "isFirstResponder" checks to see if the keyboard is currently being used in this view and returns YES if it is and NO if it isn't.
The NSLog is there just so you know what is getting passed into the if statement.
I've next solution:
In AppDelegate
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// 1. get access to ViewController which is on top
// In my case, I have navigation controller in root
UIViewController* current_controller = [self.rootNavController.viewControllers lastObject];
// 2. loop all uitextfield.
for (UITextField* o_txt in [current_controller.view subviews]) {
[o_txt resignFirstResponder];
}
}
Look's like "hot fix" )

Is it possible to differentiate between a long press and a tap on a button?

Can we call different actions / delegates in response to the two different events of
A tap on a UIButton
A tap-and-hold on a UIButton
?
Yes, it's reasonably easy to implement this using a UILongPressGestureRecognizer (on iPhone OS 3.2+). A long press will be handled by the gesture recognizer, and a short tap will pass through to the button's normal action.
For example, I subclassed UIButton and added the following method for specifying a long touch action to go along with a tap (longPressGestureRecognizer is an instance variable):
- (void)setLongTouchAction:(SEL)newValue
{
if (newValue == NULL)
{
[self removeGestureRecognizer:longPressGestureRecognizer];
[longPressGestureRecognizer release];
longPressGestureRecognizer = nil;
}
else
{
[longPressGestureRecognizer release];
longPressGestureRecognizer = nil;
longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:[[self allTargets] anyObject] action:newValue];
[self addGestureRecognizer:longPressGestureRecognizer];
}
}
I then could do the following to set both short tap and long press actions that will be handled by the same target:
[undoButton addTarget:self action:#selector(performUndo:) forControlEvents:UIControlEventTouchUpInside];
[undoButton setLongTouchAction:#selector(showUndoOptions:)];
As you can see, this is useful for the undo buttons you see in title bars of many iPad applications.
Brad Larson's answer looks pretty good but here's another one that might give you a bit more flexibility/control of what you want or might want to do.
You subclass UIButton, you override the touchesBegan and touchesEnded methods so that when the user starts a touch you call
[self performSelector:#selector(detecetedLongTap) withObject:nil afterDelay:1.0];
and in the touchesEnded you call:
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:#selector(detecetedLongTap) object:nil];
to cancel the event if the finger was lifted too soon.
You can get full code for this in this blog post:
http://www.isignmeout.com/adding-long-tap-functionality-uibutton/
The best solution I can think of, is to create another class, and subclass UIButton. Then on Interface Builder (if that's what you're using), you can set the button's class to the custom class you just created.
So in this new class, you have to override a method called
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
This is basically telling you that someone pressed down on your button. The touches is an NSSet and it holds all the information for all the fingers that are pressing down on the screen. If you only are interested in the one that's pressing on the button itself, you'll probably have something like:
NSSet *myTouches = [event touchesForView:self.view];
So now that you have the touches that correspond to your button, you have to find out how many times the user tapped on that button. You do that with something like:
NSUInteger numTaps = [[myTouches anyObject] tapCount];
If this number is 2, that means the user just double tapped your button. Now comes the next part. How do you know if the user is holding that button? Well when the user lets go of the screen, another method gets called. You'll need to override that one as well:
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
This is where you know if the person has stopped touching the screen or if his finger is still on it. If his finger is still on it, then this event hasn't been called yet.
Now enough with the background
Here's my suggestion to you. I suggest you override the touchesBegan: method and check if the number of taps in the button is 2. If so, then start a timer that does what you need it to do, for as long as you need it to be done, and then on the touchesEnded: method, you'll go ahead and stop that timer, and this way you will have done whatever it is that you needed to do, for as long as you needed to do it OR as long as the user has held on to the button.
I hope this helps, obviously I didn't write the whole code for you, you'll have to experiment and research that stuff, but if you have any questions, I'll be happy to lend a helping hand :)

motionEnded works fine until I click a link in a webView

I'm using this code to do shake detection, and for the most part it works fine:
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
if (event.type == UIEventSubtypeMotionShake) {
if ( event.subtype == UIEventSubtypeMotionShake )
{
NSLog (#"Shake Called");
}
}
I believe for this to work, I also needed to use these, which I have:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self becomeFirstResponder];
}
- (void)viewDidDisappear:(BOOL)animated {
[self resignFirstResponder];
[super viewDidDisappear:animated];
}
This all works great, and motionEnded is called every time I shake, until I click through a link in a webView on my program. I can scroll up and down in the view and shake still works, but as soon as the view loads a new page, motionEnded stops being called when I shake. This occurs both in the simulator and on a real device (iPhone 3G, iOS4). From my limited understanding, I believe it has something to do with first responders, but I could be wrong there!
I have managed to answer my own question. For the reference of others who may have similar problems, the issue is that the viewController stops being the first responder once you click a link in a webView (or edit a text box, or some similar action). To fix the issue in my case, the answer was to make the viewController the first responder again after the new page loads:
- (void)webViewDidFinishLoad:(UIWebView *)nameOfWebView {
[self becomeFirstResponder];
}
I have the same problem, but becoming first reponder when web view finishes loading doesn't solve it for me. I know webViewDidFinishLoad gets called when a new page has been loaded, and I also know motionEnded gets called when I focus the web view by tapping it and then shaking or simulating shake.

Hide Shutter in UIImagePickerController

I have designed an iris shutter animation for a camera view in an iPhone app.
Unfortunately, it seems impossible to hide Apple's shutter when the view appears, even if I hide the camera controls and create a custom cameraOverlayView.
I have gotten around this by animating my shutter on top of the normal shutter when the view appears, using the viewWillAppear and viewDidAppear methods of UIImagePickerController. However, I can't get the shutter to be hidden under my shutter the first time through. When the app launches, it shows a camera view, and the original shutter is visible. On all subsequent views of the cameraController, my workaround works. Any suggestions?
Here's my code. This is from my app delegate:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
cameraController = [[CameraController alloc] initWithMode:#"camera"];
[window addSubview:cameraController.view];
}
And this is from my UIImagePickerController subclass:
- (void) viewWillAppear:(BOOL)animated {
if (self.sourceType != UIImagePickerControllerSourceTypePhotoLibrary || simulatorView) {
[self addShutter];
[shutter close];
}
[super viewWillAppear:animated];
}
- (void) viewDidAppear:(BOOL)animated {
if (self.sourceType != UIImagePickerControllerSourceTypePhotoLibrary || simulatorView) {
[shutter openShutter:.5f];
}
[super viewDidAppear:animated];
}
Note that the docs say that subclassing UIImagePickerController isn't supported, so it may work in some cases but isn't "safe". Not sure if it would get rejected by the app store. (Probably depends on how picky their static code verification tool is.)
I don't really have a good answer, but you might try either 1) iterating over the subviews of the picker's main view to see if you can identify whatever is being used to animate the shutter, then mangle it so that it won't display, or 2) for the initial animation, just show the initial image picker main view under another opaque black view. Not sure if the user-specified overlay view would work for that or not, but you might be able to do those without subclassing.
Searching for undocumented subviews is another thing that's theoretically unsafe though since who knows how the implementation might change in the future.
Possibly too late, but my proposal is to use the following notifications (found while debugging)
PLCameraControllerAvailable - camera controller object is initiated, but shutter is not visible yet
PLCameraViewIrisAnimationDidEndNotification - iris animation is completed.
And the usage is straightforward: call UIGetScreenImage() on 1st notification, render grabbed image on screen (fullscreen) just above the UIImagePicker. Destroy rendered image on the 2nd notification.
I try the same thing with no results, so I do this workaround:
1- Suppose you have a method called showAllButtons with no parameters that will show all your custom things (buttons, tool bars,...)
2- Initialize all the custom controls hidden
3- Write a method that will call the last function but within an interval:
-(void)showAllButtonsDelayed:(NSTimeInterval)a_iMsToDelay
{
NSTimer* tmpShowButtonsTimer = [NSTimer timerWithTimeInterval:a_iMsToDelay target:self selector:#selector(showAllButtons) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:tmpShowButtonsTimer forMode:NSDefaultRunLoopMode];
}
4- Call that method in the willDidAppear method of the UIImagePickerController subclass. Play with some values of a_iMsToDelay.
Hope this helps.