I'm currently trying to add a background image to my navigation bar but the background image itself is not stretching to fill the bounds of the specified space (the pink button should be covering the blue square or atleast getting close to same size).
How do I get the background image to stretch/ fill the space?
How I add the button:
let newsButton = UIButton(type: .custom)
newsButton.translatesAutoresizingMaskIntoConstraints = false
newsButton.backgroundColor = .blue
newsButton.setTitle(NSLocalizedString("News", comment: "News button"), for: .normal)
newsButton.layer.cornerRadius = 7
newsButton.titleLabel?.font = .systemFont(ofSize: 20)
newsButton.addTarget(self, action: #selector(onClick(_:)), for: .touchUpInside)
if let image = UIImage(named: "pink_button") {
newsButton.setBackgroundImage(image, for: .normal)
}
NSLayoutConstraint.activate([
newsButton.widthAnchor.constraint(equalToConstant: 128),
newsButton.heightAnchor.constraint(equalToConstant: 43)
])
navigationItem.titleView = newsButton
CodePudding user response:
Your image has a lot of transparent space around the "red" shape.
If you replace it with this image (I trimmed out the alpha areas):
It will look like this:
As an alternative to using a "stretched image" you could use this custom view (that draws your shape) and embed the button as a subview:
class MyBottomShadowView: UIView {
var radius: CGFloat = 8
var primaryColor: UIColor = .red
var shadowColor: UIColor = .gray
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() {
// background color needs to be .clear
self.backgroundColor = .clear
}
override func draw(_ rect: CGRect) {
super.draw(rect)
var r: CGRect!
var pth: UIBezierPath!
// if rounded rect for "bottom shadow line"
// goes all the way to the top, we'll get
// anti-alias artifacts at the top corners
// so, we'll make it slightly smaller and
// move it down from the top
r = bounds.insetBy(dx: 0, dy: 2).offsetBy(dx: 0, dy: 2)
pth = UIBezierPath(roundedRect: r, cornerRadius: radius)
shadowColor.setFill()
pth.fill()
// "filled" rounded rect should be
// 2-points shorter than height
r = bounds
r.size.height -= 2.0
pth = UIBezierPath(roundedRect: r, cornerRadius: radius)
primaryColor.setFill()
pth.fill()
}
}
Your setup then becomes:
let newsButton = UIButton(type: .custom)
newsButton.translatesAutoresizingMaskIntoConstraints = false
newsButton.setTitleColor(.white, for: .normal)
newsButton.setTitleColor(.lightGray, for: .highlighted)
newsButton.setTitle(NSLocalizedString("News", comment: "News button"), for: .normal)
newsButton.titleLabel?.font = .systemFont(ofSize: 20)
// set button background to clear
newsButton.backgroundColor = .clear
newsButton.addTarget(self, action: #selector(onClick(_:)), for: .touchUpInside)
// create "bottom shadow view"
let shadView = MyBottomShadowView()
// set radius, primary and shadow colors as desired
shadView.radius = 12
shadView.primaryColor = UIColor(red: 1.00, green: 0.25, blue: 0.40, alpha: 1.0)
shadView.shadowColor = UIColor(red: 0.65, green: 0.20, blue: 0.30, alpha: 1.0)
shadView.translatesAutoresizingMaskIntoConstraints = false
shadView.addSubview(newsButton)
NSLayoutConstraint.activate([
shadView.widthAnchor.constraint(equalToConstant: 128),
shadView.heightAnchor.constraint(equalToConstant: 43),
newsButton.topAnchor.constraint(equalTo: shadView.topAnchor),
newsButton.leadingAnchor.constraint(equalTo: shadView.leadingAnchor),
newsButton.trailingAnchor.constraint(equalTo: shadView.trailingAnchor),
newsButton.bottomAnchor.constraint(equalTo: shadView.bottomAnchor),
])
navigationItem.titleView = shadView
And it looks like this: