Text and Image inside UIButton - ios

I am stuck in UIButton. I want to add to UIButton text and then next to text add an image, like this:
I want to center it.
when I type this:
let button = UIButton(type: .custom)
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle("Přidat za: \(priceForCategory)", for: .normal)
button.setImage(UIImage(named: "Coin"), for: .normal)
button.imageEdgeInsets = UIEdgeInsets(top: 6, left: -100, bottom: 6, right: 6)
button.titleLabel?.textAlignment = .right
button.alignImageRight()
button.imageView?.contentMode = .scaleAspectFit
button.backgroundColor = UIColor.custom.orange
button.addTarget(self, action: #selector(handleAddCategory), for: .touchUpInside)
button.tintColor = .white
button.titleLabel?.font = UIFont(name: ".SFUIText-Bold", size: 20)
It shows me:
My height breaks and still it doesn't work.
button.alignImageRight()
Means
func alignImageRight() {
if UIApplication.shared.userInterfaceLayoutDirection == .leftToRight {
semanticContentAttribute = .forceRightToLeft
}
else {
semanticContentAttribute = .forceLeftToRight
}
}
Thanks for every answer.

Create func for adding UIButton
func addRoundedButton() {
let button = UIButton(type: .custom)
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle("Add for: 100", for: .normal)
button.setImage(UIImage(named: "Coin"), for: .normal)
button.alignImageRight()
//Add this line for rounded corner
button.layer.cornerRadius = 20 // set cornerRadius = height/2
button.backgroundColor = UIColor.orange
button.tintColor = .white
button.titleLabel?.font = UIFont(name: ".SFUIText-Bold", size: 20)
view.addSubview(button)
[button.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -15),
button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
button.heightAnchor.constraint(equalToConstant: 40),
button.widthAnchor.constraint(equalToConstant: 300)].forEach{ $0.isActive = true }
}
Create extension for UIButton (as you already created). but add UIEdgeInsets in extension.
extension UIButton {
func alignImageRight() {
if UIApplication.shared.userInterfaceLayoutDirection == .leftToRight {
semanticContentAttribute = .forceRightToLeft
imageEdgeInsets = UIEdgeInsets(top: 0, left: 15, bottom: 0, right: 0)
} else {
semanticContentAttribute = .forceLeftToRight
imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 15)
}
}
}
Output
TIP
For auto adjust width depend on Text and Image, use this extension

Related

Change UIButton size programmatically in dialog in Swift

