Objective-C popup does not position - ios

I have a large bitmap in Xcode, on which a popup (UIView) is placed. Per default, it's hidden and is visible when pressing a button.
When visible, a x/y position is set... and it works.
After positioning, I want the popup appear with a scale-effect. This also works; however, the x/y positioning is ignored and the popup just appears where it's positioned in the Storyboard editor.
// Set position
minPopupFrame.origin.x = (_destinationensKoordinater[0] - minPopupFrame.size.width/2 + offsetX) * zoomfaktor;
minPopupFrame.origin.y = (_destinationensKoordinater[1] - minPopupFrame.size.height + offsetY) * zoomfaktor;
_popup.frame = minPopupFrame;
// Scale it to .1
_popup.transform = CGAffineTransformMakeScale(.1, .1);
_popup.hidden = NO;
// Set size to 100% in .3 seconds
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:.3];
_popup.transform = CGAffineTransformMakeScale(1, 1);
[UIView commitAnimations];
It's quite basic coding - but why doesn't it work? Suggestions, pretty please?
EDIT: I've also tried something like this - but the code is completely ignored:
_popup.hidden = NO;
CGAffineTransform scale = CGAffineTransformMakeScale(1, 1);
CGAffineTransform translate = CGAffineTransformMakeTranslation(200, 200);
CGAffineTransform transform = CGAffineTransformConcat(translate, scale);
_popup.transform = transform;
EDIT II: I also tried this:
_popup.center = CGPointMake((_destinationensKoordinater[0] - minPopupFrame.size.width/2 + offsetX) * zoomfaktor, (_destinationensKoordinater[1] - minPopupFrame.size.height + offsetY) * zoomfaktor);
_popup.transform = CGAffineTransformMakeScale(.1, .1);
_popup.alpha = 0;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:.3];
_popup.alpha = 1;
_popup.transform = CGAffineTransformMakeScale(1, 1);
[UIView commitAnimations];
The interesting bit is that the alpha animation works, but the popup positioning is ignored, if the first _popup.transform line isn't commented out. It doesn't make sense to me

Related

Scale animation in background from another anchorPoint

Ive done a Scaling animation for background image with an arrow in it,well by scaling the image(it includes the arrow) meaning its a whole background. it scales from the center of the background. but i want to start scaling from the center of arrow.
i want to achieve this :
Then to become with scale:
What i have to change in my code:
self.blueBackground.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1, 1);
[UIView animateWithDuration:5 animations:^{
self.blueBackground.transform = CGAffineTransformScale(CGAffineTransformIdentity, 30, 30);
} completion:^(BOOL finished) {
}];
With my current code the scale start from center of background so the arrow end up at the right (out the bounds of screen).
Try something like this:
- (void)animateArrow
{
self.blueBackground.transform = CGAffineTransformIdentity;
[UIView animateWithDuration:5 animations:^{
ScaleViewAboutPointInBounds(self.blueBackground, arrowCenter, 30);
} completion:^(BOOL finished) {
}];
}
static void ScaleViewAboutPointInBounds(UIView *view, CGPoint point, CGFloat scaleAmount)
{
CGFloat xAnchor = view.layer.anchorPoint.x * CGRectGetWidth(view.bounds);
CGFloat yAnchor = view.layer.anchorPoint.y * CGRectGetHeight(view.bounds);
CGFloat xOffset = point.x - xAnchor;
CGFloat yOffset = point.y - yAnchor;
CGAffineTransform shift = CGAffineTransformMakeTranslation(-xOffset, -yOffset);
CGAffineTransform unshift = CGAffineTransformMakeTranslation(xOffset, yOffset);
CGAffineTransform scale = CGAffineTransformMakeScale(scaleAmount, scaleAmount);
view.transform = CGAffineTransformConcat(shift, CGAffineTransformConcat(scale, unshift));
}
It's probably more general than what you need, and you could do it simpler, but this should work too. Just change the point to something that looks like the center of the arrow.

Scale/Animate One Side of UIView to Be Smaller? - CGAffineTransformMakeScale

