Objective C - Set ImageView Width and Maintain Aspect Ratio - ios

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
)]

Related

How to align an image inside a imageView

I wanted to know how to align an image to the right while keeping the aspect fill. So this is how my image view looks right now.
I would like to move the image to the left, so that the image looks like this.
Now I tried aligning it to the right, but the image is so big that it only shows her gun. So I was wondering how would you be able to do this. Would I have to use a ScrollView? Would appreciate the help, Thanks.
I am not sure if this works for you or not:
Try the different contentModes:
Use it like:
imgView.contentMode = .scaleAspectFit //Or any from below options
You can Use StoryBoard also:
Try different types which suites your useCase
Hope this helps.
Set Content Mode of image Which is best for you Image View.
you could resize imageview as per the image size, below code is not tested:
CGSize kMaxImageViewSize = {.width = 100, .height = 100};
CGSize imageSize = image.size;
CGFloat aspectRatio = imageSize.width / imageSize.height;
CGRect frame = imageView.frame;
if (kMaxImageViewSize.width / aspectRatio <= kMaxImageViewSize.height)
{
frame.size.width = kMaxImageViewSize.width;
frame.size.height = frame.size.width / aspectRatio;
}
else
{
frame.size.height = kMaxImageViewSize.height;
frame.size.width = frame.size.height * aspectRatio;
}
imageView.frame = frame;

Load an image in UIImageView and resize the container - swift

I have an s3 link using which I need to load an image in UIImageView. I don't have the dimensions of image with me. I have defined mainImageView (leading and trailing constraints) in storyboard
In the code, I am loading the image using:
mainImageView.setImageWith(URL(string: ("https:" + (content?.imagePath)!)), placeholderImage: nil)
Do we have any way of resizing the container once the image loads? I want the container to take the dimensions (height and width) of the image. I heard that there is something called content wrap in Android to achieve the same. However, I am unable to find an equivalent in iOS.
If you are using Autolayout, you dont actually have to do much as UIImageView has an intrinsic size which makes it take the width and height of the image. In your .xib or .storyboard you need to position the image view so that it can resolve its position(horizontal and vertical). For size you can provide a default image(ow autolayout will show error).
When you will change the image at runtime, the imageview will take the size of its image.
You can achieve it using:
imgView.frame = [self frameForImage:self.image inImageViewAspectFit:imgView];
function implementation:
-(CGRect)frameForImage:(UIImage*)image inImageViewAspectFit:(UIImageView*)imageView
{
float imageRatio = image.size.width / image.size.height;
float viewRatio = imageView.frame.size.width / imageView.frame.size.height;
if(imageRatio < viewRatio) {
float scale = imageView.frame.size.height / image.size.height;
float width = scale * image.size.width;
float topLeftX = (imageView.frame.size.width - width) * 0.5;
return CGRectMake(topLeftX, 0, width, imageView.frame.size.height);
} else {
float scale = imageView.frame.size.width / image.size.width;
float height = scale * image.size.height;
float topLeftY = (imageView.frame.size.height - height) * 0.5;
return CGRectMake(0, topLeftY, imageView.frame.size.width, height);
}
}
You can resize the image by modifying its frame to the image's size:
mainImageView.frame = CGRect(origin: mainImageView.frame.origin, size: mainImageView.image.size)
If you are using Auto Layout, you need to modify the height and width constraints accordingly or let the layout to its job.

Scaling down the width of a view after doing rotation by using CGAffineTransformScale

I have drawn a view(black rectangle) straight to the x-axis then I am applying some rotation by using CGAffineTransformMakeRotation.Please see image 1 after rotation.
After this I need to reduce the width from that rotated position.
For that I am using CGAffineTransformScale but image is not scaling down along the slope.Please see image 2.
If I change width from bound property then it works fine.
Any idea why CGAffineTransformScale behaves like that.
Below is my sample code.
**__block CGAffineTransform rotationTransform;
rotationTransform = CGAffineTransformMakeRotation(angle);
lineview.transform = rotationTransform;
[UIView animateWithDuration:10 animations:^{
CGAffineTransform finalTransform = CGAffineTransformScale(lineview.transform, 0.4, 1);
lineview.transform = finalTransform;
} completion:^(BOOL finished) {
}];
Try this to move the frame and change the width :)
VIEW.frame = CGRectMake(0,39, 320, 111);
This is the format
CGRectMake(CGFloat x, CGFloat y, CGFloat width, CGFloat height)

UIImageView pinch zoom and reposition to fit overlay