I create dialog with custom button UIButton in swift IOS. How can change UIButton size programmatically.
class SuccessMessageView: UIView, UITextFieldDelegate {
private var buttonConfirm : UIButton = {
let button = UIButton()
button.setTitle("Ok", for: .normal)
button.backgroundColor = UIColor(rgb: PreferenceManager.shared.hasDevice() ? purpleColour : orangeColour)
button.setTitleColor(.white, for: .normal)
button.layer.cornerRadius = 10
button.addTarget(self, action: #selector(confirmFunc), for: .touchDown)
button.translatesAutoresizingMaskIntoConstraints = false
button.widthAnchor.constraint(equalToConstant: 140.0).isActive = true
button.frame.size.width = 140
return button
}
}
Could you try this? Just remove the frame-related lines.
private lazy var buttonConfirm : UIButton = {
let button = UIButton()
button.setTitle("Ok", for: .normal)
button.backgroundColor = .red
button.setTitleColor(.white, for: .normal)
button.layer.cornerRadius = 10
button.addTarget(self, action: #selector(confirmFunc), for: .touchUpInside)
button.translatesAutoresizingMaskIntoConstraints = false
button.widthAnchor.constraint(equalToConstant: 200.0).isActive = true
button.heightAnchor.constraint(equalToConstant: 48).isActive = true
return button
}()
fileprivate func Frame() -> CGRect {
var circleFrame = CGRect(x: 0, y: 0, width: 2, height: 2)
return circleFrame
}
I found the solution for set UIButton width and height programatically like that set with constant.
button.anchor(nil, left: nil, bottom: nil, right: nil, topConstant: 0, leftConstant: 0, bottomConstant: 0, rightConstant: 0, widthConstant: 20, heightConstant: 30)
button.anchorCenterXToSuperview()

UIButton titleLabel has padding

UIButton title label has top and bottom padding, I want to remove padding.
Set UIButton content mode did not work.
Here is my code
lazy var button: UIButton = {
let button = UIButton(type: .custom)
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitleColor(ThemeColor.red, for: .normal)
button.setTitle("Push", for: .normal)
button.addTarget(self, action: #selector(buttonDidTap), for: .touchUpInside)
button.backgroundColor = .blue
button.contentHorizontalAlignment = .fill
button.contentVerticalAlignment = .fill
button.contentMode = .scaleAspectFill
return button
}()
and it looks like
How can I remove the padding space!
As Matt pointed out, you can fix this by adjusting the button's contentEdgeInsets
However, one thing I noticed, if you set the contentEdgeInsets to 0 all around:
button.contentEdgeInsets = UIEdgeInsets(top: 0,
left: 0,
bottom: 0,
right: 0)
You still get the the vertical padding for some reason.
I remember seeing an answer which I cannot find now where it suggested to set an extremely small edge inset and this should work:
lazy var button: UIButton = {
let button = UIButton(type: .custom)
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitleColor(.red, for: .normal)
button.setTitle("Push", for: .normal)
button.backgroundColor = .blue
button.contentHorizontalAlignment = .fill
button.contentVerticalAlignment = .fill
button.contentMode = .scaleAspectFill
button.contentEdgeInsets = UIEdgeInsets(top: .leastNormalMagnitude,
left: .leastNormalMagnitude,
bottom: .leastNormalMagnitude,
right: .leastNormalMagnitude)
return button
}()
You can use UIButton.Configuration and then set its contentInsets to .zero
lazy var button: UIButton = {
let button = UIButton(type: .custom)
button.translatesAutoresizingMaskIntoConstraints = false
var configuration = UIButton.Configuration.plain()
configuration.background.backgroundColor = .blue
configuration.background.cornerRadius = 0
configuration.baseForegroundColor = .red
configuration.title = "Push"
configuration.contentInsets = .zero
button.configuration = configuration
return button
}()
You can use the button's configuration to get more precise control over its appearance like so:
lazy var myButton: UIButton = {
let newButton = UIButton()
newButton.translatesAutoresizingMaskIntoConstraints = false
newButton.contentMode = .scaleAspectFill
newButton.addTarget(self, action: #selector(buttonDidTap), for: .touchUpInside)
// 'configurationUpdateHandler' property can be used to set appearance depending on its state
newButton.configurationUpdateHandler = { button in
switch button.state { // here i'll just use default so it's the same over all states
default:
button.configuration?.title = "Push"
button.configuration?.baseBackgroundColor = .blue
// remove padding here
button.configuration?.contentInsets.top = 0
button.configuration?.contentInsets.bottom = 0
}
}
return newButton
}()
Of course you don't need to use updateHandler, you can just access the configuration directly and just set it there
button.configuration?.contentInsets.top = 0
button.configuration?.contentInsets.bottom = 0
See if this solves the problem...

Why is space added between UIButtons?

I have the following code
let mostRead = UIButton(frame: CGRect(x: 0, y: tableView.frame.origin.y + tableView.frame.height, width: self.view.bounds.size.width, height: 160))
mostRead.setImage(UIImage.init(named: "mostread"), for: .normal)
mostRead.addTarget(self, action:#selector(self.goToMostRead(sender:)), for: .touchUpInside)
innerView.addSubview(mostRead)
let videoTitles = UIButton(frame: CGRect(x: 0, y: mostRead.frame.maxY, width: self.view.bounds.size.width, height: 160))
videoTitles.setImage(UIImage.init(named: "videotitles"), for: .normal)
videoTitles.addTarget(self, action:#selector(self.goToVideoTitles(sender:)), for: .touchUpInside)
innerView.addSubview(videoTitles)
let audioTitles = UIButton(frame: CGRect(x: 0, y: videoTitles.frame.maxY, width: self.view.bounds.size.width, height: 160))
audioTitles.setImage(UIImage.init(named: "audiotitles"), for: .normal)
audioTitles.addTarget(self, action:#selector(self.goToAudioTitles(sender:)), for: .touchUpInside)
innerView.addSubview(audioTitles)
Space gets added between the UI Buttons. If you notice in the picture, there's a lot of space between each image even though I specified no space between images. Does anyone know why that's happening?
You try to add it with stackView and auto layout like this:
first set your object under your controller class:
let buttonmostRead: UIButton = {
let button = UIButton()
button.backgroundColor = .red
button.setBackgroundImage(UIImage(named: "mostRead"), for: .normal)
button.layer.cornerRadius = 8
button.clipsToBounds = true
return button
}()
let buttonvideoTitles: UIButton = {
let button = UIButton()
button.backgroundColor = .red
button.setBackgroundImage(UIImage(named: "videoTitles"), for: .normal)
button.layer.cornerRadius = 8
button.clipsToBounds = true
return button
}()
let buttonaudiotitles: UIButton = {
let button = UIButton()
button.backgroundColor = .red
button.setBackgroundImage(UIImage(named: "audiotitles"), for: .normal)
button.layer.cornerRadius = 8
button.clipsToBounds = true
return button
}()
after that in viewDiLoad set staclView an constraints:
let stackView = UIStackView(arrangedSubviews: [buttonmostRead, buttonvideoTitles, buttonaudiotitles])
stackView.axis = .vertical
stackView.distribution = .fillEqually
stackView.spacing = 8
stackView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(stackView)
stackView.heightAnchor.constraint(equalToConstant: 466).isActive = true
stackView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -20).isActive = true
stackView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 20).isActive = true
stackView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 0).isActive = true
to set space between button, change stackView spacing...
and this is the result
I put stackView in the center of the view but you can place them wherever you want by changing the constraints...

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

add rightview in UIButton

I am trying to display some text and an image over a button. I am using the code from here
let btnSort = UIButton.buttonWithType(UIButtonType.System) as! UIButton
btnSort.frame = CGRectMake(2, 74, 140, 26)
btnSort.tintColor = UIColor.whiteColor()
btnSort.setImage(UIImage(named:"immgg"), forState: UIControlState.Normal)
btnSort.imageEdgeInsets = UIEdgeInsets(top: 6,left: 100,bottom: 6,right: 14)
btnSort.titleEdgeInsets = UIEdgeInsets(top: 0,left: -30,bottom: 0,right: 34)
btnSort.setTitle("SORT", forState: UIControlState.Normal)
btnSort.layer.borderWidth = 1.0
btnSort.layer.borderColor = UIColor.whiteColor().CGColor
btnSort.addTarget(self, action: Selector("showSortTbl"), forControlEvents: UIControlEvents.TouchUpInside)
self.view.addSubview(btnSort)
I can see the image at the right place, however the text is not appearing. I think titleEdgeInsets is not working.
the code I tried I got the output what the problem U faced.
btnSort.backgroundColor = UIColor.redColor() --> set the background color and check
let btnSort = UIButton(type: UIButtonType.System) as UIButton! //this is Swift2.0 in this place use your code
btnSort.frame = CGRectMake(2, 74, 140, 40)
btnSort.tintColor = UIColor.whiteColor()
btnSort.setImage(UIImage(named:"youtube16x16.png"), forState: UIControlState.Normal)
btnSort.imageEdgeInsets = UIEdgeInsets(top: 6,left: 100,bottom: 6,right: 14)
btnSort.titleEdgeInsets = UIEdgeInsets(top: 0,left: -30,bottom: 0,right: 34)
btnSort.setTitle("SORT", forState: UIControlState.Normal)
btnSort.layer.borderWidth = 1.0
btnSort.backgroundColor = UIColor.redColor() --> set the background color and check
btnSort.layer.borderColor = UIColor.whiteColor().CGColor
btnSort.addTarget(self, action: Selector("showSortTbl"), forControlEvents: UIControlEvents.TouchUpInside)
self.view.addSubview(btnSort)
Swift3
let btnSort = UIButton(type: .system)
btnSort.frame = CGRect(x: 2, y: 74, width: 140, height: 40)
btnSort.tintColor = UIColor.white
btnSort.setImage(UIImage(named:"youtube16x16.png"), for: .normal)
btnSort.imageEdgeInsets = UIEdgeInsets(top: 6,left: 100,bottom: 6,right: 14)
btnSort.titleEdgeInsets = UIEdgeInsets(top: 0,left: -30,bottom: 0,right: 34)
btnSort.setTitle("SORT", for: .normal)
btnSort.layer.borderWidth = 1.0
btnSort.backgroundColor = UIColor.red //--> set the background color and check
btnSort.layer.borderColor = UIColor.white.cgColor
btnSort.addTarget(self, action: #selector(ViewController.showSortTbl), for: UIControlEvents.touchUpInside)
self.view.addSubview(btnSort)
and handle the action as
func showSortTbl() {
// do your stuff here
}
output
Subclass UIButton
Override the layoutSubviews() function
class CustomButton: UIButton {
override func layoutSubviews() {
super.layoutSubviews()
guard imageView != nil else {
return
}
imageEdgeInsets = UIEdgeInsets(top: 5, left: (bounds.width - 25), bottom: 5, right: 5)
titleEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: imageView!.frame.width)
}
}
Add a button to Storyboard
Add custom class to the button
Change button type to System
Set Title and image to the button
Please check below code.
Hope it will work for you.
let teamImage: UIButton = UIButton(frame: CGRect(x: 0, y: 75, width: 100, height: 50))
let imageTest = UIImage(named: "immgg")
teamImage.setTitle("HypnotoadTitle", forState: .Normal)
teamImage.setBackgroundImage(imageTest, forState: .Normal)
self.view.addSubview(teamImage)
Set only background color and display your text :
let btnSort = UIButton(type: UIButtonType.System) as UIButton // Shift 2.0
btnSort.backgroundColor = UIColor.yellowColor()
OR
btnSort.setTitleColor(UIColor.greenColor(), forState: UIControlState.Normal)

Resources