I would like to animate a UIView so its right side becomes smaller and then back again. This animation will trigger when a UIButton in this UIView is tapped. Here is a quick mockup of what I would like - the UIView will go from state 1 > state 2 > state 1:
It looks like it is being pushed on one side.
Here is the code I have for another action - this makes the UIView smaller and larger again as if it is being pushed on the centre, rather than the side.
self.myView.transform = CGAffineTransformMakeScale(0.95,0.95);
self.myView.alpha = 1.f;
[UIView beginAnimations:#"button" context:nil];
[UIView setAnimationDuration:0.5];
self.myView.transform = CGAffineTransformMakeScale(1,1);
self.myView.alpha = 1.0f;
[UIView commitAnimations];
How do I apply this same effect but only to the right side? Any help would be much appreciated, thanks!
According to this question u need t make Perspective Transform for example, i modified a bit from that question i linked
CATransform3D perspectiveTransform = CATransform3DIdentity;
perspectiveTransform.m34 = 1.0 / -500;
perspectiveTransform = CATransform3DRotate(perspectiveTransform, 40.0f * M_PI / 180.0f, 0.0f, 1.0f, 0.0f);
[UIView animateWithDuration:0.4 animations:^{
self.myView.layer.transform = perspectiveTransform;
}];
EDIT 2 Brings back to original
- (void)startAnimation:(id)sender
{
CATransform3D perspectiveTransform = CATransform3DIdentity;
perspectiveTransform.m34 = 1.0 / -500;
perspectiveTransform = CATransform3DRotate(perspectiveTransform, 40.0f * M_PI / 180.0f, 0.0f, 1.0f, 0.0f);
[UIView animateWithDuration:1.4 animations:^{
self.myView.layer.transform = perspectiveTransform;
}completion:^(BOOL finished) {
CATransform3D originalPerspectiveTransform = CATransform3DIdentity;
[UIView animateWithDuration:0.9 animations:^{
self.myView.layer.transform = originalPerspectiveTransform;
}];
}];
}

How to lengthen the UISearchBar in x direction with animation?

I want to lengthen the right search bar 20 px to the left, and shorten left search bar 20 px to the right with animation. How can I do that?
CGRect leftFrame = self.leftSearchBar.frame;
//leftFrame.origin.x = leftFrame.origin.x - 20;
leftFrame.size.width = leftFrame.size.width - 40;
CGRect rightFrame = self.rightSearchBar.frame;
rightFrame.origin.x = rightFrame.origin.x - 40;
rightFrame.size.width = rightFrame.size.width + 40;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelay:0.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
self.leftSearchBar.frame = leftFrame;
self.rightSearchBar.frame = rightFrame;
[UIView commitAnimations];
It doesn't work. It first resizes views without animation, then moves the right view with animation.
Assuming you've not changed the anchor points, or anything like that, simply expanding the width will make it stretch to the right. Wrap this within a UIView animation block, and it should animate according to the specification within the question, as so:
UISearchBar* searchbar = ...; // However you've created your UISearchBar, we'll refer to it as 'searchbar'
CGRect searchFrame = searchbar.frame;
[UIView animateWithDuration:0.8
delay:0.0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
searchFrame.size.width += 30;
searchbar.frame = searchFrame;
}
completion:nil];
You'll need to make sure the += 30 doesn't get called more than once, as otherwise you'll be expanding by 30 points each time this is called. If you know the size before hand, you could simply substitute it with = size + 30, which is a safer bet incase you call the animation more than once.

How to animate UIImageViews like hatch doors opening

I'm trying to create an animation that would look like 2 french doors (or 2 hatch doors) opening towards the user.
I tried using the built in UIViewAnimationOptionTransitionFlipFromRight transition, but the origin of the transition seems to be the center of the UIImageView rather than the left edge. Basically I have 2 UIImageViews that each fill have the screen. I would like the animation to look like the UIImageViews are lifting from the center of the screen to the edges.
[UIView transitionWithView:leftView
duration:1.0
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^ { leftView.alpha = 0; }
completion:^(BOOL finished) {
[leftView removeFromSuperview];
}];
Has anyone done something like this before? Any help would be awesome!
UPDATE:
Working code thanks to Nick Lockwood
leftView.layer.anchorPoint = CGPointMake(0, 0.5); // hinge around the left edge
leftView.frame = CGRectMake(0, 0, 160, 460); //reset view position
rightView.layer.anchorPoint = CGPointMake(1.0, 0.5); //hinge around the right edge
rightView.frame = CGRectMake(160, 0, 160, 460); //reset view position
[UIView animateWithDuration:0.75 animations:^{
CATransform3D leftTransform = CATransform3DIdentity;
leftTransform.m34 = -1.0f/500; //dark magic to set the 3D perspective
leftTransform = CATransform3DRotate(leftTransform, -M_PI_2, 0, 1, 0);
leftView.layer.transform = leftTransform;
CATransform3D rightTransform = CATransform3DIdentity;
rightTransform.m34 = -1.0f/500; //dark magic to set the 3D perspective
rightTransform = CATransform3DRotate(rightTransform, M_PI_2, 0, 1, 0);
rightView.layer.transform = rightTransform;
}];
First add the QuartzCore library to your project and #import <QuartzCore/QuartzCore.h>
Every view has a layer property with sub-properties that are animatable. This is where you'll find all the really cool stuff when it comes to animation capabilities (I suggest reading up on the CALayer class properties you can set - it will blow your mind - dynamic soft drop shadows on any view?)
Anyway, back on topic. To rotate your doors open in 3D, first position them as if they were closed, so with each door filling half the screen.
Now set their view.layer.anchorPoint properties as follows
leftDoorView.layer.anchorPoint = CGPoint(0, 0.5); // hinge around the left edge
rightDoorView.layer.anchorPoint = CGPoint(1.0, 0.5); // hinge around the right edge
Now apply the following animation
[UIView animateWithDuration:0.5 animations:^{
CATransform3D leftTransform = CATransform3DIdentity;
leftTransform.m34 = -1.0f/500; //dark magic to set the 3D perspective
leftTransform = CATransform3DRotate(leftTransform, M_PI_2, 0, 1, 0); //rotate 90 degrees about the Y axis
leftDoorView.layer.transform = leftTransform;
//do the same thing but mirrored for the right door, that probably just means using -M_PI_2 for the angle. If you don't know what PI is, Google "radians"
}];
And that should do it.
DISCLAIMER: I've not actually tested this, so the angles may be backwards, and the perspective may be screwy, etc. but it should be a good start at least.
UPDATE: Curiosity got the better of me. Here is fully working code (this assumes that the left and right doors are laid out in the closed position in the nib file):
- (void)viewDidLoad
{
[super viewDidLoad];
leftDoorView.layer.anchorPoint = CGPointMake(0, 0.5); // hinge around the left edge
leftDoorView.center = CGPointMake(0.0, self.view.bounds.size.height/2.0); //compensate for anchor offset
rightDoorView.layer.anchorPoint = CGPointMake(1.0, 0.5); // hinge around the right edge
rightDoorView.center = CGPointMake(self.view.bounds.size.width,self.view.bounds.size.height/2.0); //compensate for anchor offset
}
- (IBAction)open
{
CATransform3D transform = CATransform3DIdentity;
transform.m34 = -1.0f/500;
leftDoorView.layer.transform = transform;
rightDoorView.layer.transform = transform;
[UIView animateWithDuration:0.5 animations:^{
leftDoorView.layer.transform = CATransform3DRotate(transform, M_PI_2, 0, 1, 0);
rightDoorView.layer.transform = CATransform3DRotate(transform, -M_PI_2, 0, 1, 0);
}];
}
- (IBAction)close
{
[UIView animateWithDuration:0.5 animations:^{
CATransform3D transform = CATransform3DIdentity;
transform.m34 = -1.0f/500;
leftDoorView.layer.transform = transform;
rightDoorView.layer.transform = transform;
}];
}

