UIButton contentVerticalAlignment doesn't center button image - ios

I created a UIButton programmatically and set its image, but the image just won't center vertically, it's always rendered at the bottom of the button.
Here is my code:
CGFloat logoutButtonSize = self.profileItem.detailView.frame.size.height;
CGFloat logoutButtonX = self.profileItem.detailView.frame.size.width - logoutButtonSize - 8;
CGRect logoutButtonFrame = CGRectMake(logoutButtonX, 0, logoutButtonSize, logoutButtonSize);
UIButton *logoutButton = [[UIButton alloc] initWithFrame:logoutButtonFrame];
[logoutButton setImage:[UIImage imageNamed:#"logout.png"] forState:UIControlStateNormal];
logoutButton.imageView.contentMode = UIViewContentModeCenter;
logoutButton.contentMode = UIViewContentModeCenter;
[logoutButton addTarget:self
action:#selector(confirmLogout)
forControlEvents:UIControlEventTouchUpInside];
logoutButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
logoutButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
logoutButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
After setting a distinct background color for the imageView of the button I can see that it's still aligned to the bottom:
(blue = button, red = image view)
Why is it not working?

Based on your posted image, it looks like the Button itself is being clipped at the bottom, as opposed to the image not being centered vertically.
Your code:
CGRect logoutButtonFrame = CGRectMake(logoutButtonX, 0, logoutButtonSize, logoutButtonSize);
says the Button (blue rectangle) should be square. Yet in the image you posted, the blue rectangle is 120 x 88.
The bottom portion of your button is not being displayed, so it looks like your image is not centered.
By the way, you shouldn't need much of the code you are using:
// define the frame size
CGFloat logoutButtonSize = self.profileItem.detailView.frame.size.height;
CGFloat logoutButtonX = self.profileItem.detailView.frame.size.width - logoutButtonSize - 8;
CGRect logoutButtonFrame = CGRectMake(logoutButtonX, 0, logoutButtonSize, logoutButtonSize);
// instantiate the UIButton
UIButton *logoutButton = [[UIButton alloc] initWithFrame:logoutButtonFrame];
// set the image
[logoutButton setImage:[UIImage imageNamed:#"logout.png"] forState:UIControlStateNormal];
// add the button action target
[logoutButton addTarget:self
action:#selector(confirmLogout)
forControlEvents:UIControlEventTouchUpInside];
// set the resizing mask properties
logoutButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
// shouldn't need any of the following
//logoutButton.imageView.contentMode = UIViewContentModeCenter;
//logoutButton.contentMode = UIViewContentModeCenter;
//logoutButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
//logoutButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;

Point 1
AFAIK, UIControlContentVerticalAlignmentCenter & contentHorizontalAlignment is for text alignment and not for image....
Point 2
UIButton *logoutButton = [[UIButton alloc] initWithFrame:logoutButtonFrame]; will create basic button (like < iOS 6) opposed to Custom button. Below is how you should have button programmatically.
UIButton * logoutButton = [UIButton buttonWithType:UIButtonTypeCustom];
[logoutButton setBackgroundImage:[UIImage imageNamed:#"logout.png"] forControlEvents:UIControlEventTouchUpInside];
[logoutButton addTarget:self action:#selector(confirmLogout) forControlEvents:UIControlEventTouchUpInside];
[logoutButton setTitle:#"" forState:UIControlStateNormal];
logoutButton.frame = CGRectMake(logoutButtonX, 0, logoutButtonSize, logoutButtonSize);
[self.view addSubview: logoutButton];
Now for image to adjust,
continueButton.imageView.contentMode = UIViewContentModeScaleAspectFit;
You are done...
And last
Your code is not working because your UIButton is not Custom button.

Related

iOS: UIButton draw circle border in iOS

I need to draw a circle like border outside UIButton. Below is the attach image and code. I also need to show text below button. Following code will add image and text beneath that. But how do I have layer.
UIButton *imageButton = [UIButton buttonWithType:UIButtonTypeCustom];
[imageButton setBackgroundImage:image forState:UIControlStateNormal];
imageButton.translatesAutoresizingMaskIntoConstraints = NO;
imageButton.backgroundColor = [UIColor clearColor];
[imageButton setTitle:title forState:UIControlStateNormal];
imageButton.titleLabel.textAlignment = NSTextAlignmentCenter;
imageButton.titleLabel.font = [UIFont fontWithName:#"OpenSans" size:fon];
[imageButton setTitleEdgeInsets:UIEdgeInsetsMake(95, 0.0f, 0.0f, 0.0f)];
[imageButton setTitleColor:[UIColor iconTextColor] forState:UIControlStateNormal];
[imageButton addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
set the button width and height ex : width =100 and height = 100, should be same if you want a round then,
imageButton.layer.cornerRadius = 50 // this value should be half from width or height (width = height)
imageButton.layer.masksToBounds = YES
//if you want border with above
imageButton.layer.borderWidth = 1;
imageButton.layer.borderColor = [[UIColor blackColor] CGColor];
You can do something like this.
borderView = UIView()
yourButton = UIButton()
borderView.frame.size.width = yourButton.frame.size.width + 1
borderView.layer.cornerRadius = borderView.frame.size.width/2
borderView.clipToBounds = true
borderView.backgroundColor = UIColor.clearColor()
borderView.layer.borderWidth = 1
borderView.layer.borderColor = UIColor.blueColor()

How to make 3 clickable area on a button in Objective-C

I'm new in objective-C and I've create a project that use a button to change some elements from my view. I would like that depending on what part of the button I click, it displays different elements than previous.
For exemple when I click on the left area from button a red circle appears and when I click in the middle, it's the blue circle that appears and in the right area it's a green circle.
I tried searching on google and stackoverflow but I have trouble understanding how the selector used in this case. Could someone help me?
PS: Sorry for the mistakes, my English is not very good
I help you.
First you need the create the small custom view programmatically or through the xib or storyboard
UIView *viewButton = [[UIView alloc] initWithFrame: CGRectMake ( 100, 100, 300, 300)];
[self.view addSubView:viewButton];
Then Create the 3 buttons inside the viewButton
//First Button
UIButton *buttonLeftRed = [UIButton buttonWithType:UIButtonTypeCustom];
OR
UIButton *buttonLeftRed = [UIButton buttonWithType:UIButtonTypeSystem];
buttonLeftRed.frame = CGRectMake(0, 0, 100, 100);
buttonLeftRed.tag = 1;
[buttonLeftRed setTitle:#"Red" forState:UIControlStateNormal];
[buttonLeftRed addTarget:self
action:#selector(actionPressMeOne:) forControlEvents:UIControlEventTouchUpInside];
[viewButton addSubview:buttonLeftRed];
//Second Button
UIButton *buttonMiddleBlue = [UIButton buttonWithType:UIButtonTypeCustom];
OR
UIButton *buttonMiddleBlue = [UIButton buttonWithType:UIButtonTypeSystem];
buttonMiddleBlue.frame = CGRectMake(100, 0, 100, 100);
buttonMiddleBlue.tag = 2;
[buttonMiddleBlue setTitle:#"Blue" forState:UIControlStateNormal];
[buttonMiddleBlue addTarget:self
action:#selector(actionPressMeSecond:) forControlEvents:UIControlEventTouchUpInside];
[viewButton addSubview:buttonMiddleBlue];
//Third Button
UIButton *buttonRightGreen = [UIButton buttonWithType:UIButtonTypeCustom];
OR
UIButton *buttonRightGreen = [UIButton buttonWithType:UIButtonTypeSystem];
buttonRightGreen.frame = CGRectMake(200, 0, 100, 100);
buttonRightGreen.tag = 3;
[buttonRightGreen setTitle:#"Blue" forState:UIControlStateNormal];
[buttonRightGreen addTarget:self
action:#selector(actionPressMeThird:) forControlEvents:UIControlEventTouchUpInside];
[viewButton addSubview:buttonRightGreen];
If you want to change circle button, you have to import the Quartzcore Framework
#import <QuartzCore/QuartzCore.h>
#pragma mark - UIButton Action Methods
//First
- (void)actionPressMeOne:(UIButton *)sender
{
NSLog(#"Pressed Button Tag is - %#",sender.tag);
UIButton *button = sender;
//Then do whatever you want to do here
//half of the width
button.layer.cornerRadius = button.frame.size.width/2.0f;
button.layer.borderColor=[UIColor redColor].CGColor;
button.layer.borderWidth=2.0f;
button.clipsToBounds = YES;
[button setBackgroundColor:[UIColor redColor]];
}
//Second
- (void)actionPressMeSecond:(UIButton *)sender
{
NSLog(#"Pressed Button Tag is - %#",sender.tag);
UIButton *buttonTwo = sender;
//Then do whatever you want to do here
//half of the width
buttonTwo.layer.cornerRadius = button.frame.size.width/2.0f;
buttonTwo.layer.borderColor=[UIColor blueColor].CGColor;
buttonTwo.layer.borderWidth=2.0f;
buttonTwo.clipsToBounds = YES;
[buttonTwo setBackgroundColor:[UIColor blueColor]];
}
//Third
- (void)actionPressMeThird:(UIButton *)sender
{
NSLog(#"Pressed Button Tag is - %#",sender.tag);
UIButton *buttonThree = sender;
//Then do whatever you want to do here
//half of the width
buttonThree.layer.cornerRadius = button.frame.size.width/2.0f;
buttonThree.layer.borderColor=[UIColor greenColor].CGColor;
buttonThree.layer.borderWidth=2.0f;
buttonThree.clipsToBounds = YES;
[buttonThree setBackgroundColor:[UIColor greenColor]];
}
Thank You:-)

How to identify the subviews (imageviews) addeded to the UIButton in UIAutomation?

I have a UIButton and the button background is set to an image. Added
an image view on the top right corner of the button and I set it
to different image when the button is clicked to show the selection.
When I try to automate this using instruments. I don’t see any subviews
(image views) in the UIAutomator.logElementTree()method does not show
any image views.
How to identify the image views added as subview in the UIButton?
Here is the code.
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(40, 40, 100, 100);
[button addTarget:self action:#selector(didTapButton:) forControlEvents:UIControlEventTouchUpInside];
[button setBackgroundImage:[UIImage imageNamed:#“testImage.png”] forState:UIControlStateNormal];
UIImageView *imageview = [[UIImageView alloc] initWithImage:image];
imageview.frame = CGRectMake(70,30,20,20);
[button addSubview:imageview];
You have to set the accessibilityEnabled & accessibilityLabel.
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(40, 40, 100, 100);
[button addTarget:self action:#selector(didTapButton:) forControlEvents:UIControlEventTouchUpInside];
button.accessibilityEnabled = YES;
button.accessibilityLabel =#"My Button";
[button setBackgroundImage:[UIImage imageNamed:#“testImage.png”] forState:UIControlStateNormal];
UIImageView *imageview = [[UIImageView alloc] initWithImage:image];
imageview.accessibilityEnabled = YES;
imageview.accessibilityLabel = #"My Image";
imageview.frame = CGRectMake(70,30,20,20);
[button addSubview:imageview];
Refer this tutorial
Sweet Angel's answer is enough if you have a single UIImageView subview. However, I would suggest using tags to identify subviews.
imageView.tag = 1346;//Any arbitrary number (I am unsure if there are any limitations to the values you can use, but all 4 digit numbers work fine for me).
Then to get the imageView:
UIImageView* imageView = (UIImageView*)[button viewWithTag:1346];
That's it.
If you want to identify imageview on button taped, try following code :
- (IBAction)didTapButton:(UIButton *)sender
{
for (id view in sender.subviews)
{
if ([view isKindOfClass:[UIImageView class]])
{
NSLog(#"Image view captured.....");
}
}
}

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

UIButton Image + Text IOS

I need a UIButton with image & text. Image should be in the top & text comes under the image both should be clickable.
I see very complicated answers, all of them using code. However, if you are using Interface Builder, there is a very easy way to do this:
Select the button and set a title and an image. Note that if you set the background instead of the image then the image will be resized if it is smaller than the button.
Set the position of both items by changing the edge and insets. You could even control the alignment of both in the Control section.
You could even use the same approach by code, without creating UILabels and UIImages inside as other solutions proposed. Always Keep It Simple!
EDIT: Attached a small example having the 3 things set (title, image and background) with correct insets
I think you are looking for this solution for your problem:
UIButton *_button = [UIButton buttonWithType:UIButtonTypeCustom];
[_button setFrame:CGRectMake(0.f, 0.f, 128.f, 128.f)]; // SET the values for your wishes
[_button setCenter:CGPointMake(128.f, 128.f)]; // SET the values for your wishes
[_button setClipsToBounds:false];
[_button setBackgroundImage:[UIImage imageNamed:#"jquery-mobile-icon.png"] forState:UIControlStateNormal]; // SET the image name for your wishes
[_button setTitle:#"Button" forState:UIControlStateNormal];
[_button.titleLabel setFont:[UIFont systemFontOfSize:24.f]];
[_button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; // SET the colour for your wishes
[_button setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted]; // SET the colour for your wishes
[_button setTitleEdgeInsets:UIEdgeInsetsMake(0.f, 0.f, -110.f, 0.f)]; // SET the values for your wishes
[_button addTarget:self action:#selector(buttonTouchedUpInside:) forControlEvents:UIControlEventTouchUpInside]; // you can ADD the action to the button as well like
...the rest of the customisation of the button is your duty now, and don't forget to add the button to your view.
UPDATE #1 and UPDATE #2
or, if you don't need a dynamic button you could add your button to your view in the Interface Builder and you could set the same values at there as well. it is pretty same, but here is this version as well in one simple picture.
you can also see the final result in the Interface Builder as it is on the screenshot.
Xcode-9 and Xcode-10 Apple done few changes regarding Edge Inset now, you can change it under size-inspector.
Please follow below steps:
Step-1:
Input text and select image which you want to show:
Step-2:
Select button control as per your requirement as shown in below image:
Step-3:
Now go-to size inspector and add value as per your requirement:
swift version:
var button = UIButton()
newGameButton.setTitle("Новая игра", for: .normal)
newGameButton.setImage(UIImage(named: "energi"), for: .normal)
newGameButton.backgroundColor = .blue
newGameButton.imageEdgeInsets.left = -50
In my case, I wanted to add UIImage to the right and UILabel to the left. Maybe I can achieve that by writing code (like the above mentioned), but I prefer not to write code and get it done by using the storyboard as much as possible. So this is how did it:
First, write down something in your label box and select an image that you want to show:
And that will create a button looking like this:
Next, look for Semantic and select Force Right-to-Left (If you don't specify anything, then it will show the image to the left and label to the right like the above image):
Finally, you'll see UIImage to the right and UILabel to the left:
To add space between a label and an image, go to the Size inspector and change those values depending on your requirement:
That's it!
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.imageView.image = [UIImage imageNamed:#"your image name here"];
button.titleLabel.text = #"your text here";
but following code will show label above and image in background
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.background.image = [UIImage imageNamed:#"your image name here"];
button.titleLabel.text = #"your text here";
There is no need to use label and button in same control because UIButton has UILabel and UIimageview properties.
Use this code:
UIButton *sampleButton = [UIButton buttonWithType:UIButtonTypeCustom];
[sampleButton setFrame:CGRectMake(0, 10, 200, 52)];
[sampleButton setTitle:#"Button Title" forState:UIControlStateNormal];
[sampleButton setFont:[UIFont boldSystemFontOfSize:20]];
[sampleButton setBackgroundImage:[[UIImage imageNamed:#"redButton.png"]
stretchableImageWithLeftCapWidth:10.0 topCapHeight:0.0] forState:UIControlStateNormal];
[sampleButton addTarget:self action:#selector(buttonPressed)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:sampleButton]
You should create custom imageview for image and custom label for text and you add to your button as subviews. That's it.
UIButton *yourButton = [UIButton buttonWithType:UIButtonTypeCustom];
yourButton.backgroundColor = [UIColor greenColor];
yourButton.frame = CGRectMake(140, 40, 175, 30);
[yourButton addTarget:self action:#selector(yourButtonSelected:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:yourButton];
UIImageView *imageView1 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, yourButton.frame.size.width, yourButton.frame.size.height/2)];
imageView1.image =[UIImage imageNamed:#"images.jpg"];
[yourButton addSubview:imageView1];
UILabel *label=[[UILabel alloc] initWithFrame:CGRectMake(0, yourButton.frame.size.height/2, yourButton.frame.size.width, yourButton.frame.size.height/2)];
label.backgroundColor = [UIColor greenColor];
label.textAlignment= UITextAlignmentCenter;
label.text = #"ButtonTitle";
[yourButton addSubview:label];
For testing purpose, use yourButtonSelected: method
-(void)yourButtonSelected:(id)sender{
NSLog(#"Your Button Selected");
}
I think it will be helpful to you.
Use this code:
UIButton *button=[UIButton buttonWithType:UIButtonTypeRoundedRect];
button.imageView.frame=CGRectMake(0.0f, 0.0f, 50.0f, 44.0f);///You can replace it with your own dimensions.
UILabel *label=[[UILabel alloc] initWithFrame:CGRectMake(0.0f, 35.0f, 50.0f, 44.0f)];///You can replace it with your own dimensions.
[button addSubview:label];
I encountered the same problem, and I fix it by creating a new subclass of UIButton and overriding the layoutSubviews: method as below :
-(void)layoutSubviews {
[super layoutSubviews];
// Center image
CGPoint center = self.imageView.center;
center.x = self.frame.size.width/2;
center.y = self.imageView.frame.size.height/2;
self.imageView.center = center;
//Center text
CGRect newFrame = [self titleLabel].frame;
newFrame.origin.x = 0;
newFrame.origin.y = self.imageView.frame.size.height + 5;
newFrame.size.width = self.frame.size.width;
self.titleLabel.frame = newFrame;
self.titleLabel.textAlignment = UITextAlignmentCenter;
}
I think that the Angel García Olloqui's answer is another good solution, if you place all of them manually with interface builder but I'll keep my solution since I don't have to modify the content insets for each of my button.
Make UIImageView and UILabel, and set image and text to both of this....then Place a custom button over imageView and Label....
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"search.png"]];
imageView.frame = CGRectMake(x, y, imageView.frame.size.width, imageView.frame.size.height);
[self.view addSubview:imageView];
UILabel *yourLabel = [[UILabel alloc] initWithFrame:CGRectMake(x, y,a,b)];
yourLabel.text = #"raj";
[self.view addSubview:yourLabel];
UIButton * yourBtn=[UIButton buttonWithType:UIButtonTypeCustom];
[yourBtn setFrame:CGRectMake(x, y,c,d)];
[yourBtn addTarget:self action:#selector(#"Your Action") forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:yourBtn];
It's really simple,just add image to background of you button and give text to titlelabel of button for uicontrolstatenormal.
That's it.
[btn setBackgroundImage:[UIImage imageNamed:#"img.png"] forState:UIControlStateNormal];
[btn setContentVerticalAlignment:UIControlContentVerticalAlignmentBottom];
[btn setTitle:#"Click Me" forState:UIControlStateNormal];

Resources