I am using an UIImagePickerView to grab photos from the camera or camera roll. When the user 'picks' an image, I'm inserting the image onto an UIImageView, which is nested in a UIScrollView to allow pinch/pan. I have an overlay above the image view which represents the area to which the image will be cropped (just like when UIImagePickerView's .allowEditing property is YES).
The Apple-provided "allowEditing" capability also has the same problem I'm seeing with my code (which I why I tried to write it myself in the first place, and I need custom shapes in the overlay). The problem is that I can't seem to find a good way to allow the user to pan around over ALL the image. There are always portions of the image which can't be placed in the crop window. It's always content around the edges (maybe the outside 10%) of the image, which cannot be panned into the crop window.
In the above photo, the brown area at the top and bottom are the scroll view's background color. The image view is sized to the image.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
// Calculate what height/width we'll need for our UIImageView.
CGSize screenSize = [UIScreen mainScreen].bounds.size;
float width = 0.0f, height = 0.0f;
if (image.size.width > image.size.height) {
width = screenSize.width;
height = image.size.height / (image.size.width/screenSize.width);
} else {
height = screenSize.height;
width = image.size.width / (image.size.height/screenSize.height);
}
if (width > screenSize.width) {
height /= (width/screenSize.width);
width = screenSize.width;
}
if (height > screenSize.height) {
width /= (height/screenSize.height);
height = screenSize.height;
}
// Update the image view to the size of the image and center it.
// Image view is a subview of the scroll view.
imageView.frame = CGRectMake((screenSize.width - width) / 2, (screenSize.height - height) / 2, width, height);
imageView.image = image;
// Setup our scrollview so we can scroll and pinch zoom the image!
imageScrollView.contentSize = CGSizeMake(screenSize.width, screenSize.height);
// Close the picker.
[[picker presentingViewController] dismissViewControllerAnimated:YES completion:NULL];
}
I've considered monitoring scroll position and zoom level of the scroll view and disallow a side of the image to pass into the crop "sweet spot" of the image. This seems like over-engineering, however.
Does anyone know of a way to accomplish this?
I'm a moron. What a difference a good night's sleep can make ;-) Hopefully, it will help someone in the future.
Setting the correct scroll view contentSize and contentInset did the trick. The working code is below.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
// Change the frame of the image view so that it fits the image!
CGSize screenSize = [UIScreen mainScreen].bounds.size;
float width = 0.0f, height = 0.0f;
if (image.size.width > image.size.height) {
width = screenSize.width;
height = image.size.height / (image.size.width/screenSize.width);
} else {
height = screenSize.height;
width = image.size.width / (image.size.height/screenSize.height);
}
// Make sure the new height and width aren't bigger than the screen
if (width > screenSize.width) {
height /= (width/screenSize.width);
width = screenSize.width;
}
if (height > screenSize.height) {
width /= (height/screenSize.height);
height = screenSize.height;
}
CGRect overlayRect = cropOverlay.windowRect;
imageView.frame = CGRectMake((screenSize.width - width) / 2, (screenSize.height - height) / 2, width, height);
imageView.image = image;
// Setup our scrollview so we can scroll and pinch zoom the image!
imageScrollView.contentSize = imageView.frame.size;
imageScrollView.contentInset = UIEdgeInsetsMake(overlayRect.origin.y - imageView.frame.origin.y,
overlayRect.origin.x,
overlayRect.origin.y + imageView.frame.origin.y,
screenSize.width - (overlayRect.origin.x + overlayRect.size.width));
// Dismiss the camera's VC
[[picker presentingViewController] dismissViewControllerAnimated:YES completion:NULL];
}
The scrollview and image view are set up like this:
imageScrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
imageScrollView.showsHorizontalScrollIndicator = NO;
imageScrollView.showsVerticalScrollIndicator = NO;
imageScrollView.backgroundColor = [UIColor blackColor];
imageScrollView.userInteractionEnabled = YES;
imageScrollView.delegate = self;
imageScrollView.minimumZoomScale = MINIMUM_SCALE;
imageScrollView.maximumZoomScale = MAXIMUM_SCALE;
[self.view addSubview:imageScrollView];
imageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.backgroundColor = [UIColor grayColor]; // I had this set to gray so I could see if/when it didn't align properly in the scroll view. You'll likely want to change it to black
[imageScrollView addSubview:imageView];
Edit 3-21-14 Newer, fancier, better implementation of the method that calculates where to place the image in the screen and scrollview. So what's better? This new implementation will check for any image that is being set into the scrollview which is SMALLER in width or height, and adjust the frame of the image view such that it expands to be at least as wide or tall as the overlay rect, so you don't ever have to worry about your user selecting an image that isn't optimal for your overlay. Yay!
- (void)imagePickerController:(UIImagePickerController *)pickerUsed didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
// Change the frame of the image view so that it fits the image!
CGSize screenSize = [UIScreen mainScreen].bounds.size;
float width = 0.0f, height = 0.0f;
if (image.size.width > image.size.height) {
width = screenSize.width;
height = image.size.height / (image.size.width/screenSize.width);
} else {
height = screenSize.height;
width = image.size.width / (image.size.height/screenSize.height);
}
CGRect overlayRect = cropOverlay.windowRect;
// We should check the the width and height are at least as big as our overlay window
if (width < overlayRect.size.width) {
float ratio = overlayRect.size.width / width;
width *= ratio;
height *= ratio;
}
if (height < overlayRect.size.height) {
float ratio = overlayRect.size.height / height;
height *= ratio;
width *= ratio;
}
CGRect imageViewFrame = CGRectMake((screenSize.width - width) / 2, (screenSize.height - height) / 2, width, height);
imageView.frame = imageViewFrame;
imageView.image = image;
// Setup our scrollview so we can scroll and pinch zoom the image!
imageScrollView.contentSize = imageView.frame.size;
imageScrollView.contentInset = UIEdgeInsetsMake(overlayRect.origin.y - imageView.frame.origin.y,
(imageViewFrame.origin.x * -1) + overlayRect.origin.x,
overlayRect.origin.y + imageView.frame.origin.y,
imageViewFrame.origin.x + (screenSize.width - (overlayRect.origin.x + overlayRect.size.width)));
// Calculate the REAL minimum zoom scale!
float minZoomScale = 1 - MIN(fabsf(fabsf(imageView.frame.size.width) - fabsf(overlayRect.size.width)) / imageView.frame.size.width,
fabsf(fabsf(imageView.frame.size.height) - fabsf(overlayRect.size.height)) / imageView.frame.size.height);
imageScrollView.minimumZoomScale = minZoomScale;
// Dismiss the camera's VC
[[picker presentingViewController] dismissViewControllerAnimated:YES completion:NULL];
}

