I have this UIPickerView on my Storyboard :
and here's the position based on Size Inspector :
and here's my code :
- (void)showPickerView
{
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
self.picker.frame = CGRectMake(0 , 288, self.picker.frame.size.width, self.picker.frame.size.height);
self.picker.hidden = NO;
}
completion:^(BOOL finished) {
}];
}
(after trial and error) in order to be placed correctly (bottom) on 4-inch screen, I have to set 288 as Y. I have no idea where this number come from.
because if you do some a little math here you won't get that number :
iPhone screen height = 1136px, pickerview height = 216pts = 432px
if X and Y measured from TOP-LEFT (0, 0), then for 4 inch screen I should use 1136 - 432 = 704 px / 2 = 352pts. not 288pts.
but according to Size Inspector' origin, this object measured from bottom left. so, (0,0) of X and Y now measured from BOTTOM-LEFT. you still won't get that number.
plus, even worse... when I run on 3.5 inch Simulator it's not fully shown.
how to give X and Y value for UIPickerView so it will perfectly shown for both 3.5 and 4 inch retina display screen?
thank you.
The size 1136px is for full screen, you have to take in consideration that the status bar has 20px and the navigation bar has 44px so for your computation is like:
1136px - 432(picker) - 40(status bar) - 88(navigation bar) = 576; 576/2 = 288px
That's why the 288px is working for you.
if you want to give proper coordinates to your picker view you have to do something like this:
self.picker.hidden = NO;
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
self.picker.frame = CGRectMake(0 ,
self.view.fra.size.height
- self.picker.frame.size.height,
self.picker.frame.size.width,
self.picker.frame.size.height);
}
completion:^(BOOL finished) {
}];
But be careful, it's really important when you call this, make sure you call it in or after -viewDidAppear: is called. Due to the fact you want this piece of code to work perfect on both 3.5'' and 4 inch screens, the view won't be properly resized and the frame is not correct until this method is called, especially if you use storyboards with or xib that creates view controllers with views for 4 inch display.
Robert,
UIPicker's position is measured always from top left corner,
UIPicker co-ordinates are the co-ordinates of centre of uipicker.
For example if you give (0,0)it will show you quarter of pickerview i.e bottom right quarter.
As the uipicker height is fixed that is 216 you need Y c0-ordinate more than or=216/2=108.
And to see full width you need X co-ordinate (picker width/2 )
Best approach in my opinion is to use the bounds property of the containing view, which should be the root view of the view controller.
UIPickerView height is 216 pixels, as illustrated by this post - this value is set by default when a Picker View is initialised.
So if we take the post of danypata into consideration, but don't want to manually calculate with set values for navigation bar height, status bar height, etc... we can do something like the following:
UIPickerView *pickerView = [[UIPickerView alloc] init]; // default frame is set
float pvHeight = pickerView.frame.size.height;
float y = view.bounds.size.height - pvHeight; // the root view of view controller
[UIView animateWithDuration:0.5f delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
self.picker.frame = CGRectMake(0 , y, pickerView.frame.size.width, pvHeight);
}
completion:nil];
Related
I am trying to slide an image from off the screen onto the screen from the left and stopping at the center point in the view. I would like to keep it contrained at the y position if possible (IE image is set in story board).
I am reading this tutorial, but it is in swift and I cannot make the same assignments in objective-c.
http://www.raywenderlich.com/95910/uiview-animation-swift-tutorial
It says to set the view off the screen (in swift):
heading.center.x -= view.bounds.width
Then animate (in swift):
UIView.animateWithDuration(0.5, animations: {
self.heading.center.x += self.view.bounds.width
})
However I cannot manipulate center.x in objective c like they are doing in swift.
I have tried adjusting the initial position of the image in viewWillAppear by changing the bounds with no luck.
EDIT:
Here is what I am trying to get it positioned off the screen:
self.heading.center = CGPointMake(-200, self.heading.center.y);
No matter how negative I set the x position the view will still appears on the screen. Actually no matter what I set x position to the view does not move in the x direction at all. I have also tried to set the frame
The x coordinate of the view's center is not directly assignable in Objective-C. Instead, try setting the center point as whole. In your example, this could look something like this:
[UIView animateWithDuration:0.5 animations:^{
CGFloat newCenterX = self.heading.center.x + self.view.bounds.size.width;
self.heading.center = CGPointMake(newCenterX, self.heading.center.y);
}];
Try to use CGAffineTransformMakeTranslation:
[UIView animateKeyframesWithDuration:5
delay:0
options:UIViewKeyframeAnimationOptionCalculationModeLinear
animations:^{
view.transform = CGAffineTransformMakeTranslation(550, -40);
}];
I have four UIViews, positions on the four sides of my full view, e.g.
View 3
View 4 View 2
View 1
(Note that the bottom view is offset a little bit)
They are all 44x44 pixels and look exactly the same.
I have the views move counter clockwise to the next view's location (i.e. View 1 moves to View 2, View 2 moves to View 3, etc.), and View 4 moves to View 1, but not offset. This part works normally, the code is as follows:
[UIView animateWithDuration:0.5 animations:^{
[view1 setFrame:view2.frame];
[view2 setFrame:view3.frame];
[view3 setFrame:view4.frame];
[view4 setFrame:centerFrame];
} completion:^(BOOL finished) {
[self reloadData];
}];
centerFrame is view1's frame not offset.
In the method reloadData, the frames are move back to their original positions, and, because they all look the same, the only thing that users should see is the movement of the bottom view back to its offset position (although it is really changing from view4 to view1). This change looks a little bit sudden, and I wanted to animate it, but I don't want the views to move back, just cross dissolve, so that only the bottom view looks like it changed. I've tried:
[UIView transitionWithView:self.view duration:1.0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
// Reset frames
} completion:nil];
and
[UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
// Reset frames
} completion:nil];
but both move the views. So my question,
How do I animate a UIView frame change with a cross dissolve animation instead of moving between the points?
Thanks in advance!
You can animated alpha = 0, update the frames in the completion block and then animated alpha = 1. Make the duration of each animation block 1/2 the usual so together they'll take the same time as the rotation event.
If you want to do a simultaneous dissolve then duplicate all the views, set their alpha = 0, update their frames and then animate the alpha of both groups:
old views'.alpha = 0new views'.alpha = 1
a third solution - group all the views in a subview, copy the whole hierarchy and then animate the transition between them using options:UIViewAnimationOptionTransitionCrossDissolve
What I'm trying to reach is similar to what is implemented on youTube app on iPad. The search field is expanding in animation from right to left. I'm trying to do so and i'm getting very strange and not smooth animation, Although left to right is working perfect.
|<-------------------------------|Search Field|
It seems that the origin value is changed first and than the width changed , un like the left-right expanding animation that the origin stays the same.
Thanks
You can use animation just put Search field in dynamically in view and put below code.
[UIView beginAnimations : #"Display notif" context:nil];
[UIView setAnimationDuration:0.30];
[UIView setAnimationBeginsFromCurrentState:FALSE];
CGRect frGnrVw = generalView.frame;
CGRect frTblNote = tblNotes.frame;
frGnrVw.size.height = 0.0;
frGnrVw.size.height += 78.0;
generalView.frame = frGnrVw;
[UIView commitAnimations];
In above code general view is my view which has hight 0 and when some action called at that time view height increase and and we will see that view expanding down in that i can not change view's x and y position But in your case first hide your view and when search action calls set hidden NO of your view and in my code i increase height so you can increase your width and also change it's x position means (decrese) i.e you increase width 320 than you decrese it x position to 320 .
just try it it will work.
you can also put it statically in your story board or in nib just set its width =0 and x= 320.
you have to do like below.
[UIView beginAnimations : #"Display notif" context:nil];
[UIView setAnimationDuration:0.30]; // set duration of animation in seconds.
[UIView setAnimationBeginsFromCurrentState:FALSE];
CGRect frGnrVw = generalView.frame; //get frame of view.
frGnrVw.size.width = 0.0;
frGnrVw.size.width += 320.0;//increase width.
frGnrVw.origin.x -=320.0; // decrese position.
generalView.frame = frGnrVw; //set new frame to view.
[UIView commitAnimations]; // this will require.
you just put your view with search field at the position x=320 ,y = as your requirement ,width = 0 and height = as your requirement.
try it it will work.
Also you can hide like same in reverse order.
means increase its x position and decrease its width with above code.
If my answer helps than please vote up my answer.
I am building a uicollectionview that will have rows of cells. Each cell will contain a UIButton. I want to be able to 'zoom into' the UIButton on tap.
I have discovered this code for zooming in on self.view, but I am not sure how to make it properly zoom in on the center of the tapped UIButton. Right now, it zooms in towards the bottom right corner of the screen.
Any suggestions on properly centering in on the tapped button?
-(void)didTapButton:(UIButton*)sender{
CGFloat s = 3;
CGAffineTransform tr = CGAffineTransformScale(self.view.transform, s, s);
CGFloat h = sender.frame.size.height;
CGFloat w = sender.frame.size.width;
[UIView animateWithDuration:2.5 delay:0 options:0 animations:^{
self.view.transform = tr;
self.view.center = CGPointMake(w*s/2,h-h*s/2);
} completion:^(BOOL finished) {}];
}
If you're using auto layout, you won't be able to use view animation in the way you're doing, because layout is triggered by the transform and keeps resetting the frame. This could explain why the zoom seems to expand the view down and to the right rather than from the center. (You might like to see my essay on the struggle between auto layout and view transforms.)
I am developing an iPad application that has a set of UIButton instances where I do a slight CGAffineTransform rotation in viewWillAppear: so that they are not perfectly aligned on the screen. A problem occurs, though, when the device is rotated in any direction and the background image of the button becomes more and more skewed the more it is rotated:
Correct:
After a few device rotations:
Here is the code that I am using to animate the view on viewDidAppear::
/*
* Animate video button
*/
CGPoint videoCenter = self.videoButton.center;
self.videoButton.center = CGPointMake(self.videoButton.center.x + 25.0f, self.videoButton.center.y + 25.0f);
[UIView animateWithDuration:0.5f
delay:0.0f
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
self.videoButton.center = videoCenter;
self.videoButton.transform = CGAffineTransformRotate(CGAffineTransformIdentity, [self convertDegreesToRadians:4.0f]);
}
completion:^(BOOL finished) {
// Do Nothing
}];
I have tried resetting the transform to what I need it to be in willRotateToInterfaceOrientation:, and though it lessens the degree to which it happens, after a number of rotations it produces a similar result.
I have tried changing autoresizesSubviews of the main view to be NO:
self.view.autoresizesSubviews = NO;
But then I have to layout my landscape orientation completely by hand, which I want to avoid.
How do I set the rotation transform so that it does not distort the background images of my UIButton on device orientation?
UPDATE:
I added some log statements in viewWillRotateToInterfaceOrientation: and noticed that the button's width is growing. This explains the image distortion, but why is it even changing? That seems odd to me:
width height
-------------------------------
268.574524 149.81514
286.267822 150
304.092621 150
321.91745 150
339.742279 150
357.567078 150
374.401642 150
391.236206 150
409.061066 150
425.895599 150
442.730164 150
459.564728 150
476.399292 150
493.233826 150
509.078125 150
524.922424 150
540.766663 150
556.611023 150
The problem that you are experiencing may be due to autoresizing done by UIViewController upon interface rotation. My suggestion is that you keep track of the original frame of the image view, and restore that original frame in didRotateFromInterfaceOrientation:. So, in -viewDidLoad, do something like this to save the frame of the view:
videoFrame = self.videoButton.frame;
In the header for this view controller, you should also declare CGRect videoFrame in order for the code above to work. Now, we can use this saved frame when the interface orientation is finished changing:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)orientation {
CGPoint oldCenter = [self.videoButton center];
[self.videoButton setTransform:CGAffineTransformIdentity];
[self.videoButton setFrame:videoFrame];
// restore previous center and rotation
[self.videoButton setCenter:oldCenter];
[self.videoButton setTransform:CGAffineTransformRotate(CGAffineTransformIdentity, [self convertDegreesToRadians:4.0f])];
}