User interaction on Button while animating in iOS - objective-c

I am creating buttons programatically, and they are animated (fade & movement), I need the buttons to still have user interaction though. I have tried things like
options:(UIViewAnimationOptionAllowUserInteraction
which seems to do nothing :/ I have read several posts on here with different advice, including someone saying it isn't actually possible. Does anyone know if I can enable user interaction while a button is animating, and if it's not possible how do people get around this issue?
Thank you.
This is the current animation code that I was using:
[UIView animateWithDuration:106
delay:0
options:(UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionAllowAnimatedContent | UIViewAnimationOptionCurveEaseInOut)
animations:^{
[_planetButton setCenter:point];
_planetButton.alpha = 0.2;
_planetButton.userInteractionEnabled = YES;
}
completion:^(BOOL finished){
NSLog(#"animation completed");
//[_planetButton removeFromSuperview];
}
];
I also tried animation such as:
CABasicAnimation *move = [CABasicAnimation animationWithKeyPath:#"transform2"];
move.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
move.duration = 5.105;
move.repeatCount = 1;
move.autoreverses = YES;
move.removedOnCompletion = YES;
move.toValue = [NSValue valueWithCGPoint:point];
[_planetButton.layer addAnimation:move forKey:nil];

Related

Xcode Animations complete instantly - CAAnimations call didStop - flag = FALSE

I'm getting some weird bugs. I thought I had a handle on this. I copied code from one of my other projects. I'm wondering if it could be something to do with my custom class.
I have a view controller initialize my custom class called "TitleCardView"
Inside there I have a bunch of animations like this one:
CGPoint startPointb = borderMaskLayer.position;
CGPoint endPointb = CGPointMake(borderMaskLayer.position.x, borderMaskLayer.position.y-1000);
CABasicAnimation* bmoveAnim = [CABasicAnimation animationWithKeyPath:#"position"];
bmoveAnim.delegate=self;
[bmoveAnim setValue:#"borderMaskAnim1" forKey:#"id"];
bmoveAnim.fromValue = [NSValue valueWithCGPoint:startPointb];
bmoveAnim.toValue = [NSValue valueWithCGPoint:endPointb];
bmoveAnim.duration = 1;
[bmoveAnim setBeginTime:CACurrentMediaTime()+.4];
bmoveAnim.fillMode = kCAFillModeForwards;
bmoveAnim.removedOnCompletion = NO;
bmoveAnim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
[self.borderLayer.mask addAnimation:bmoveAnim forKey:#"position"];
[self.borderWhiteLayer.mask addAnimation:bmoveAnim forKey:#"position"];
The animation works fine but when I try to implement AnimationDidStop{, as soon as the view loads, all the animations get logged by the delegate method with the FALSE (did not finish) flag.
I added a button and tried to use:
[UIView animateWithDuration:6 animations:^{
continueButton.alpha = 1.0f;
}];
and this code with the delay parameter....
Same problem. As soon as the view loads, its like the animation gets run immediately with a duration of 0.
Are you not supposed to add animations in your init method? I feel like there must be a rule I'm breaking that I don't know about.
This code does work:
this button is the last thing in the init method
continueButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[continueButton addTarget:self
action:#selector(titleNext)
forControlEvents:UIControlEventTouchUpInside];
[continueButton setTitle:#"Click to Continue" forState:UIControlStateNormal];
continueButton.frame = CGRectMake(0.0, 390.0, 320.0, 75.0);
[self addSubview:continueButton];
continueButton.alpha = 1.0;
then this is the method it calls
-(void)titleNext{
// proceeds to the motto page from the title page
[UIView animateWithDuration:.6 animations:^{
continueButton.alpha = 0.0f;
}];
}
So can anyone tell me why my animations are acting weird???
I recreated the project and found the animationDidStop delegate worked when the animations were created in -(void)viewDidAppear{ instead of -(void)viewDidLoad{
For swift it works if the animations are in
override func viewDidAppear(_ animated: Bool)

Animating with Auto Layout and iOS7 jumps to end of animation (fine in iOS6)

I am using Autolayout and animating by changing the constraints, however, in iOS7 the view simply jumps to the end position - in iOS6 I get a nice animation.
Is should be noted these views are UICollectionViews and I have checked the Storyboard and there are no Layout errors.
All I can think is there is something and am or am not setting on the Storyboard or something that I am doing wrong with the Constant settings in the Storyboard.
primaryMenuYContraints.constant = BUTTOMX;;
leftMenuYContraints.constant = 136.0f;
leftMenuBottomConstraint.constant = 5.0f;
[UIView animateWithDuration:0.7f
delay:0.0f
options:UIViewAnimationOptionCurveLinear
animations:^
{
// Move in menus
[self.primaryOptionCollection layoutIfNeeded];
[self.menuOptionCollection layoutIfNeeded];
}
completion:^(BOOL finished)
{
}];
I changed to and now works in both iOS7 and 6, still not sure why it does/did it though! I still think I am setting something up wrong in the Storyboard. I am add another view (nothing to do with this lot) programmatically so I believe that is based around frames until I convert it (which I am not doing).
primaryMenuYContraints.constant = BUTTOMX;;
leftMenuYContraints.constant = 136.0f;
leftMenuBottomConstraint.constant = 5.0f;
[UIView animateWithDuration:0.7f
delay:0.0f
options:UIViewAnimationOptionCurveLinear
animations:^
{
// Move in menus
[self.view layoutIfNeeded];
}
completion:^(BOOL finished)
{
}];

Strange controls animation after transitionWithView

I am trying to transition from one view to another.
The final view I'm transitioning to is a XIB with a couple buttons and a title bar.
My problem is that after the transition, the buttons get displayed on the very top left of the window for a fraction of a second, and eventually "drag" to their expected coordinates. Everything is perfectly usable and functional, but the transition looks a little funny.
Any idea what could cause this?
Here is my code snipet:
Homepage *hp = [[Homepage alloc] init];
hp.data = self.data;
[UIView transitionWithView:self.view duration:0.5
options:UIViewAnimationOptionTransitionCurlDown
animations:^ { [self.view addSubview:hp.view]; }
completion:nil];
[hp DisplayThumbnails];
[hp release];
I wanted to provide the code snippet that I've used to resolve this problem using Jacob's recommendation in case someone else runs into this. Here it is:
Homepage *hp = [[Homepage alloc] init];
hp.data = self.data;
[hp.view setHidden:YES];
[self.view addSubview:hp.view];
[UIView transitionWithView:self.view duration:0.5
options:UIViewAnimationOptionTransitionCurlDown
animations:^ { [hp.view setHidden:NO];}
completion:nil];
[hp DisplayThumbnails];

Force NavigationBar's title to animate

I'm developing a navigation system that drills down three steps and then lets you navigate the contents with arrows that actually just change the contents of that view, so technically the navigationcontroller doesn't receive any pop/push, because of that I as soon as I do a
self.navigationItem.title = [[[self.symbol valueForKey:#"section_title"] uppercaseString] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
the title changes as It should but for obvious reasons doen't animate.
Is there a way to force it to animale as if a pop/push action happened?
something like:
self.navigationItem.direction = NavigationDirectionLeft;
self.navigationItem.title = #"Whatevah!";
so that as soon as the title changes it make the old title fades out
in a transition that goes from left to right and the the title fades in, or
way better the new title faded in transitioning from left to right entering
from the left side
[FYI I don't need to support ios versions prior to 5.0, so only 5.0 > :)]
OK, this isn't a perfect solution, but might give you a starting point:
Fading between nav bar titles is fairly simple:
CATransition *fade = [CATransition animation];
fade.type = kCATransitionFade;
fade.duration = 2.0;
[self.navigationController.navigationBar.layer addAnimation: fade forKey: #"fadeText"];
self.navigationItem.title = "new Title";
There are other kinds of "out of the box" transitions you can use to animate the position of the title, so for example:
CATransition *push = [CATransition animation];
push.duration = 2.0;
push.type = kCATransitionPush;
push.subtype = kCATransitionFromRight;
[self.navigationController.navigationBar.layer addAnimation: push forKey: #"pushText"];
self.navigationItem.title = "new Title";
The problem with this is that the whole nav bar moves. To get around this you'll need to find the layer for the title label in the navbar's subviews. This view hierarchy is 'private', so you shouldn't go submitting this code to the store, but like I say… this might give you a starting point.
CATransition *fade = [CATransition animation];
fade.type = kCATransitionFade;
fade.duration = 2.0;
CATransition *move = [CATransition animation];
move.duration = 2.0;
move.type = kCATransitionMoveIn;
move.subtype = kCATransitionFromRight;
UILabel * navBarTitleLabel;
for (UIView * view in self.navigationController.navigationBar.subviews) {
if ([NSStringFromClass(view.class) isEqualToString: #"UINavigationItemView"]) {
navBarTitleLabel = view.subviews.firstObject;
break;
}
}
[navBarTitleLabel.layer addAnimation: fade forKey: #"fadeText"];
[navBarTitleLabel.layer addAnimation: move forKey: #"moveText"];
self.navigationItem.title = newTitle;
You might find that you need to removeAllAnimations from the layer once they're complete. I didn't get a chance to fully test it all out.
Try setting a UIView as self.navigationItem.titleView and then create a UILabel and add it as title. When you want to animate, animate this Label over this UIView and add a new UILabel and animate that to replace this. You can use some block based animations for this.
For eg:-
[UIView animateWithDuration:0.5
delay:1.0
options: UIViewAnimationCurveEaseOut
animations:^{
label.frame = labelFrame;
}
completion:^(BOOL finished){
NSLog(#"Done!");
}];

Drop Down UIView With Buttons

Okay, so I want to make a menu that expands down at the current touch location. I achieve this by adding my menuView with a height of 1 and then changing the height to my desired one like this:
[UIView beginAnimations:NULL context:nil];
CGRect fullRect;
fullRect = CGRectMake(menuView.frame.origin.x, menuView.frame.origin.y, 290, 180);
menuView.frame = fullRect;
[UIView commitAnimations];
Now the problem is that there are 4 buttons in this menuView and these buttons appear first and then the menuView expands down under them. Any ideas how to make the buttons appear with the menuView and not before it?
You have to set menuView.clipsToBounds = YES so the buttons are not shown outside the bounds of your menuView while it is expanding.
I would also add the following to have a fade-in effect for your buttons.
button1.alpha = 0.0; // Do this for each button before the [UIView beginAnimations];
button1.alpha = 1.0; // Do this during the animation block.
I would use a Block animation instead. That way, you can make the buttons appear during or after the animation easily. Try something like:
[UIView animateWithDuration:1.0
animations:^{
CGRect newRect = menuView.frame;
menuView.size.height += 289;
menuView.frame = newRect;
}
completion:^(BOOL finished){
[UIView animateWithDuration:0.1
animations:^{
button.hidden = NO;
}
completion:^(BOOL finished){
;
}];
}];
This will make the button stop hiding at the end of the animation. Of course, you could add more blocks in the completion block to handle more animations, and it is easy to customize this. Hope that helps!