How to drawrect paintcode content centre horizontal on landscape iOS on retina iPad?

I'm getting in a bit of a muddle trying to draw some paintcode graphics code in the middle of the screen horizontally.
I'm really not sure if scale or landscape orientation affects this.
I've created a UIView subclass and addSubview in viewDidLoad like so...
MenuTitleView *fancyView = [[MenuTitleView alloc] initWithFrame:self.view.bounds];
[[self view] addSubview:fancyView];
Rather than the size PaintCode gave me...
CGRect textRect = CGRectMake(0, 0, 418, 129);
I'm trying to determine the screen / view width and the size of the canvas width.
I've tried various things without success.
CGRect screenRect = [[UIScreen mainScreen] applicationFrame];
CGFloat w = screenRect.size.width;
CGFloat width = 500;
CGFloat height = 200;
CGFloat x = (w - width) * 0.5f;
CGFloat y = 20;
CGRect textRect = CGRectMake(x, y, width, height);
Scale is not an issue, because Quartz and UIKit now work in 'points' rather than in pixels, so that's already accounted for. However orientation is not, [UIScreen mainScreen] will return the same rect either for applicationFrame or bounds etc, it's oblivious to orientation.
I like to put a solution in a category on UIView or UIViewController, because you'll reuse it plenty. something like this...
-(CGRect )workingCanvas{
CGRect screenRect = [UIScreen mainScreen].bounds;
BOOL landscape = UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]);
CGRect result = CGRectZero;
CGFloat lesserDimension = (screenRect.size.width < screenRect.size.height) ? screenRect.size.width : screenRect.size.height;
CGFloat greaterDimension = (screenRect.size.width > screenRect.size.height) ? screenRect.size.width : screenRect.size.height;
result.size.width = (landscape) ? greaterDimension : lesserDimension;
result.size.height = (landscape) ? lesserDimension : greaterDimension;
if ([[UIApplication sharedApplication]isStatusBarVisible]){
result.size.height -= [[UIApplication sharedApplication]statusBarFrame].size.height;
}
return result;
}
if you want to position your view just in the middle of the screen try this
CGRect screenRect = [[UIScreen mainScreen] applicationFrame];
CGFloat width = 500;
CGFloat height = 200;
CGFloat x = CGRectGetMidX(screenRect);
CGFloat y = 20;
CGRect textRect = CGRectMake(x, y, width, height);
already tested is working
Good Luck!!

Resources