I ve made 2 views (one front , one back) and putted them inside another view called contain.
I just wanted to make a transition between the two views (front,back) by pressing a button.So i wrote the following code:
(IBAction)flip:(id)sender {
[UIView transitionWithView:_contain
duration:0.5
options:(UIViewAnimationOptionTransitionFlipFromRight)
animations:^{
if (a == NO) {
[_front removeFromSuperview];
[_contain addSubview:_back];
a = YES;
}else if (a == YES){
[_back removeFromSuperview];
[_contain addSubview:_front];
a = NO;
}
}
completion:nil];
}
The problem is that the first transition works flawless,but when we reach to then second transition (back to front) the transition takes place but instead of the front view i 've got the blank page of the contain view.And then the transition don't work when i press the button.Any advice?
Thank you.
Related
On my SplashScreenViewController, I have a series of sequenced animations that hide and display views via cross-dissolves. There is also a button that is present throughout to allow the user to skip out of this. However, the button is not responding to its touch up inside event. If I tap on it rapidly, sometimes I can get it to fire, but rarely.
I assume that this is a result of what I am doing to the other UIViews and that the touch is being absorbed by them.
Each of the other subviews has User Interaction Enabled set to false (unchecked in the IB). The button is presented last in the IB, which should make it the top view. I also add the following code just in case:
_btnAlreadyRegistered.hidden = NO;
[[UIApplication sharedApplication].keyWindow bringSubviewToFront:_btnAlreadyRegistered];
_btnAlreadyRegistered.enabled = YES;
Here is an example of one of the methods that executes the animation. Each of the various fade in / fade out animations follows this same pattern:
- (void) fadeOutHello {
_btnAlreadyRegistered.hidden = NO;
[[UIApplication sharedApplication].keyWindow bringSubviewToFront:_btnAlreadyRegistered];
_btnAlreadyRegistered.enabled = YES;
[UIView transitionWithView:[self view]
duration:CROSS_FADE_DURATION_3
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{_grayView.hidden = YES;}
completion:^(BOOL finished){[self fadeInGetRegistered];}
];
}
Try UIViewAnimationOptionTransitionCrossDissolve | UIViewAnimationOptionAllowUserInteraction
I've got a webpage that is being viewed with a UIWebView. It's got an input form, so I'm shifting the UIWebView up when the keyboard is summoned, and then moving it back down when the keyboard is dismissed, so that the selected input field is centered. Code below:
-(void)keyboardWillShow:(NSNotification*) aNotification {
float offset = [self calculateYOffsetForKeyboard];
[UIView animateWithDuration:0.3f delay:0.05f options:UIViewAnimationOptionBeginFromCurrentState animations:^ {
self.web.frame = CGRectMake(webView_rect_x, offset, self.web.scrollView.frame.size.width, self.web.scrollView.frame.size.height);
} completion:nil];
}
-(void)keyboardWillHide: (NSNotification*) aNotification {
[UIView animateWithDuration:0.3f delay:0.05f options:UIViewAnimationOptionBeginFromCurrentState animations:^ {
self.web.frame = CGRectMake(webView_rect_x, 0, self.web.scrollView.frame.size.width, self.web.scrollView.frame.size.height);
} completion:nil];
}
Here's the weird part: when I do that (tap an input field to summon the keyboard then tap "Done" to dismiss it), everything but the top-left quarter of the UIWebView becomes untouchable. It looks fine, animates up and down perfectly, displays the content properly, but anything right of or below the center point doesn't respond to touches (i.e. several buttons can't be pressed, etc).
Any idea why this might happen? I've commented out lines and determined that it is the "self.web.frame" that is causing the problem: remove that movement and it works fine. I've also NSLog'd the "self.web.scrollView.frame.size.width" and "self.web.scrollView.frame.size.height" values and they seem to be changing as expected and returning to normal. Also the calculateYOffsetForKeyboard method is returning a proper value, (it changes based on which field is selected, but it's generally around -108.5).
So why would moving the frame back and forth alter the view's ability to respond to touches? Any ideas?
I would prefer first download the project from below link and then continue with question (only 36kb)
Download Link
At start what I have is like below.
When I click My Office button, I am calling action actionSeenButton which will print NSLog(#"actionSeenButton");
- (IBAction)actionSeenButton:(id)sender {
NSLog(#"actionSeenButton");
}
This works perfect.
When I click, Show hidden button, I am sliding view by 100 and showing the image and buttons that I have at the top, as shown in below image
Code used is
- (IBAction)showHiddenButton:(id)sender {
CGAffineTransform translation = CGAffineTransformIdentity;
translation = CGAffineTransformMakeTranslation(0, 100);
[UIView beginAnimations:nil context:nil];
self.view.transform = translation;
[UIView commitAnimations];
}
When I click this button, I am calling action actionHiddenButton which will print NSLog(#"actionHiddenButton");
- (IBAction)actionHiddenButton:(id)sender {
NSLog(#"actionHiddenButton");
}
BUT the problem is, when I click the new button that I see, action is not getting called.
Any idea why this is happening?
Note
When I move the top hidden button from y=-70 to y=170, action is getting called.
Sample project can be downloaded from here
What I wanted to implement is, showing three buttons (as menu) on the top in one line by moving view down.
verify that your button is not behind the frame of another view. even if the button is visable, if there is something covering it up it wont work. i don't have access to xcode at the moment but my guess is your view "stack" is prohibiting you from interacting with the button. a button is esentually a uiview and you can do all the same animations to buttons and labels that you can with views. your best bet is to leave the view in the background alone and just move your buttons. since your "hidden" button isn't part of your main "view" hiarchy thats where your problem is.
upon further investigation, your problem is related to auto-layout and making sure your button object stays in the view hierarchy. if you turn off auto-layout you will see where the problem is. when you animate the main view down the "hidden" button is off of the view and there for inactive. the easiest solution is to just animate the buttons. the next best solution closest to what you have is to add another view onto your "main view" and then put the buttons into that view. also why do you have that background image twice? why not just set the background color of your view to that same yellow?
I downloaded your project and it seems the translation you're making for self.view. So the actionHiddenButton is not in the frame.Its better to have the controls you want to animate in the separate view.
If you want to see the problem, after your view get transformed set clipsToBounds to YES. Like
self.view.transform = translation;
self.view.clipsToBounds = YES;
Yipeee!!! Below is how I did.
.h
Added new variable.
#property (retain, nonatomic) NSString *hideStatus;
.m
-(void) viewDidAppear:(BOOL)animated {
NSLog(#"viewDidAppear");
CGAffineTransform translation = CGAffineTransformIdentity;
translation = CGAffineTransformMakeTranslation(0, -100);
self.view.transform = translation;
self.view.clipsToBounds = YES;
[UIView commitAnimations];
self.view.frame = CGRectMake(0,-80,320,560);
hideStatus = #"hidden";
}
- (IBAction)showHiddenButton:(id)sender {
NSLog(#"hideStatus===%#", hideStatus);
CGAffineTransform translation = CGAffineTransformIdentity;
if ([hideStatus isEqualToString:#"hidden"]) {
translation = CGAffineTransformMakeTranslation(0, 0);
hideStatus = #"shown";
} else {
translation = CGAffineTransformMakeTranslation(0, -100);
hideStatus = #"hidden";
}
[UIView beginAnimations:nil context:nil];
self.view.transform = translation;
self.view.clipsToBounds = YES;
[UIView commitAnimations];
}
Attached is the sample project. You can download from here.
I'm running into an issue: I'm successfully transitioning from one view to the next one - from view containing a static image to one containing a video (mov or mp4, etc using avPlayer), vice versa or whatever else type of sequence.
However when I'm transitioning from a view containing a video to a one containing an image I'm still hearing the sound of the video after the image is loaded. Strange. The funniest is that it does not happen when I transitioning from video to video... Any idea guys?
Please check the code I'm using to transition the view (with a dissolve effect):
- (void) replaceView: (UIView *) theCurrentView withView: (UIView *) theReplacementView
{
theReplacementView.alpha = 0.0;
[self.view addSubview: theReplacementView];
[UIView animateWithDuration: 1.5
animations:^{
theCurrentView.alpha = 0.0;
theReplacementView.alpha = 1.0;
}
completion:^(BOOL finished) {
[theCurrentView removeFromSuperview];
}];
self.currentView = theReplacementView;
[self.view addSubview:theReplacementView];
}
Try explicitly stop video playback in viewWillDisappear method.
I am using the following code in my presenting VC to fade in the child modal VC, and this works fine:
self.infoViewController.view.alpha = 0.0;
[self.navigationController presentModalViewController:self.infoViewController animated:NO];
[UIView animateWithDuration:0.5
animations:^{self.infoViewController.view.alpha = 1.0;}];
However I can't get it to fade out, I have tried a few things, this is the latest I tried that doesn't work:
- (IBAction)dismissAction:(id)sender
{
if ([[self parentViewController] respondsToSelector:#selector(dismissModalViewControllerAnimated:)])
{
[[self parentViewController] dismissModalViewControllerAnimated:YES];
self.parentViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
self.parentViewController.view.alpha = 0.0;
[UIView animateWithDuration:0.5
animations:^{self.parentViewController.view.alpha = 1.0;}];
} else
{
[[self presentingViewController] dismissViewControllerAnimated:YES completion:nil];
self.presentedViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
self.presentedViewController.view.alpha = 0.0;
[UIView animateWithDuration:0.5
animations:^{
self.presentedViewController.view.alpha = 1.0;}];
}
}
The modal view controller is faded out but immediately, not over a time period like it is when its displayed.
This (original part) is not to take away from H2CO3's correct answer. UIModalTransitionStyleCrossDissolve does pretty-much exactly the effect you're looking for. You are just not setting the modalTransitionStyle until it's to late. Replace all of your code with these functions in there respective positions:
-(void)show{
self.infoViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:self.infoViewController animated:YES];
}
- (IBAction)dismissAction:(id)sender{
[self dismissModalViewControllerAnimated:YES];
}
Edit in response to timing being an issue: Let's talk about the offending code. We'll concentrate on just the if true part, since it's essentially identical to the else.
[[self parentViewController] dismissModalViewControllerAnimated:YES];
self.parentViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
self.parentViewController.view.alpha = 0.0;
[UIView animateWithDuration:0.5
animations:^{self.parentViewController.view.alpha = 1.0;}];
If you're looking for a reciprocal animation this isn't it. In your original animation you set the next view's alpha to 0, then presented the next view controller, then set it's view's alpha to 1. So logically you need to dismiss the view controller after the animation; This is really easy using blocks. The code would look something like this:
[UIView animateWithDuration:0.5 animations:^{
self.view.alpha = 0;
} completion:^(BOOL b){
[self.presentingViewController dismissModalViewControllerAnimated:NO];
self.view.alpha = 1;
}];
This line of code animates the view's alpha to 0, then (upon completion) dismisses the presented view controller, and sets the view's alpha back to 1. This is a reciprocal animation.
In the docs of UIViewController, we can find:
#property(nonatomic, assign) UIModalTransitionStyle modalTransitionStyle
Set this property to UIModalTransitionStyleCrossDissolve and it will dissolve properly :)
Hope that helps.
I guess, this might be useful for those heroic guys, who still tries to use MPMoviePlayerViewController in full screen mode and with orientation, which differs from the app major one.
I've spent literally a half of working day playing with presenting MPMoviePlayerViewController modally or not modally. But there is no luck with that at all, in sense of transition animation changing. (The modal mode needed for setting orientation which differs from the app major orientation).
I tried presentViewController or presentModalViewController, but the result is the same. No matter what type is the modalTransitionStyle property set, if I do [... dismissViewControllerAnimated:true ...] then default transition style (UIModalTransitionStyleCoverVertical) used anyway. I tested that in iOS 5.1 device and in iOS 6 Simulator.
I haven't tried any other types of controllers... Considering that common controller has method dismissMoviePlayerViewControllerAnimated, I can assume, that this method is used anyway for dismissing a video controller, no matter how did it appear. (Entering transitions didn't work for me as well, except they did not process as CoverVertical (in case of modalTransitionStyle changing).
So, my solution was not use the transition animation at all.
I am sure, Apple had some reasons for allowing only some definite animation for MovieViewController (I really hope so, and that was made not because of "laziness"), but if they wanted some nice experience user would get, they failed, as in my app that's even better when the video appears without any animation (which is worse than CrossDisolving for sure) but that's better than banal CoverVertical.
Looking on that from developer's point of view, it really sounds like they spend much more money for designers to paint nice icons for customers instead of more pleasant and effective work of developers. (