UIButton titleLabel text bottom to its frame - ios

How can i display the UIButton titleLabel text to bottom of its frame. Currently i am using the UIEdge top margin and setting the negative UIButton image width, result is not as expected. i also want to place the image center to its frame.
`
let leftButton: UIButton = {
let button = UIButton()
button.layer.borderWidth = 2
button.layer.borderColor = UIColor.ublGray1().cgColor
button.setImage(UIImage.init(named: leftButtonImage)?.withRenderingMode(.alwaysTemplate), for: .normal)
button.tintColor = UIColor.cerulean()
button.layer.masksToBounds = false
button.layer.cornerRadius = 37
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle(leftButtonTitle, for: .normal)
button.titleEdgeInsets = UIEdgeInsets(top: 110, left: -26, bottom: 0, right: 0)[![enter image description here][1]][1]
button.imageEdgeInsets = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 0)
button.setTitleColor(UIColor.charcoalGrey(), for: .normal)
button.titleLabel?.font = UIFont.aspiraMedium(size: 16)
return button
}()
`

You can try something like this.

How about setting "Title Insets" - bottom - to a negative number? It works.
But if you want it to stick to the bottom of the frame, it won't work, so... how about this:
bt.titleEdgeInsets.top = (bt.imageView?.safeAreaInsets.bottom)!
or bt.titleEdgeInsets.top = (bt.imageView?.alignmentRectInsets.bottom)!

Related

Why my UIButton's title is truncated in the middle while using titleEdgeInsets?

Here is my UIButton defined like this:
private var continueButton: AttributedButton = {
let button = AttributedButton()
button.backgroundColor = .systemGreen
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 18)
button.titleEdgeInsets = UIEdgeInsets(top: 6, left: 20, bottom: 6, right: 20)
button.setTitle("game.continue".localized.uppercased(), for: .normal)
button.setTitleColor(.white, for: .normal)
button.cornerRadius = 10
return button
}()
and it looks like this:
Use contentEdgeInsets property instead of titleEdgeInsets

How to get Inset Buttons like that of iOS Maps app modal?

Swift 4.2 implemented views programmatically only
I have created a stack view and put four buttons in it but they are just simple buttons without any gray background.
I want to achieve the exact four buttons in my stackview equally centered as like as -
button.contentEdgeInset //Not working
This is what I tried -
let feedbackButton:UIButton = {
let origImage = UIImage(named: "feedback")
let tintedImage = origImage?.withRenderingMode(.alwaysTemplate)
let button = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 50))
button.translatesAutoresizingMaskIntoConstraints = false
button.setBackgroundImage(tintedImage, for: UIControl.State.normal)
button.tintColor = .systemPinkColor
button.layer.cornerRadius = 7
button.backgroundColor = UIColor.lightGray.withAlphaComponent(0.5)
button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 40, bottom: 0, right: 40)
// button.imageEdgeInsets = UIEdgeInsets(top: 0, left: 50, bottom: 0, right: 50)
// button.titleEdgeInsets = UIEdgeInsets(top: 0, left: 50, bottom: 0, right: 50)
button.clipsToBounds = true
button.addTarget(self, action: #selector(feedbackFaculty), for: .touchUpInside)
return button
}()
Output -
The button's image gets stretched along with insets. button.imageInsets and button.titleInsets not working.
Help me out. Thanks!
The background image doesn't follow the content insets. So this line:
button.setBackgroundImage(tintedImage, for: UIControl.State.normal)
needs to be changed to:
button.setImage(tintedImage, for: .normal)
Also, here's a couple things to note (per Apple's UIButton documentation):
Supply a title string or image; size the button appropriately for your content.
Which implies that you cannot set an image and title at the same time, this might be why you're noticing titleInset and imageInset not playing nicely.
However, if you just set appropriate constraints for the buttons and set insets for the title OR the image you should be able to get the look you want. Also make sure your stack view is configured to use equal spacing for it's distribution.
The imageInset for each button in the image below is (20, 20, 20, 20).

Swift: Radio button into StackView are not displayed properly

I created a list of radio button in a stackView, but I do not understand why they are displayed wrong, they are not properly aligned
I want all my buttons to be correctly aligned on the left as I can solve this problem thank you!
Here is a part of the code:
var buttons = [UIButton]()
var titles = ["Lasy", "What I've been told", "I'm do into it", "Close the best i can", "Hard core"]
func setupUI() {
for title in titles {
// create button
let button = UIButton(type: .custom)
button.setTitleColor(.black, for: .normal)
button.setTitle(title, for: .normal)
button.setImage(UIImage(named: "uncheck.png")!, for: .normal)
// if the selected button cannot be reclick again, you can use .Disabled state
button.setImage(UIImage(named: "check.png")!, for: .selected)
button.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 35)
button.addTarget(self, action: #selector(radioButtonAction), for: .touchUpInside)
buttons.append(button)
}
for button in buttons {
addArrangedSubview(button)
}
setupUserChoice()
}
func setupUserChoice(){
if titles.contains(value) {
let valueIndex = titles.index(of: value)
radioButtonAction(sender: buttons[valueIndex!])
}
}
func setStackView() {
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.distribution = .fill
stackView.spacing = 16.0
stackView.alignment = .leading
}
The problem is with the way you are trying to set the imageEdgeInsets. It is only adjusting the image position, not increasing the size of the button accordingly. For increasing the size of the button, you need to set contentEdgeInsets. But you also need to adjust the title position according to the change in image's position. You can use titleEdgeInsets for that.
So remove you code button.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 35) and replace it with :-
let leftPadding_beforeImage: CGFloat = 35
let gapBetweenImageAndTitle: CGFloat = 8
let rightPadding_afterTitle: CGFloat = 16
button.imageEdgeInsets = UIEdgeInsetsMake(0, leftPadding_beforeImage, 0, 0)
button.titleEdgeInsets = UIEdgeInsetsMake(0, (leftPadding_beforeImage+gapBetweenImageAndTitle), 0, -(leftPadding_beforeImage+gapBetweenImageAndTitle))
button.contentEdgeInsets = UIEdgeInsetsMake(0, 0, 0, (leftPadding_beforeImage+gapBetweenImageAndTitle+rightPadding_afterTitle))
I hope the variable names are self-explanatory. If you want to know more about UIButton edgeInsets, I suggest you reading this fantastic answer.
Set the frame of each button, because UIStackViews use intrinsic content size. for example :
button.frame = CGRect(x: 0, y: 0, width: 100, height: 20)

