No resizing, but positioning when setting backgroundImage of UIButton - ios

I want the button to basically overlap a certain part of the original picture and crop the rest instead of squishing the picture into the button. I can't seem to find a UIContentMode to achieve this.

Try this:
You can have a UIImage after some CGRect inside any UIViews. Just make a CGRect with the part of the UIImageView that contains your original UIImage, and execute the code below:
CGRect newImageFrame = CGRectMake(...); //fill this rect according to the crop area of the imageView
UIGraphicsBeginImageContextWithOptions(newImageFrame, YES, 0);
[editingCell.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Now the newImage will hold the image that you will use as background of your button.
Example:
Assuming your UIImageView has the frame (50,50, 100, 200), you can crop a similar result of your image with something like this: newImageFrame = CGRectMake(50, 130, 100, 40).
Please, let me know if worked or not.

please try this code:
CGRect frame = CGRectMake(10, y, 280, 40);
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = frame;
button.tag=i;
[button setTitle:(NSString *)#"new button" forState:(UIControlState)UIControlStateNormal];
[button addTarget:self action:#selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
[button setBackgroundImage:[UIImage imageNamed:#"temp.png"] forState:UIControlStateNormal];
[self.view addSubview:button];
i have checked it out.
hope this will help you.

Related

iOS change UIButton frame to it's image frame weird error

I have a strange error when trying to change UIButton's frame.
I am trying to do the following:
UIButton* btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
UIImage *image = [UIImage imageNamed:imageName];
btn.frame = CGRectMake(0, 0, image.size.width, image.size.height);
[btn setImage:image forState:UIControlStateNormal];
and I an image editor I see that image size is 35x37, but image.size.width / height gives me 16.
What am I doing wrong?
PS: If I double the image.size.width, then the button's frame seems ok. I thought that both image size and UIView frame are in points.

UIButton changes image created in code when in highlighted state

I have two buttons. They both have the same image except the fact that one of the images is flipped. I don't want to have an excess image in the bundle of my app if it's possible to create image programmatically so i create my buttons like this:
UIImage *forwardImage = [UIImage imageNamed:rewind_btn_img];
UIImage *rewindImage = [UIImage imageWithCGImage:forwardImage.CGImage
scale:forwardImage.scale
orientation:UIImageOrientationUpMirrored];
NSArray *images = #[rewindImage, forwardImage];
for (int i = 0; i < 2; i++)
{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *image = images[i];
btn.frame = CGRectMake(0.f, 0.f, image.size.width, image.size.height);
btn.center = CGPointMake(self.playButton.center.x + (i == 0 ? - 80.f : 80.f) * TGScaleMultiplier, self.playButton.center.y);
btn.tag = i + 1;
[btn setBackgroundImage:image forState:UIControlStateNormal];
[btn addTarget:self action:#selector(rewindButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
The problem is that when i press the button whose image is rewindImage it shows the original image, flipped to the other side. Am i doing something incorrectly here? Is there any workaround?
Not sure exactly why that UIImage:imageWithCGImage is flaky but I tried another method for mirroring the image and when applied to the button it works great. So get rid of the UIImage:imageWithCGImage line and use this:
UIImage *rewindImageBase = [UIImage imageNamed:rewind_btn_img];
UIGraphicsBeginImageContext(rewindImageBase.size);
CGContextRef current_context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(current_context, rewindImageBase.size.width, 0);
CGContextScaleCTM(current_context, -1.0, 1.0);
[rewindImageBase drawInRect:CGRectMake(0, 0, rewindImageBase.size.width, rewindImageBase.size.height)];
UIImage *rewindImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
That should do it.
if it initially looks right, but changes when you press it, Try setting the image for all button states, or at least for the normal state and the selected state.
[btn setBackgroundImage:image forState:UIControlStateNormal];
[btn setBackgroundImage:image forState:UIControlStateSelected];
you could also try setting the showsTouchWhenHighlited but the first way should work
[btn setShowsTouchWhenHighlighted:NO];
EDIT: try also setting the highlighted state, this works for me
[btn setBackgroundImage:image forState:UIControlStateHighlighted];

Is it possible to have a UIButton comprised of text, but at the end has an image?

For example, is a button like this achievable?
I've seen questions like this where they go over how to put it before, which is indeed quite easy, but I'm not totally sure how to append it to the end of the text on the button when the text can be anything really. Conceptually, it would be something like having text, and then a UIButton say 10pt to the right of it.
Would the best way to do this simply be a UIView with a UILabel and a UIImageView inside it, with a tap gesture recognizer attached?
A quick sample :
- (void)viewDidLoad
{
[super viewDidLoad];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *img = [UIImage imageNamed:#"Arrow.png"];
[button setTitle:#"A Button" forState:UIControlStateNormal];
[button setImage:img forState:UIControlStateNormal];
[button sizeToFit];
CGRect imageRect = [button imageRectForContentRect:button.bounds];
CGRect titleRect = [button titleRectForContentRect:button.bounds];
UIEdgeInsets imageInset = UIEdgeInsetsZero;
UIEdgeInsets titleInset = UIEdgeInsetsZero;
titleInset.left = -2 * imageRect.size.width;
imageInset.left = titleRect.size.width;
button.titleEdgeInsets = titleInset;
button.imageEdgeInsets = imageInset;
[self.view addSubview:button];
CGFloat prevHeight = button.frame.size.height;
UIButton *anotherButton = [UIButton buttonWithType:UIButtonTypeCustom];
[anotherButton setTitle:#"Another Button" forState:UIControlStateNormal];
[anotherButton setImage:img forState:UIControlStateNormal];
[anotherButton sizeToFit];
imageRect = [anotherButton imageRectForContentRect:anotherButton.bounds];
titleRect = [anotherButton titleRectForContentRect:anotherButton.bounds];
imageInset = UIEdgeInsetsZero;
titleInset = UIEdgeInsetsZero;
titleInset.left = -2 * imageRect.size.width;
imageInset.left = titleRect.size.width;
anotherButton.titleEdgeInsets = titleInset;
anotherButton.imageEdgeInsets = imageInset;
CGRect frame = anotherButton.frame;
frame.origin.y += prevHeight + 4;
[anotherButton setFrame:frame];
[self.view addSubview:anotherButton];
}
You just need to adjust buttons size and insets, if you want to add space between title and image.
You could also just have a UILabel and a UIImageView and an invisible UIButton on top of them.
Or as you said, a UIView with you custom content and a gesture recognizer. In that case however it might be more difficult to achieve the same behavior as a regular button (no highlighting, you can't move your finger before letting go, etc.)
Also, UIButton is a subclass of UIView. This means, you can easily add additional subviews (such as an UIImageView) inside the UIButton.
You could use an empty UIButton and put a UILabel and a UIImageView into it. And use Auto Layout to position them inside the button.
Just create UIButton
UIImage *arrowDownImage = [UIImage imageNamed:#"arrowDown.png"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:arrowDownImage forState:UIControlStateNormal];
[button setTitle:#"Test" forState:UIControlStateNormal];
// set image and title Inset
[button setImageEdgeInsets:UIEdgeInsetsMake(<#CGFloat top#>, <#CGFloat left#>, <#CGFloat bottom#>, <#CGFloat right#>)];
[button setTitleEdgeInsets:UIEdgeInsetsMake(<#CGFloat top#>, <#CGFloat left#>, <#CGFloat bottom#>, <#CGFloat right#>)];
Play with Insets and this will give you exactly what you need.
This is IB example of button, but you can do the same programmatically.
And this is ImageInset
Title Inset

Set background image of UIBarButtonItem programmatically changes its size

I've been able to have a custom UIBarButtonItem with an embedded uibutton through story board. It's the map button.
see parameters on this screenshot, I had to use background property instead of Image.
But when I tried to customize some uibarbuttons programmatically, then the buttons get smaller. I had the same result with the map button when I was using Image property.
Here the code i'm writing for the back button,
UIImage *backButtonImage = [[UIImage imageNamed:#"Retour.png"]resizableImageWithCapInsets:UIEdgeInsetsMake(21, 21, 21, 21)] ;
backButtonImage = [backButtonImage stretchableImageWithLeftCapWidth:0 topCapHeight:0];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0, 0, backButtonImage.size.width, backButtonImage.size.height);
[button setBackgroundImage:backButtonImage forState:UIControlStateNormal];
[button setBackgroundImage:backButtonImage forState:UIControlStateHighlighted];
[button addTarget:self action:#selector(back) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *backBarButton = [[UIBarButtonItem alloc] initWithCustomView:button] ;
self.navigationItem.leftBarButtonItem = backBarButton;
I tried with or without resizableImageWithCapInsets, stretchableImageWithLeftCapWidth with the same result below (the back button should have the same size as the map button)
I tried also iOS 5 setBackButtonBackgroundImage methods but the button was not customized at all.
If you don't find an answer to your problem, I can suggest you this function :
- (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize
{
//UIGraphicsBeginImageContext(newSize);
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
It returns an image scaled to the specified size.
So you can resize your image at the desired size and then set it as a background image.
Well the problem was that I had overwritten the Retour#2x.png for retina display with Retour.png -__-'

UIButton with resizable Image

Ok guys,
i know i am doing something wrong, but i cannot figure that out. here is the code that will
put the resizable image for the normal button state.
self.loginButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.loginButton.frame = CGRectMake(0.0, 44.0, 314, 44);
UIImage *image = [[UIImage imageNamed:#"loginbutton_image"] resizableImageWithCapInsets:UIEdgeInsetsMake(0.0,10.0,0.0,10.0)];
[self.loginButton setImage:image forState:UIControlStateNormal];
[self addSubview:self.loginButton];
Here is the image
either the image asset is wrong or the code.
the image is of 21 px width.
the cap inset of 10 & 10 on left right leaves 1Px to resize.
does any one spot what i am doing wrong.
thanks all for stopping by
Arun
you should do it this way:
self.loginButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.loginButton.frame = CGRectMake(0.0, 44.0, 314, 44);
UIImage *image = [[UIImage imageNamed:#"loginbutton_image"] resizableImageWithCapInsets:UIEdgeInsetsMake(0.0,10.0,0.0,10.0)];
[self.loginButton setBackgroundImage:image forState:UIControlStateNormal];
[self.view addSubview:self.loginButton];
This way you are setting the background image property of the button. The background image is already attached to the button view, so no need to addSubview.
try
self.loginButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.loginButton.frame = CGRectMake(0.0, 44.0, 314, 44);
UIImage *image = [[UIImage imageNamed:#"loginbutton_image"] stretchableImageWithLeftCapWidth:10 topCapHeight:10]; //assuming the height is 44
[self.loginButton setImage:image forState:UIControlStateNormal];
[self addSubview:self.loginButton];

Resources