Home > Back-end >  How to set image to right edge corner in UIButton in/after iOS 15? (Swift)
How to set image to right edge corner in UIButton in/after iOS 15? (Swift)

Time:10-20

I'm facing an issue in iOS 15 where when setting the image to the right corner doesn't work while before iOS 15 it is working properly.
What I want to achieve: ExpectedResult

What I'm achieving: ActualResult

Here is the complete code which I'm using for iOS 15:

import UIKit

class ViewController: UIViewController { 
 
    override func viewDidLoad() {
        super.viewDidLoad()
        let btnDropdown = getDropdownButton()
        btnDropdown.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(btnDropdown)
        NSLayoutConstraint.activate([
            btnDropdown.heightAnchor.constraint(equalToConstant: 44),
            btnDropdown.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor),
            btnDropdown.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor),
            btnDropdown.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor, constant: 30)
        ])
    }
    
    fileprivate func getDropdownButton() -> UIButton {
        var button: UIButton!
        if #available(iOS 15.0, *),
           let btnConfig = getButtonConfiguration() {
            button = UIButton(configuration: btnConfig)
        } else {
            button = UIButton(type: .custom)
        }
        button.setTitle("Select Tags", for: .normal)
        setupGeneralSettings(for: button)
        return button
    }
    
    fileprivate func setupGeneralSettings(for button: UIButton) {
        button.titleEdgeInsets = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8)
        button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8)
        button.contentHorizontalAlignment = .left
        button.layer.borderWidth = 1
        button.layer.cornerRadius = 8
        button.clipsToBounds = true
        button.backgroundColor = .lightGray.withAlphaComponent(0.3)
        button.titleLabel?.font = UIFont.systemFont(ofSize: 14, weight: .medium)
        button.setTitleColor(UIColor.black, for: .normal)
    }
    
    @available(iOS 15.0, *)
    fileprivate func getButtonConfiguration() -> UIButton.Configuration? {
        var btnConfig = UIButton.Configuration.plain()
        btnConfig.buttonSize = .medium
        btnConfig.titleAlignment = .leading
        btnConfig.imagePlacement = .trailing
        btnConfig.image = UIImage(systemName: "arrowtriangle.down.circle")
        btnConfig.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 8, bottom: 0, trailing: 8)
        btnConfig.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer { incoming in
            var outgoing = incoming
            outgoing.font = UIFont.systemFont(ofSize: 14, weight: .medium)
            return outgoing
        }
        return btnConfig
    }
}

NOTE: When I say iOS 15, I mean that I'm using UIButton.Configuration because as the UIButton's titleEdgeInset, imageEdgeInset & contentEdgeInset is deprecated in iOS 15. Also, I think there is something I'm missing in UIButton.Configuration by which the image will get to the right edge of the button but I'm not sure what it is.

Please let me know if there is any other information that's needed.
Thanks in Advance!

CodePudding user response:

You can add an external image like that:

Under your controller class, declare your objects:

let btnDropdown = UIButton()
let myImageView = UIImageView()

In viewDidLoad (or in a function) set objects attribute and constraints:

    myImageView.image = UIImage(systemName: "arrowtriangle.down.circle")
    myImageView.tintColor = .systemBlue
    myImageView.contentMode = .scaleAspectFit
    myImageView.clipsToBounds = true
    myImageView.translatesAutoresizingMaskIntoConstraints = false
    
    btnDropdown.contentHorizontalAlignment = .left
    btnDropdown.setTitle("Select Tags", for: .normal)
    btnDropdown.layer.borderWidth = 1
    btnDropdown.layer.borderColor = UIColor.black.cgColor // here set your border color
    btnDropdown.layer.cornerRadius = 8
    btnDropdown.clipsToBounds = true
    btnDropdown.setTitleColor(UIColor.black, for: .normal)
    btnDropdown.translatesAutoresizingMaskIntoConstraints = false
    btnDropdown.configuration = UIButton.Configuration.filled()
    btnDropdown.configuration?.background.backgroundColor = .lightGray.withAlphaComponent(0.3)
    btnDropdown.configuration?.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer { incoming in
      var outgoing = incoming
      outgoing.font = UIFont.systemFont(ofSize: 14, weight: .medium)
      return outgoing
     }

    view.addSubview(btnDropdown)
    NSLayoutConstraint.activate([
        btnDropdown.heightAnchor.constraint(equalToConstant: 44),
        btnDropdown.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 20),
        btnDropdown.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -20),
        btnDropdown.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 30)
    ])
    
    view.addSubview(myImageView)
    NSLayoutConstraint.activate([
        myImageView.trailingAnchor.constraint(equalTo: btnDropdown.trailingAnchor, constant: -8),
        myImageView.topAnchor.constraint(equalTo: btnDropdown.topAnchor, constant: 8),
        myImageView.bottomAnchor.constraint(equalTo: btnDropdown.bottomAnchor, constant: -8),
        myImageView.widthAnchor.constraint(equalToConstant: 28) // 28 is the result of difference from 44 (the height of button) and the sum of padding top   padding bottom (8   8): 44 - 16 = 28
    ])

This is the result:

enter image description here

CodePudding user response:

You may be running into issues by mixing some old-style button code with the new .configuration style, however...

Change this line in setupGeneralSettings():

    button.contentHorizontalAlignment = .left

to this:

    button.contentHorizontalAlignment = .fill

and see if you get the desired layout.

  • Related