Rotate UIButton on change of orientation - ios

I have round button which consists of the following image
Now on rotation of device I want to rotate the button in a way that the image maintains the orientation.
How can I achieve this,
I do not want to change the frame of the button i want it to stay where it is I just want to transform the button.

If you have an IBOutlet Object.
theButton.transform = CGAffineTransformMakeRotation(M_PI / -4);
If you want to create run time button on view.
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *btn=[UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn setFrame:CGRectMake(100, 100, 200, 44)];
btn.transform=CGAffineTransformMakeRotation(M_PI / -4);
[btn setTitle:#"RakeshBhatt" forState:UIControlStateNormal];
[self.view addSubview:btn];
}

To rotate a image view try this
// Set the anchor point and center so the view swings from the upper right
imageView.layer.anchorPoint = CGPointMake(1.0, 0.0);
imageView.center = CGPointMake(CGRectGetWidth(self.view.bounds), 0.0);
// Rotate 90 degrees to hide it off screen
CGAffineTransform rotationTransform = CGAffineTransformIdentity;
rotationTransform = CGAffineTransformRotate(rotationTransform, DegreesToRadians(90));
swingView.transform = rotationTransform;

Related

Animate 3 lines into arrow in iOS for a uibutton

Does anyone know how to animate 3 parallel lines to a right arrow as happens in navigation menu bar to open up a side menu by applying CGAfflineRotation to 3 views .
I really need help on these as so that at-least I can get an idea to start it.
This is what it will be look like some how tried to draw it:-
_______
_______ \
_______ to ___________\
/
/
Any idea or suggestion will be helpful.
As you said, you should use CGAffineRotation. I'm giving simple example of what you want, everything should be ofc packed into proper methods, views should be with some basic autolayouts/layoutFrames etc. I'm just posting possible solution for rotation, quickly written in viewDidAppear, what should be changed.
Another option is to use eg firstView.layer.anchorPoint and set it to proper position.
#define degreesToRadians(x) (M_PI * x / 180.0)
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// let's create these 3 views as a lines
UIView *firstView = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 50, 1)];
[firstView setBackgroundColor:[UIColor blackColor]];
[self.view addSubview:firstView];
UIView *secondView = [[UIView alloc] initWithFrame:CGRectMake(50, 53, 50, 1)];
[secondView setBackgroundColor:[UIColor blackColor]];
[self.view addSubview:secondView];
UIView *thirdView = [[UIView alloc] initWithFrame:CGRectMake(50, 56, 50, 1)];
[thirdView setBackgroundColor:[UIColor blackColor]];
[self.view addSubview:thirdView];
// now we can perform rotation, mind the degree and offsets in transform.
[UIView animateWithDuration:1 animations:^{
CGAffineTransform transform = CGAffineTransformMakeTranslation(24, 1);
transform = CGAffineTransformRotate(transform, degreesToRadians(45));
transform = CGAffineTransformTranslate(transform, -24, 1);
firstView.transform = transform;
transform = CGAffineTransformIdentity;
transform = CGAffineTransformMakeTranslation(24, -1);
transform = CGAffineTransformRotate(transform, degreesToRadians(-45));
transform = CGAffineTransformTranslate(transform, -24, -1);
thirdView.transform = transform;
} completion:^(BOOL finished) {}];
}
It is easier to do such animation with CALayer Animation instead of UIView Animation. You need to add three sub layers: top_line, middle_line, and bottom_line. Then draw the line on each layer and the right position (Hint: use CAShapeLayer for drawing lines). At last just rotate the top_line and bottom_line layer with a proper angle, you probably need to change the anchor point and layer's position as well. It is quite tricky at the last step, maybe just do some trials with different angle and anchor point values until you find the most proper ones.
When you successfully did such animation, try to do the reverse animation. Then create a Custom UIButton with these two animations embedded in. Congratulations! You have a hamburger button with cool animations which could be reused anywhere!

Creating a scalable Image button in iOS. Without a blurry image.

