How to slicing image and stretchable in iOS - ios

I need to stretch image right and left side centre half circle remain as it is. also need half circle in center
I have tried slicing concept and also tried below code
UIImage *image = self.imgBGBottom.image;
CGFloat capWidth = floorf(image.size.width / 2) - 50;
CGFloat capHeight = 0;
UIImage *capImage = [image resizableImageWithCapInsets:
UIEdgeInsetsMake(capHeight, capWidth, capHeight, capWidth)];
[self.imgBGBottom setImage:capImage];
but it is not working for me
Please help me. Thanks in advance.

You are using function, use - (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight instead - (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets.
Set top, left cap to stretch your image as described in following code.
Objective-C
UIImage *image = [UIImage imageNamed:#"test"];
CGFloat capTop = 50; // top cap to keep half round as is
CGFloat capLeft = 5; // To repeat it or stretch equally.
UIImage *capImage = [image stretchableImageWithLeftCapWidth:capLeft topCapHeight:capTop];
Swift
let image = UIImage(named: "stretchableImage")
let capTop:Int = 50; // top cap to keep half round as is
let capLeft:Int = 5; // To repeat it or stretch equally.
let capImage = image?.stretchableImage(withLeftCapWidth: capLeft, topCapHeight: capTop)
Alternet Solution
Same result can be achieved using following function as well.
Objective-C
UIImage *stretchedImage = [image resizableImageWithCapInsets:
UIEdgeInsetsMake(50, 50, 0, 50)];
Swift
var stretchedImage = image?.resizableImage(withCapInsets: UIEdgeInsets(top: 50, left: 50, bottom: 0, right: 50), resizingMode: .stretch)
Note : Keep stretchable image as small as possible otherwise it will not stretch properly with smaller image container(ImageView, Button etc.). You can reduce height & width of your existing image.

try this
UIImage *image = self.imgBGBottom.image;
CGFloat capWidth = floorf(image.size.width / 2) - 50;
CGFloat capTop = 50; //the value is determined by the half circle height,i guess it is 50 height
CGFloat capBottom = 0;
UIImage *capImage = [image resizableImageWithCapInsets:
UIEdgeInsetsMake(capHeight, capTop, capBottom, capWidth)];
[self.imgBGBottom setImage:capImage];

Related

How to center UIImageView within UIButton with its text?

I have a UIButton, and im adding an image like so:
UIImageView *cardImage = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"Visa.png"]];
cardImage.frame = CGRectMake(15, _cardButton.frame.size.height - 25 - 10, 25, 25);
cardImage.contentMode=UIViewContentModeScaleAspectFit;
[_cardButton addSubview:cardImage];
How can i show this image centered WITH the titleLable of the UIButton?
// try like this
cardImage.frame = _cardButton.frame;
cardImage.center = _cardButton.center;
cardImage.contentMode=UIViewContentModeCenter;
Try this on Its may be helpful to you
CGFloat flotspacing = 50; // the amount of spacing to appear between image and title
Btn.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, flotspacing);
Btn.titleEdgeInsets = UIEdgeInsetsMake(0, flotspacing, 0, 0);
and also try this code with .h and .m file
UIButton+BtnPosition.h
#interface UIButton(ImageTitleCentering)
-(void) centerButtonPositionAndImageWithSpacing:(CGFloat)spacing;
#end
UIButton+BtnPosition.m
#implementation UIButton(ImageTitleCentering)
-(void) centerButtonPositionAndImageWithSpacing:(CGFloat)spacing {
self.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, spacing);
self.titleEdgeInsets = UIEdgeInsetsMake(0, spacing, 0, 0);
}
#end
Now call this function with following
[button centerButtonPositionAndImageWithSpacing:10];
I use this coding for set button image and title in center it may be helpful to you.
Thanks...
Instead of adding imageview as subview of UIButton, try to set image with button image property.
// the space between the image and text
CGFloat spacing = 6.0;
// lower the text and push it left so it appears centered
// below the image
CGSize imageSize = button.imageView.image.size;
button.titleEdgeInsets = UIEdgeInsetsMake(
0.0, - imageSize.width, - (imageSize.height + spacing), 0.0);
// raise the image and push it right so it appears centered
// above the text
CGSize titleSize = [button.titleLabel.text sizeWithAttributes:#{NSFontAttributeName: button.titleLabel.font}];
button.imageEdgeInsets = UIEdgeInsetsMake(
- (titleSize.height + spacing), 0.0, 0.0, - titleSize.width);
// increase the content height to avoid clipping
CGFloat edgeOffset = fabsf(titleSize.height - imageSize.height) / 2.0;
button.contentEdgeInsets = UIEdgeInsetsMake(edgeOffset, 0.0, edgeOffset, 0.0);
Why you want to add UIImageView as subview to UIButton. UIButton is having BackgroundImage and Image property to set your image to button. Set the contentMode property to center to center the image.
_cardButton.contentMode=UIViewContentModeCenter;
If image looks too big in the UIButton, reduce the size of the image or ask your designer to give the image with required Padding.

Image resizing inside tableviewcell

I ran into a problem that can not solve 2 days. On the server image and come before inserting them in the box, I cut them on the client to fit the screen. Everything is good but the images change randomly height. Now the height is calculated independently - in proportion to the width.
Normal image:
Bad image
I can not ask explicitly UIImageView because I dynamically I rely all the cells to different devices.
My resize function:
-(UIImage *)resizeImage :(UIImage *)theImage :(CGSize)theNewSize {
UIGraphicsBeginImageContextWithOptions(theNewSize, NO, 1.0);
CGFloat height = theImage.size.height;
CGFloat newHeight = 0;
newHeight = (theNewSize.width * height) / theImage.size.width;
newHeight = floorf(newHeight);
NSLog(#"new height image %f", newHeight);
[theImage drawInRect:CGRectMake(0, 0, theNewSize.width, newHeight)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
inside layoutSubviews:
if(device == thisDeviceClass_iPhone5) {
[self.imageView setFrame:CGRectMake(0,0, 320, 255)]; //180
offset = 0;
padding = 5;
} else if(device == thisDeviceClass_iPhone6){
[self.imageView setFrame:CGRectMake(0,0, 375, 255)]; //211
offset = 25;
} else if(device == thisDeviceClass_iPhone6plus) {
[self.imageView setFrame:CGRectMake(0,0, 414, 255)]; //233
offset = 40;
}
Your approach is very old school. You are "hard coding" the size of the image which means that if next year Apple came up with a new iPhone that have, yet again, a different size you'll be in trouble. You should consider using auto-layout constrains which is Apple's recommended approach (here is a good tutorial: http://www.raywenderlich.com/50317/beginning-auto-layout-tutorial-in-ios-7-part-1).
You can also set the ImageView.contentMode to UIViewContentModeScaleAspectFill which will do the crop and resize for you.

How to make imageView fixed size and with rounded corners

I'm using Parse.com to build a simple app. I want to know if there is any way to make the imageView size fixed (for example 30x30px) and round the corners of the image?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
//-------------------------------------------------------------------------------------------------------------------------------------------------
{
PFTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (cell == nil) cell = [[PFTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cell"];
PFUser *user = users[indexPath.row];
cell.textLabel.text = user[PF_USER_FULLNAME];
PFImageView *imageView = [[PFImageView alloc] init];
[imageView setBackgroundColor:[UIColor clearColor]];
cell.imageView.image = [UIImage imageNamed:#"tab_profile.png"]; // placeholder image
cell.imageView.file = (PFFile *)user[PF_USER_THUMBNAIL]; // remote image
[cell.imageView loadInBackground];
return cell;
}
Please help with any advice, I'm new to Xcode and Parse SDK...
1)
2)
This is what I usually use to get a circle on an imageView:
Crop (not resize) the image to make it a square. The method below resizes the image to whatever size you pass as a CGSize:
(UIImage *)squareImageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize
{
double ratio;
double delta;
CGPoint offset;
//make a new square size, that is the resized imaged width
CGSize sz = CGSizeMake(newSize.width, newSize.width);
//figure out if the picture is landscape or portrait, then
//calculate scale factor and offset
if (image.size.width > image.size.height)
{
ratio = newSize.width / image.size.width;
delta = (ratio*image.size.width - ratio*image.size.height);
offset = CGPointMake(delta/2, 0);
} else {
ratio = newSize.width / image.size.height;
delta = (ratio*image.size.height - ratio*image.size.width);
offset = CGPointMake(0, delta/2);
}
//make the final clipping rect based on the calculated values
CGRect clipRect = CGRectMake(-offset.x, -offset.y,
(ratio * image.size.width) + delta,
(ratio * image.size.height) + delta);
//start a new context, with scale factor 0.0 so retina displays get
//high quality image
if ([[UIScreen mainScreen] respondsToSelector:#selector(scale)]) {
UIGraphicsBeginImageContextWithOptions(sz, YES, 0.0);
} else {
UIGraphicsBeginImageContext(sz);
}
UIRectClip(clipRect);
[image drawInRect:clipRect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Then, call the method just created, and apply the corner radius (in this case it will be a circle):
imageView.image = [self squareImageWithImage:imageNormal scaledToSize:CGSizeMake(50, 50)]; // assuming you want a 50x50px image
// convert imageview to circle
imageView.layer.cornerRadius = cell.imageView.frame.size.width / 2;
imageView.clipsToBounds = YES;
You can reduce the amount of the cornerRadius to something else with this same call.
This is how I do it:
Image with fix size
If it's possible use Storyboard and create 2 size constraints for the PFImageView with the 30 px value, but if the project doesn't uses size classes it should work without constraints, just set the proper size for the image. If you experience shape changes you could play with View Mode also.
TooManyEduardos's solution for the rounded image is correct, if you don't want circle just play with the numbers.
//1
imageView.layer.cornerRadius = cell.imageView.frame.size.width / 2;
//2
imageView.layer.cornerRadius = cell.imageView.frame.size.width / 4;
//3
imageView.layer.cornerRadius = cell.imageView.frame.size.width / 6;
//4
imageView.layer.cornerRadius = cell.imageView.frame.size.width / 8;

iOS - Cell image blurred

I have placed an image in a UITableViewCell and for some reason, the image is a bit blurred...
This is what I'm using:
NSURL *urlForProfileImage = [NSURL URLWithString: [_currentTweet[#"user"] objectForKey:#"profile_image_url_https"]];
UIImage *thumbnail = [UIImage imageWithData: [NSData dataWithContentsOfURL:urlForProfileImage]];
cell.imageView.image = thumbnail;
Is there another way to provide the desired result but maintain the images quality?
Reason :
The default imageView size is 40x40 and so your image needs to be 80x80 pixels (retina display).
But the image that you are getting from the "pbs.twimg.com/profile_images/192098593/Apple_normal.png" is 48x48.
And so it is blurred.
Solution :
One option is that you add a custom imageView which is 24x24. (width : 24 & height : 24) Then your image will not show blurred.
Or, you can try modifying the height and width of the imageView by subclassing the class UITableViewCell and using its layoutSubviews method. The "trick" is to write layout code in this method, otherwise the code does not have any effect :
- (void)layoutSubviews {
[super layoutSubviews];
self.imageView.bounds = CGRectMake(0,0,24,24);
self.imageView.frame = CGRectMake(0,0,24,24);
self.imageView.contentMode = UIViewContentModeScaleAspectFit;
CGRect tmpFrame = self.textLabel.frame;
tmpFrame.origin.x = 30;
self.textLabel.frame = tmpFrame;
tmpFrame = self.detailTextLabel.frame;
tmpFrame.origin.x = 30;
self.detailTextLabel.frame = tmpFrame;
}

scale Image in an UIButton to AspectFit?

I want to add an image to a UIButton, and also want to scale my image to fit with the UIButton (make image smaller). Please show me how to do it.
This is what I have tried, but it does't work:
Adding image to button and using setContentMode:
[self.itemImageButton setImage:stretchImage forState:UIControlStateNormal];
[self.itemImageButton setContentMode:UIViewContentModeScaleAspectFit];
Making a "stretch image":
UIImage *stretchImage = [updatedItem.thumbnail stretchableImageWithLeftCapWidth:0 topCapHeight:0];
I had the same problem. Just set the ContentMode of the ImageView that is inside the UIButton.
[[self.itemImageButton imageView] setContentMode: UIViewContentModeScaleAspectFit];
[self.itemImageButton setImage:[UIImage imageNamed:stretchImage] forState:UIControlStateNormal];
None of the answers here really worked for me, I solved the problem with the following code:
button.contentMode = UIViewContentModeScaleToFill;
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
You can do this in the Interface Builder as well.
The easiest way to programmatically set a UIButton imageView in aspect fit mode :
Swift
button.contentHorizontalAlignment = .fill
button.contentVerticalAlignment = .fill
button.imageView?.contentMode = .scaleAspectFit
Objective-C
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
button.imageView.contentMode = UIViewContentModeScaleAspectFit;
Note:
You can change .scaleAspectFit (UIViewContentModeScaleAspectFit) to .scaleAspectFill (UIViewContentModeScaleAspectFill) to set an aspect fill mode
If you really want to scale an image, do it, but you should resize it before using it. Resizing it at run time will just lose CPU cycles.
This is the category I'm using to scale an image :
UIImage+Extra.h
#interface UIImage (Extras)
- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize;
#end;
UIImage+Extra.m
#implementation UIImage (Extras)
- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize {
UIImage *sourceImage = self;
UIImage *newImage = nil;
CGSize imageSize = sourceImage.size;
CGFloat width = imageSize.width;
CGFloat height = imageSize.height;
CGFloat targetWidth = targetSize.width;
CGFloat targetHeight = targetSize.height;
CGFloat scaleFactor = 0.0;
CGFloat scaledWidth = targetWidth;
CGFloat scaledHeight = targetHeight;
CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
if (!CGSizeEqualToSize(imageSize, targetSize)) {
CGFloat widthFactor = targetWidth / width;
CGFloat heightFactor = targetHeight / height;
if (widthFactor < heightFactor)
scaleFactor = widthFactor;
else
scaleFactor = heightFactor;
scaledWidth = width * scaleFactor;
scaledHeight = height * scaleFactor;
// center the image
if (widthFactor < heightFactor) {
thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
} else if (widthFactor > heightFactor) {
thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
}
}
// this is actually the interesting part:
UIGraphicsBeginImageContextWithOptions(targetSize, NO, 0);
CGRect thumbnailRect = CGRectZero;
thumbnailRect.origin = thumbnailPoint;
thumbnailRect.size.width = scaledWidth;
thumbnailRect.size.height = scaledHeight;
[sourceImage drawInRect:thumbnailRect];
newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
if(newImage == nil) NSLog(#"could not scale image");
return newImage ;
}
#end
You can use it to the size you want. Like :
[self.itemImageButton setImage:[stretchImage imageByScalingProportionallyToSize:CGSizeMake(20,20)]];
I had problems with the image not resizing proportionately so the way I fixed it was using edge insets.
fooButton.contentEdgeInsets = UIEdgeInsetsMake(10, 15, 10, 15);
This can now be done through IB's UIButton properties. The key is to set your image as a the background, otherwise it won't work.
Expanding on Dave's answer, you can set the contentMode of the button's imageView all in IB, without any code, using Runtime Attributes:
1 means UIViewContentModeScaleAspectFit,
2 would mean
UIViewContentModeScaleAspectFill.
1 - clear Button default text (important)
2 - set alignment like image
3 - set content mode like image
If you simply want to reduce your button image:
yourButton.contentMode = UIViewContentModeScaleAspectFit;
yourButton.imageEdgeInsets = UIEdgeInsetsMake(10, 10, 10, 10);
I have a method that does it for me.
The method takes UIButton and makes the image aspect fit.
-(void)makeImageAspectFitForButton:(UIButton*)button{
button.imageView.contentMode=UIViewContentModeScaleAspectFit;
button.contentHorizontalAlignment=UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment=UIControlContentVerticalAlignmentFill;
}
The cleanest solution is to use Auto Layout. I lowered Content Compression Resistance Priority of my UIButton and set the image (not Background Image) via Interface Builder. After that I added a couple of constraints that define size of my button (quite complex in my case) and it worked like a charm.
Swift 5.0
myButton2.contentMode = .scaleAspectFit
myButton2.contentHorizontalAlignment = .fill
myButton2.contentVerticalAlignment = .fill
make sure that you have set the image to Image property, but not to the Background
Background image can actually be set to scale aspect fill pretty easily. Just need to do something like this in a subclass of UIButton:
- (CGRect)backgroundRectForBounds:(CGRect)bounds
{
// you'll need the original size of the image, you
// can save it from setBackgroundImage:forControlState
return CGRectFitToFillRect(__original_image_frame_size__, bounds);
}
// Utility function, can be saved elsewhere
CGRect CGRectFitToFillRect( CGRect inRect, CGRect maxRect )
{
CGFloat origRes = inRect.size.width / inRect.size.height;
CGFloat newRes = maxRect.size.width / maxRect.size.height;
CGRect retRect = maxRect;
if (newRes < origRes)
{
retRect.size.width = inRect.size.width * maxRect.size.height / inRect.size.height;
retRect.origin.x = roundf((maxRect.size.width - retRect.size.width) / 2);
}
else
{
retRect.size.height = inRect.size.height * maxRect.size.width / inRect.size.width;
retRect.origin.y = roundf((maxRect.size.height - retRect.size.height) / 2);
}
return retRect;
}
in xCode 13.4.1, configure style to default and state config to default
For Xamarin.iOS (C#):
myButton.VerticalAlignment = UIControlContentVerticalAlignment.Fill;
myButton.HorizontalAlignment = UIControlContentHorizontalAlignment.Fill;
myButton.ImageView.ContentMode = UIViewContentMode.ScaleAspectFit;
You just need to set content mode of UIButton imageview for three events. -
[cell.button setImage:[UIImage imageWithData:data] forState:UIControlStateNormal];
[cell.button setImage:[UIImage imageWithData:data] forState:UIControlStateHighlighted];
[cell.imgIcon setImage:[UIImage imageWithData:data] forState:UIControlStateSelected];
We have code for three event bcoz while highlighting or selecting if button size is SQUARE and image size is rectangle then it will show square image at the time of highlighting or selecting.
I am sure it will work for you.

Resources