UIButton: superimpose a title on top of an image programmatically

How do I superimpose a button title on top of a button image programmatically and position them both to be dead center in the button frame overlapping each other?
let button = UIButton()
button.setImage(coolpic, for .normal)
button.contentMode = .center
button.setTitle("tap me", for: .normal)
// a bunch of constraints and styling that define the frame
Do I have to set the image as a background image? Do I need to create a UILabel as the button title and add it as a subview of the button?
Thanks!
You can do this with image insets, but I like to use extensions for things like this - that way I can use them anywhere in my app without subclassing. Here's my code for setting an image position in a UIButton:
extension UIButton {
func setImagePosition(at pos:ButtonImagePosition, withAdjustment adj:CGFloat?) {
let _adj:CGFloat = (adj != nil) ? adj! : 0
let width = frame.size.width
var imgWidth = self.imageView?.frame.size.width
switch pos {
case .center:
self.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
case .right:
imgWidth = imgWidth! - _adj
self.imageEdgeInsets = UIEdgeInsets(top: 0, left: width - imgWidth!, bottom: 0, right: 0)
case .left:
self.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: width + imgWidth!)
}
}
}
enum ButtonImagePosition {
case left
case right
case center
}
Then I call it as follows
button.setImagePosition(at: .right, withAdjustment: nil)
You could try:
let button = UIButton()
button.setImage(UIImage(named:"yourImage.png")?, for: .normal)
button.setTitle("MyTitle", for: .normal)
button.titleLabel?.font = button.titleLabel?.font.withSize(15)
button.titleLabel?.textAlignment = .center

How to resize an image inside an UIButton programmatically?

I have this UIButton and an image to fit in.
I don't want that the image take all the space inside the button but just a little part of it right in the center, but if I resize the button it will resize the image too.
How can I do that, is there an option to set whatever dimension I want independently from the size of the UIButton?
Thanks!
This can be done through code in the following way:
let imageSize:CGSize = CGSize(width: 20, height: 20)
let button:UIButton = UIButton(type: UIButton.ButtonType.custom)
button.frame = CGRect(x: 200, y: 200, width: 60, height: 60)
button.backgroundColor = UIColor.yellow
button.setImage(UIImage(named: "chat.png"), for: UIControl.State.normal)
// The below line will give you what you want
button.imageEdgeInsets = UIEdgeInsets(
top: (button.frame.size.height - imageSize.height) / 2,
left: (button.frame.size.width - imageSize.width) / 2,
bottom: (button.frame.size.height - imageSize.height) / 2,
right: (button.frame.size.width - imageSize.width) / 2)
self.view.addSubview(button)
This way, you can achieve what you wanted.
I couldn't get the button's imageView to resize until I used contentHorizontalAlignment and contentVerticalAlignment both set to .fill. Then using imageEdgeInsets I repositioned the image.
let button = UIButton()
let image = UIImage(systemName: "bag.badge.plus")
button.setImage(image, for: .normal)
button.contentHorizontalAlignment = .fill
button.contentVerticalAlignment = .fill
button.imageEdgeInsets = UIEdgeInsets(top: 6, left: 6, bottom: 10, right: 10)
Result:
You can experiment with image view insets. Every UIButton has a property imageView.
In Swift 3 you can do this like so:
//let button = UIButton()
button.imageView?.backgroundColor = UIColor.red
button.imageEdgeInsets = UIEdgeInsetsMake(10, 10, 10, 10)
red background is just so you know what is changing
I would do it this way:
A UIButton is just a UIView. You can simply add a UIImageView with a set image and call addSubview on the UIButton.
Taking into account what KVISH said before i have implemented this and it worked as expected. I posted this because Houman asked for an example.
//grab the image using the name of the pic
var image = UIImage(named: "picture")
//set the size for the image
image = image?.resize(toWidth: 18)
image = image?.resize(toHeight: 18)
//set the image to the button
buttonName.setImage(image, for: UIControlState.normal)
//adjust the position
buttonName.imageEdgeInsets = UIEdgeInsetsMake(8,16,9,0)
As of iOS 13, when using SF Symbols, I prefer this:
let button = UIButton()
let font = UIFont.systemFont(ofSize: 30) // <- make it larger, smaller, whatever you want.
let config = UIImage.SymbolConfiguration(font: font)
let image = UIImage(systemName: "bag.badge.plus", withConfiguration: config)
button.setImage(image, for: .normal)
These can be achieved by adding imageEdgeInsets to a UIButton.
In swift4.2
button.imageEdgeInsets = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)

Resources