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.
Related
I'm writing a little card game where 4 cards are dealt to the screen and the user can tap each card to reveal (and again to hide) it.
Each card-front and card-back are stored in image views. A UIButton catches the user tap and should flip the card over.
I've added front and back of the card as subviews to a container view and I use the method UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight for the animation.
Please see the code below, I've removed the handling of the 4 different cards in the methods below for the sake of simplification & readability. Also I've replaced some array/filename-juggling for the cards with static image-names for front and back here.
The strange thing with this code now is the sometimes it works as expected 10 times in a row (i.e. the flipping animation is shown) but sometimes no animation is shown at all (i.e. the other card side is shown but without the flipping.). Then it's the other way round: Sometimes the card is shown without any animation for 7 or 8 times then suddenly the flipping-animation is shown.
It's driving me nuts as I can't see the reason for this strange behaviour.
Do you have any idea? I'm building for iOS 8 to iOS 10.
From the .h file:
#interface GameViewController : UIViewController
{
UIImageView *cardback1;
UIImageView *cardfront1;
UIView *containerView;
BOOL c1Flipped;
// much more...
}
And from the .m file:
-(void)flipCardButtonClicked:(id)sender
{
containerView = [[UIView alloc] initWithFrame: CGRectMake(25,420,220,300)];
[self.view addSubview:containerView];
c1Flipped = !c1Flipped;
cardback1 = [[UIImageView alloc] initWithFrame: CGRectMake(0,0,220,300)];
cardfront1 = [[UIImageView alloc] initWithFrame: CGRectMake(0,0,220,300)];
if (c1Flipped)
{
cardback1.image = [UIImage imageNamed:#"backside.png"];
cardfront1.image = [UIImage imageNamed:#"frontside.png"];
}
else
{
cardback1.image = [UIImage imageNamed:#"frontside.png"];
cardfront1.image = [UIImage imageNamed:#"backside.png"];
}
[containerView addSubview:cardfront1];
[containerView addSubview:cardback1];
[cardfront1 release];
[cardback1 release];
[self performSelector:#selector(flipSingleCard) withObject:nil afterDelay:0.0];
}
-(void)flipSingleCard
{
[containerView.layer removeAllAnimations];
[UIView beginAnimations:#"cardFlipping" context:self];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(flipDidStop:finished:context:)];
[UIView setAnimationDuration:0.5];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:containerView cache:YES];
[containerView exchangeSubviewAtIndex:0 withSubviewAtIndex:1];
[UIView commitAnimations];
}
-(void)flipDidStop:(NSString*)animationID finished:(BOOL)finished context:(void *)context
{
[containerView removeFromSuperview];
[containerView release];
}
My guess is that [self performSelector:#selector(flipSingleCard) withObject:nil afterDelay:0.0]; is the culprit. Seems like this could be a timing issue. Have you tried adding an actual delay to this? Say...0.1? I believe that doing this could fix this, OR just simply calling the method directly instead of using performSelector.
Looks like it indeed was a timing issue as suspected by BHendricks.
Adding a 0.1 delay solved the problem.
Thanks a lot.
There is a strang flicker when I use AVPlay:
I create a demo to show this bug: Demo 。
I am referring to the flicker from the beginning, that one happens because I have a transition between the image and the movie. but I need
the image showing before the video appear.
because I have to keep image showing,before the video is downloaded completely.
Can anyone fix this bug?
You can make this transition smoother by using an animation when hiding the image view:
if (!self.imageView.hidden) {
NSTimeInterval fadeDuration = .5;
static CGFloat invisibleAlpha = .0;
[UIView animateWithDuration:fadeDuration animations:^{
self.imageView.alpha = invisibleAlpha;
} completion:^(BOOL finished) {
[self.player play];
}];
}
Note that you can set the .5 value to another value.
I'm trying to maintain existing code and added a new UITextView to a View Controller. All of the views enter the screen by sliding in from the left side. My newly added view also slides in from the left side along with the other views (without me doing anything because the animation is set on their container). The problem is that my view also appears for a second or so before the animation starts. How can I prevent this from happening?
Here is the code for the animation on the container
- (void) showAndAnimateContainerView{
[self.containerView setHidden:NO];
[self hideContainerView:self.containerView];
self.marginLeft.constant = 0;
[UIView animateWithDuration:STD_ANIMATION_TIME delay:ZERO_ANIMATION_TIME options:UIViewAnimationOptionCurveLinear animations:^{
[self.containerView layoutIfNeeded];
} completion:^(BOOL finished) {
}];
}
- (void) hideContainerView:(UIView *) view{
self.widthView.constant = WIDTH_SCREEN;
self.marginLeft.constant = -WIDTH_SCREEN;
[view layoutIfNeeded];
}
Don't know what else I can add to the question to make it more clear.
I have to give a delete thumbnail animation in my ipad application just like iphone/ipad applications delete effect.
Any body help me please sample photo is attached
If you need more details then kindly mention it in comments
I have done this using CGAffineTransformMakeRotation. Don't know there is some other better method. But What I have done is my logic you can copy that as it is and you just need to add a delete button on the left top of that view. In the following code I am just animating the thumbnail or any view just like iPad does on its home screen. One thing, You need to declare int direction globally. and every time when you will call this method you will set direction = 1;
-(void)shakeToDelete:(UIView *)shakeMe
{
[UIView animateWithDuration:0.1 animations:^
{
shakeMe.transform = CGAffineTransformMakeRotation(0.05 * direction);
}
completion:^(BOOL finished)
{
direction = direction * -1;
[self shakeToDelete:shakeMe];
}];
}
/// edit
I tried this way and got it working in my sample screen as attached in photo
You better should use an autoreverse and looped animation, cause creating animations over and over will fulfill the phone memory.
With this code, only one animation is retained.
view.transform = CGAffineTransformMakeRotation(-kDeleteAnimationAmplitude);
[UIView animateWithDuration:0.1 delay:0 options:UIViewAnimationOptionRepeat|UIViewAnimationOptionAutoreverse animations:^{
view.transform = CGAffineTransformMakeRotation(kDeleteAnimationAmplitude);
} completion:nil];
Then if you want to stop your animation, just call:
[view.layer removeAllAnimations];
I created an app for iPad which lets you navigare through some presentations... there are two views: The list of presentations and the view which shows you the presentation.
When a user selects a presentation (in PresentationListController), I show the presentation in the other view (PresentationViewController).
The PresentationViewController contains a UIScrollView with a list of pages... the problem is that after some time, without a recurring event which causes this problem, the UIScrollView 'loses' its capacity to bounce... so the scrolling is not smooth and it's like scrolling a rigid view without that fancy bounce effect... The user is still able to scroll but the effect is very ugly. The problem is that, the problem remains even if I go back the the PresentationListController and select a new PresentationViewController... the new presentation which is shown, have this problem.
I thought it was due to the fact that the navigationcontroller kept the UIView in memory and reused it whenever I opened a new presentation, but this is not the case because I debugged and saw that when I change the presentation, the dealloc method is called on the PresentationViewController.
So, how can I manage this problem?
EDIT
I found how to reproduce it: I am doing an animiation to open the list of pages, and an animation to close it. When I open a presentation which contains lots of pages (so that the contentSize of the UIScrollView > the width of the UIScrollView), I get no problem. But When I open and close the pages list in a presentation which only has one page, the problem begins. I wrote the code I am using to perform the animation+
here is the code I am using to perform the animation which opens and closes the pages list:
- (IBAction)showPagesView:(id)sender {
if (pagesListVisible) {
[self resetNavigationControls];
} else {
[self resetNavigationControls];
scvPages.frame = CGRectMake(0, 960, 768, 0);
scvPages.alpha = 0.0f;
[btnPages setImage:[UIImage imageNamed:#"thumbON.png"] forState:UIControlStateNormal];
[UIView animateWithDuration:0.7 animations:^{
scvPages.frame = CGRectMake(0, 760, 768, 200);
scvPages.alpha = 1.0f;
pagesListVisible = YES;
} completion:^(BOOL finished) {
if (finished) {
scvPages.contentSize = scvPages_ContentSize;
}
}];
}
}
Here is the method I use to hide the pages list (and other views)
- (void)resetNavigationControls {
if (pagesListVisible) {
[btnPages setImage:[UIImage imageNamed:#"thumb.png"] forState:UIControlStateNormal];
hidePages = YES;
// Nascondi la lista delle pagine.
[UIView animateWithDuration:0.7
animations:^
{
scvPages.frame = CGRectMake(0, 960, 768, 0);
scvPages.alpha = 0.0f;
}
completion:^(BOOL finished)
{
if (finished) {
scvPages.contentSize = scvPages_ContentSize;
pagesListVisible = NO;
}
}
];
}
}
Hope it helps. Thank you.
If I had to bet, it would be on your scrollview being zoomed and not resetting the affine transform back to the identity. I'm no expert on such things, but that's where I would look.
If your scrollview isn't zooming at all, then I'd recommend logging the values of scrollview.bounces, .bouncesZoom, .alwaysBounceVertical and .alwaysBounceHorizontal on a timer from the beginning of your app and see if anything changes the values while triggering your bug. You want all to be YES all the time, of course.
Good luck,
Damien