animated popup view similar to one in Ipad music folder

I would like to know what is the name of the functionality that is used in the Ipad's Music folder, where when an album folder is clicked, details regarding that album pops up in an animated view.
I tried using presentModelViewController but its functionality is different.
It would be great if someone could help me out.
I just managed to get sth. like this to work using CoreAnimation / QuartzCore Framework...
be sure to
#import <QuartzCore/QuartzCore.h>
when you want to animate, use CATransform3Dand the poorly documented CATransform3D.m34 property. this will do the first half of the animation (assuming 200x200<->450x450 with 180° rotation):
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationDelegate:self];
CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
rotationAndPerspectiveTransform.m34 = 1.0 / -1000; // this turns on perspective!
rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, 90.0f * M_PI / 180.0f, 0.0f, 1.0f, 0.0f);
someView.layer.transform = rotationAndPerspectiveTransform;
someView.bounds = CGRectMake(0, 0, 325, 325);
[UIView commitAnimations];
for the second half of the animation, you have to add/remove your view to the hierarchy. this example shows hiding/showing of a view that already exists as a subview of someView, it also makes use of a BOOL isUp instance variable (the first half of the aniation is independent of the isUp-flag!)
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
if (flag) {
if (isUp) {
someSubView.hidden = YES; // hide subview
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
CATransform3D rotationAndPerspectiveTransform = CATransform3DRotate(someView.layer.transform, -90.0f * M_PI / 180.0f, 0.0f, 1.0f, 0.0f);
someView.layer.transform = rotationAndPerspectiveTransform;
someView.bounds = CGRectMake(0, 0, 200, 200);
[UIView commitAnimations];
isUp = NO;
} else {
someSubView.hidden = NO; // Show subview
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
CATransform3D rotationAndPerspectiveTransform = CATransform3DRotate(someView.layer.transform, 90.0f * M_PI / 180.0f, 0.0f, 1.0f, 0.0f);
someView.layer.transform = rotationAndPerspectiveTransform;
someView.bounds = CGRectMake(0, 0, 450, 450);
[UIView commitAnimations];
isUp = YES;
}
}
}
one last thing: everything in your view will appear mirrored, it might not be the ideal solution, but mirroring back by applying a CGAffineTransform to the subview does the trick:
- (void)viewDidLoad
{
[super viewDidLoad];
someSubView.transform = CGAffineTransformMakeScale(-1, 1);
isUp = NO;
}
i'm alredy a month late with this solution but i hope it helped someone :)
i first tried using the animateWithDuration:animations:completion: block-based API but that turned out to lag heavily (no smooth first/second-half animaiton even without touching subviews).
On the iPad you have several different options with regards to animating a modal view controller, you can find them here: UIModalTransitionStyle.
However, if you are referring to the "zoom and flip" sort of effect on the album I'm pretty sure this is private behaviour so you would need to develop this yourself.... you might be able to accomplish this with Core Graphics/Quartz.

Resources