I have an animation that moves three buttons upward on the screen programmatically. However, when I test it on the simulator for iPhone 6 or 4 the position of the buttons are all wrong (but are only right on the iPhone 5). How do I fix this. The buttons are built programmatically so I can't really use auto layout to position them on the view controller.
-(IBAction)Search:(id)sender {
self.button.frame = CGRectMake(124, 475, 78, 72);
self.buttonTwo.frame = CGRectMake(124, 475, 78, 76);
self.buttonThree.frame = CGRectMake(124, 475, 78, 76);
// animate
[UIView animateWithDuration:0.75 animations:^{
self.button.frame = CGRectMake(13, 403, 78, 72);
self.buttonTwo.frame = CGRectMake(124, 347, 78, 76);
self.buttonThree.frame = CGRectMake(232, 403, 78, 76);
You are using fixed values for frames, but the screens are different widths and/or heights.
If they are correct for iPhone 5-5s (Also known as iPhone 4") then one way to handle it is:
-(IBAction)Search:(id)sender {
CGFloat screenWidth = self.view.bounds.size.width;
CGFloat screenHeight = self.view.bounds.size.height;
CGFloat normalizedX = (124 / 320) // You calculate these 'normalized' numbers, possibly from a designer's spec.
// it's the percent the amount should be over, as number from 0-1.
// This number is based on screen width of 320 having x 124 pt.
CGFloat startingX = normalizedX * screenWidth;
CGFloat startingY = (475 / 588) * screenHeight;
CGFloat width = (78 / 320) * screenWidth;
CGFloat height = (72 / 588) * screenHeight;
CGRect startingRect = CGRectMake(startingX, startingY, width, height)
self.button.frame = startingRect;
self.buttonTwo.frame = startingRect;
self.buttonThree.frame = startingRect;
// animate
[UIView animateWithDuration:0.75 animations:^{
CGFloat firstX = (13 / 320) * screenWidth;
CGFloat lowerY = (403 / 588) * screenHeight;
self.button.frame = CGRectMake(firstX, lowerY, width, height);
CGFloat secondX = (124 / 320) * screenWidth;
CGFloat upperY = (347 / 588) * screenHeight;
self.buttonTwo.frame = CGRectMake(secondX, upperY, width, height);
CGFloat thirdX = (233 / 320) * ScreenWidth;
self.buttonThree.frame = CGRectMake(thirdX, lowerY, width, height);
}];
}
This will scale the size of everything up and keep the relative positions. Note UIButtons will have the same text size. You can play with these numbers until you get the effect you want. Hope this helps!
Related
I am new to Objective-C. I created an animation that move 3 buttons upwards. These buttons contain images. However, when this button animation occurs it resizes the button images and makes them HUGE. I tried to correct the code below to resize the button images, but I still get HUGE buttons. Can someone please help me? It should be Width:78 Height:76. I tried replacing width and height but it still doesn't work. Note: Just correct the code, I don't need a completely different answer.
-(IBAction)Search:(id)sender {
CGFloat screenWidth = self.view.bounds.size.width;
CGFloat screenHeight = self.view.bounds.size.height;
CGFloat normalizedX = (124 / 320); // You calculate these 'normalized' numbers, possibly from a designer's spec.
// it's the percent the amount should be over, as number from 0-1.
// This number is based on screen width of 320 having x 124 pt.
CGFloat startingX = normalizedX * screenWidth;
CGFloat startingY = (475 / 200) * screenHeight;
CGFloat width = (42 / 40) * screenWidth;
CGFloat height = (30 / 30) * screenHeight;
CGRect startingRect = CGRectMake(startingX, startingY, width, height);
self.button.frame = startingRect;
self.buttonTwo.frame = startingRect;
self.buttonThree.frame = startingRect;
// animate
[UIView animateWithDuration:0.75 animations:^{
CGFloat firstX = (13 / 770) * screenWidth;
CGFloat lowerY = (403 / 370) * screenHeight;
self.button.frame = CGRectMake(firstX, lowerY, width, height);
CGFloat secondX = (124 / 424) * screenWidth;
CGFloat upperY = (347 / 447) * screenHeight;
self.buttonTwo.frame = CGRectMake(secondX, upperY, width, height);
CGFloat thirdX = (232 / 680) * screenWidth;
self.buttonThree.frame = CGRectMake(thirdX, lowerY, width, height);
}];
}
Looks to me like your height and width math is wrong.
(42/40) * screenWidth will simplify to (1) * screenWidth, or the full width of the screen (The expression 42/40 will be done using integer math, resulting in 1.0. If it used floating point, you'd get 1.05 * screenWidth, which would make the images even bigger.)
You have a similar problem with your height calculation. You are setting the button to be the full height of the screen, and slightly wider.
I am using the following animation to show a full screen image of a thumbnail onto the view:
[UIView animateWithDuration:0.5 delay:0 options:0 animations:^{
[testImageView setFrame:CGRectMake(0, 0, testImage.size.width, testImage.size.height)];
}completion:^(BOOL finished){
}];
However, this will not contain the image within the bounds of the screen if it is a large image.
Is there a way that I can set the width of the image to the width of the screen, and adjust the image's height then to keep the proper aspect ratio?
Like the above method but with a bit more modification:
CGFloat verticalScale = image.height / bounds.height;
CGFloat horizontalScale = image.width / bounds.width;
CGFloat scale = max(verticalScale,horizontalScale);
CGFloat imageViewHeight = image.height / scale;
CGFloat imageViewWidth = image.width / scale;
CGRect imageViewFrame = CGRectMake(x: DESIRE_X, y: DESIRE_Y, width:imageViewWidth ,height:imageViewHeight)
imageView.frame = imageViewFrame;
imageView.contentMode = UIViewContentModeScaleAspectFill;
CGRect bounds = [UIScreen mainScreen].bounds;
[testImageView setFrame:bounds];
testImageView.contentMode = UIViewContentModeScaleAspectFit;
But there may be some paddings if the image's scale is not equal to screen's.If you prefer the image to cover the full screen, then change contentMode to UIViewContentModeScaleAspectFill.
Please try this below code:
testImageView
=[[UIImageView alloc]initWithFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y ,self.view.frame.size.width, self.view.frame.size.height
)]
I'm using PEPhotoCropEditor library in one of my iOS project. I able to having constant aspect ratio (1:1) with following code.
- (void)openEditor {
PECropViewController *controller = [[PECropViewController alloc] init];
controller.delegate = self;
controller.image = self.imageView.image;
UIImage *image = self.imageView.image;
CGFloat width = image.size.width;
CGFloat height = image.size.height;
CGFloat length = MIN(width, height);
CGRectMake(CGFloat x, CGFloat y, CGFloat width, CGFloat height)
controller.imageCropRect = CGRectMake((width - length) / 2,
(height - length) / 2,
length,
length);
// Restricted to a square aspect ratio
controller.keepingCropAspectRatio = YES;
controller.cropAspectRatio = 1.0;
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:controller];
[self presentViewController:navigationController animated:YES completion:NULL];
}
But then I needed to have aspect ratio (height:width) of (1:3) instead of (1:1).
controller.cropAspectRatio = 1.0f / 3.0f;
I tried above and nothing happened. Still having same aspect ratio. Then I change below code too.
controller.imageCropRect = CGRectMake((width - length) / 2,
(height - length) / 2,
length * 3,
length);
Again nothing happened. After commenting above I hard coded the value like below.
controller.imageCropRect = CGRectMake(0.0f, 0.0f, 300.0f, 100.0f);
Then the cropping area displayed correctly but when resizing that aria will lead to destroy the crop aspect ratio (1:3)
Any idea how to remain aspect ratio (1:3) till all editing process complete?
Set this in ViewdidAppear in PECropViewController.m
self.cropAspectRatio = 1.0f;
self.keepingCropAspectRatio = YES;
And pass value to function setKeepingAspectRatio in PECropRectView.m
- (void)setKeepingAspectRatio:(BOOL)keepingAspectRatio
{
_keepingAspectRatio = keepingAspectRatio;
if (self.keepingAspectRatio) {
CGFloat width = CGRectGetWidth(self.bounds);
CGFloat height = CGRectGetHeight(self.bounds);
self.fixedAspectRatio = your_fixed_aspect_ratio_value;//fminf(width / height, height / width);
}
}
you will get expected result.
I call this function at viewDidLoad and didRotateFromInterfaceOrientation
-(void) makeBox{
[self.view1 removeFromSuperview];
float viewWidth = CGRectGetWidth(self.view.frame);
float viewHeight = CGRectGetHeight(self.view.frame);
float startx = (viewWidth / 100) * 10;
float starty = (viewHeight /100) * 20;
float width = (viewWidth / 100) * 80;
float height = (viewHeight /100) * 60;
CGRect frame1 = CGRectMake(startx, starty, width, height);
self.view1 = [[UIView alloc] initWithFrame:frame1];
[self.view1 setBackgroundColor:[UIColor redColor]];
[self.view addSubview:self.view1];
}
When the view does change, its very 'sketchy' & not very graceful at all. I'm using simulator but i assume that it would be the same if i were to run on a device. How would i go about making this transition smoother? I would post to user experiance page, but i wish todo this programmatically
The overall point of this, other than to learn, is to achieve orientation independent graphics from code (without autolayout).
There's no need to remove the view and create a new one with the desired frame if its the only thing you're changing. Just modify the view frame in-place:
- (void)makeBox {
CGFloat viewWidth = CGRectGetWidth(self.view.frame);
CGFloat viewHeight = CGRectGetHeight(self.view.frame);
CGFloat startx = (viewWidth / 100) * 10;
CGFloat starty = (viewHeight /100) * 20;
CGFloat width = (viewWidth / 100) * 80;
CGFloat height = (viewHeight /100) * 60;
CGRect view1Frame = CGRectMake(startx, starty, width, height);
if (!self.view1) {
// The view doesn't exists yet, we create it
self.view1 = [[UIView alloc] initWithFrame:view1Frame];
[self.view1 setBackgroundColor:[UIColor redColor]];
[self.view addSubview:self.view1];
}
else {
// Just update the frame
self.view1.frame = view1Frame;
}
}
For extra-nice UX, wrap the frame update in an animation block:
// ... snip ...
else {
[UIView animateWithDuration:0.3 animations:^() {
self.view1.frame = view1Frame;
}];
}
I have this code:
it's for 3 scroll view to have a random paging
CGRect frame = scrollView.frame;
CGRect frame1 = scrollView1.frame;
CGRect frame2 = scrollView2.frame;
frame.origin.x = frame.size.width * (arc4random() % (arrayimage.count ));
frame.origin.y = 0;
frame1.origin.x = frame.size.width * (arc4random() % (arrayimage.count ));
frame1.origin.y = 0;
frame2.origin.x = frame.size.width * (arc4random() % (arrayimage.count ));
frame2.origin.y = 0;
int pageFirst = scrollView.contentOffset.x/scrollView.frame.size.width;
int pageSecond = scrollView1.contentOffset.x/scrollView1.frame.size.width;
int pageThird = scrollView2.contentOffset.x/scrollView2.frame.size.width;
my problem is that when I launch my app nslog values for pageFisrt, pageSecond and PageThird is ever equal but paging is random and different; how can I have the correct value of pagefirst, pageSecond and pageThird?
You are setting the frame of your 3 scroll views which will position the 3 scrollViews at random places in their superview - this does not affect the contentOffset.
It looks as though what you meant to do was
scrollView.contentOffset = (CGPoint){scrollView.bounds.size.width * (arc4random() % (arrayimage.count )), 0};