What am I trying to do:
I want to make a button that scales up or down depending on it's current state which is determined by it either being big or small.
When button is big and I press it, it becomes small. When the button is small and I press it, it becomes big.
The button must contain a image of a QR code and subsequently be scannable by a QR reader.
My problem:
Is that the image is blurry when big. This isn't the case if I put the image inside a ImageView instead of a button.
The effect is best described here:
http://imgur.com/a/h3rJg#0
The Code:
Button/Image Declaration
UIImage* image = [QREncoder encode:user];
// declare image - QREncoder can be found on github
UIImage *strechedBackground = [image stretchableImageWithLeftCapWidth:220 topCapHeight:220];
UIImageView* imageView = [[UIImageView alloc] initWithImage:image];
CGFloat qrSize = self.view.bounds.size.width - kPadding * 2;
CGRect largeFrame = CGRectMake(kPadding, (self.view.bounds.size.height - qrSize) / 2,
qrSize, qrSize);
imageView.frame = largeFrame;
[imageView layer].magnificationFilter = kCAFilterNearest;
//[self.view addSubview:imageView];
// add qr button to the view
self.qrButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.qrButton.frame = largeFrame;
[self.qrButton setBackgroundImage:image forState:UIControlStateNormal];
[self.qrButton addTarget:self
action:#selector(aMethod)
forControlEvents:UIControlEventTouchDown];
self.qrButton.contentMode = UIViewContentModeCenter;
[self.view addSubview:self.qrButton];
Button/Image Scale Function
- (void)aMethod{
// some variables concerned with button sizes and dimensions
CGFloat qrSize = self.view.bounds.size.width - kPadding * 2;
CGRect largeFrame = CGRectMake(kPadding, (self.view.bounds.size.height - qrSize) / 2,
qrSize, qrSize);
CGFloat smallButtonWidth = 33.0;
CGFloat smallButtonHeight = 33.0;
CGFloat largeButtonWidth = 264.0;
CGFloat largeButtonHeight = 264.0;
CGRect smallFrame = CGRectMake(self.view.frame.size.width - smallButtonWidth - kPadding/2, self.view.frame.size.height - smallButtonHeight - kPadding/2, smallButtonWidth, smallButtonHeight);
// a boolean ivar indicates the size of the button
if (!self.qrButtonIsBig){
NSLog(#"Button was Big");
// animate the view...
[UIView animateWithDuration:0.5
delay:0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
//self.qrButton.transform = CGAffineTransformMakeScale(3, 3);
// resting positon after animation
self.qrButton.frame = smallFrame;
}
completion:nil];
NSLog(#"Button is now Small");
}else{
NSLog(#"Button was Small");
// animate the view...
[UIView animateWithDuration:0.5
delay:0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
self.qrButton.transform = CGAffineTransformIdentity;
// resting positon after animation, bottom left with 20 px margin
self.qrButton.frame = largeFrame;
}
completion:nil];
NSLog(#"Button is now Big");
}
self.qrButtonIsBig = !self.qrButtonIsBig;
}
If you need your view to be sharper when it is resized then you need your CALayer class to be a CATiledLayer. you can subclass it in order to define how you will fill your tiles.
Check this question if you want to go this road
check this question if you don't want to use CATiledLayer
Since the ImageView was sharp and ButtonImage blurry. It makes sense to scale the imageview with an invisible button on top as a practical work around rather than trying to get the image to be sharp in the button.

Animate size of View keeping its bottom left point fixed

I have a UIView at the bottom left of its superview, i.e.its frame is like
[myView setFrame:CGRectMake(0,superView.bounds.size.height-myViewHeight,myViewWidth,myViewHeight)];
I want to animate its size such that its bottom left point remains fixed at its position. I am not sure how to play with anchor point property of layers.
Currently I am increasing its size using the following lines of code.
[UIView animateWithDuration:0.2 animations:^{
[bottomLbl setFrame:CGRectMake(0, bottomView.bounds.size.height-250, 300, 250)];
This works fine but when I try to bring back to its original size, its bottom point gets lifted at the start of animation and settles down at the end of animation.
First define the point for the bottom left corner...
CGPoint bottomLeft = CGPointMake(0, 480); // this can be anything.
Then you need to define the sizes (big and small).
CGSize bigSize = CGSizeMake(280, 280);
CGSize smallSize = CGSizeMake(50, 50); // again, these can be anything.
Then animate them...
// create the rect for the frame
CGRect bigFrame = CGRectMake(bottomLeft.x, bottomLeft.y - bigSize.height, bigSize.width, bigSize.height);
CGRect smallFrame = CGRectMake(bottomLeft.x, bottomLeft.y - smallSize.height, smallSize.width, smallSize.height);
[UIView animateWithDuration:0.2
animations:^{
// set the rect onto the view
bottomLbl.frame = bigFrame;
// or
bottomLbl.frame = smallFrame;
}];
As long as you set the frame and the calculated end frames are correct and it's all done in one animation then the bottom left corner won't move.
If this doesn't help can you please post a video of what is happening (and all your animation code).
EDIT
[UIView animateWithDuration:0.2
delay:0.0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
// set the rect onto the view
bottomLbl.frame = bigFrame;
// or
bottomLbl.frame = smallFrame;
}
completion:nil];

Center of second animation not using new position

I am having an issue with running two animations in iOS. First i am trying to move the image from the bottom of the screen to the top by changing frame in the first animation set, then on completion i am trying to extend the length of the object by transforming the scale. But for some reason once the first animation is finished the object goes back to the original place at the bottom of the screen and the growing transformation happens off the screen. Can anyone help me with this? Thanks in advance for your help, here is my code:
CGRect fullview = CGRectMake(59, 102, 650, 150);
CGRect iconView = CGRectMake(59, 102, 290, 150);
CGRect textView = CGRectMake(349, 102, 360, 150);
[_profileBtn setEnabled:FALSE];
[_profileBtn setHidden:TRUE];
[UIView animateWithDuration:1 animations:^{ // animate the following:
_profileIcon.frame = iconView; // move to new location
_profileText.frame = textView; // move to new location
_profileBackground.frame =fullview;
}completion:^(BOOL finished){
[UIView animateWithDuration:1 animations:^{ // animate the following:
_profileBackground.transform = CGAffineTransformMakeScale(1, 5.64);
}];
}];
Check out the documentation for the UIView transform property. Specifically, what happens to the object's frame if you adjust the transform. I think instead of performing the second animation on the UIView's transform, you should apply it to the scale of its layer's transform.
I figure out a solution that was close to what i wanted. This will do the translation and the movement at the same time:
CGRect iconView = CGRectMake(59, 102, 290, 150);
CGRect textView = CGRectMake(349, 102, 360, 150);
_profileIcon.frame = iconView; // move to new location
_profileText.frame = textView; // move to new location
CGAffineTransform scale = CGAffineTransformMakeScale(1, 5.00);
CGRect fullview = CGRectMake(59, 40, 650, 150);
_profileBackground.frame = CGRectApplyAffineTransform(fullview,scale);

zoom in UIImageView and UIImageView.center

Trying to zoom in / out an imageView.
i've managed that successfully so now i'm trying to place some buttons on the view and when button tapped to zoom on that area.
How can i implement that?
here is my code so far
-(void)zoomHere:(UIButton *)sender{
NSLog(#"zoom in");
//[self performSelector:#selector()
// withObject:nil
// afterDelay:1.6f];
CGAffineTransform transformer = CGAffineTransformScale(imageView.transform, 1.05, 1.05);
if (transformer.a < 5) {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration: 0.2];
imageView.transform = transformer;
[UIView setAnimationDelegate:self];
[UIView commitAnimations];
}
}
and the view did load
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *buttonView = [[UIView alloc]initWithFrame:CGRectMake(00.0, 20.0, 768, 1004.0)];
zoomHere = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[zoomHere addTarget:self
action:#selector(zoomHere:)
forControlEvents:UIControlEventTouchDown];
[zoomHere setTitle:#"ZoomIN" forState:UIControlStateNormal];
zoomHere.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
[buttonView addSubview:zoomHere];
buttonView.multipleTouchEnabled = YES;
[self.view addSubview:buttonView];
}
It still zoom in but not on that area where the button sits on screen!
if you want to use scale transform, you probably should use translate transform as welllike this:
CGAffineTransform scale = CGAffineTransformMakeScale(1.05, 1.05);
CGAffineTransform translate = CGAffineTransformMakeTranslation(10, 20);
CGAffineTransform delta = CGAffineTransformConcat(scale, translate);
imageView.transform = CGAffineTransformConcat(imageView.transform, delta);
this is how you know the position of button on your image view:
[imageView convertPoint:button.center fromView:self.view]
so if you know button's coordinates and your current scale then you can calculate new translate transformBut as for me, i would rather use scroll view to zoom in and zoom out that image view. You can have nice bouncing animations and zooming animations, also you can have pan and pinch, but of cource it is up to you.

Resources