我对 IOS 开发和 AutoLayout 非常陌生。 我面临使用 Storyboard 对齐 UIbutton 内的图像和文本的问题。我尝试使用 TitleEdgeinset 和 ImageEdge insets 来实现它,将标题(文本)垂直居中放置在图像下方。但问题是我有 3 个类似的按钮,它们是垂直堆叠的(StackView),并且文本是动态设置的,因为我们已经本地化了字符串(包括阿拉伯语 rtl)。 图像和文本根据文本长度移动。有什么方法可以实现使所有带有图像和文本的按钮垂直对齐。此外,如果使用边缘插图,当前无法使用不同的屏幕分辨率。感谢您的帮助。预先感谢。
前几天,我解决了类似的问题,试试这个
private func adjustImageAndTitleOffsetsForButton (button: UIButton) {
let spacing: CGFloat = 6.0
let imageSize = button.imageView!.frame.size
button.titleEdgeInsets = UIEdgeInsetsMake(0, -imageSize.width, -(imageSize.height + spacing), 0)
let titleSize = button.titleLabel!.frame.size
button.imageEdgeInsets = UIEdgeInsetsMake(-(titleSize.height + spacing), 0, 0, -titleSize.width)
}
为每个按钮调用此方法,例如
self.adjustImageAndTitleOffsetsForButton(yourButton)
结合 Ajay 和 Matej 的答案:
import Foundation
import UIKit
class VerticalButton: UIButton {
override func awakeFromNib() {
super.awakeFromNib()
self.contentHorizontalAlignment = .left
}
override func layoutSubviews() {
super.layoutSubviews()
centerButtonImageAndTitle()
}
private func centerButtonImageAndTitle() {
let titleSize = self.titleLabel?.frame.size ?? .zero
let imageSize = self.imageView?.frame.size ?? .zero
let spacing: CGFloat = 6.0
self.imageEdgeInsets = UIEdgeInsets(top: -(titleSize.height + spacing),left: 0, bottom: 0, right: -titleSize.width)
self.titleEdgeInsets = UIEdgeInsets(top: 0, left: -imageSize.width, bottom: -(imageSize.height + spacing), right: 0)
}
}
如果您使用的是 iOS 15.0,您可以使用:
// Create a button
let button = UIButton(type: .custom)
// Configure the button using UIButton.Configuration
var config = UIButton.Configuration.filled()
config.titlePadding = 10
config.imagePlacement = .top // this is whats makes the magic
config.imagePadding = 10
button.configuration = config
我修改了Ajay的答案,因为我的图像没有居中:
func centerButtonImageAndTitle(button: UIButton) {
let spacing: CGFloat = 5
let titleSize = button.titleLabel!.frame.size
let imageSize = button.imageView!.frame.size
button.titleEdgeInsets = UIEdgeInsets(top: 0, left: -imageSize.width, bottom: -(imageSize.height + spacing), right: 0)
button.imageEdgeInsets = UIEdgeInsets(top: -(titleSize.height + spacing), left: -imageSize.width/2, bottom: 0, right: -titleSize.width)
}
这是一个对我有用的解决方案。只需在情节提要中将按钮类设置为
HorizontallyCenteredButton
,并根据您的需要设置标题和图像顶部和底部插图(将图像放置在标题上方),按钮将自动调整水平插图,使图像位于标题上方居中.
class HorizontallyCenteredButton: LocalizedButton {
override func awakeFromNib() {
super.awakeFromNib()
self.contentHorizontalAlignment = .left
}
override func layoutSubviews() {
super.layoutSubviews()
self.centerButtonImageAndTitle()
}
func centerButtonImageAndTitle() {
let size = self.bounds.size
let titleSize = self.titleLabel!.frame.size
let imageSize = self.imageView!.frame.size
self.imageEdgeInsets = UIEdgeInsets(top: self.imageEdgeInsets.top, left: size.width/2 - imageSize.width/2, bottom: self.imageEdgeInsets.bottom, right: 0)
self.titleEdgeInsets = UIEdgeInsets(top: self.titleEdgeInsets.top, left: -imageSize.width + size.width/2 - titleSize.width/2, bottom: self.titleEdgeInsets.bottom, right: 0)
}
}
要垂直对齐所有按钮,首先选择按钮,然后单击故事板右下角标题为“对齐”的按钮,最后在出现的菜单中选择“垂直居中”。这应该可以解决问题。
您可以使用这个自定义类
class VerticalButton: UIButton {
private let stackView = UIStackView()
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setup()
}
private func setup() {
stackView.axis = .vertical
stackView.alignment = .center
stackView.spacing = 5 // Adjust spacing between image and title
addSubview(stackView)
stackView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
stackView.centerXAnchor.constraint(equalTo: centerXAnchor),
stackView.centerYAnchor.constraint(equalTo: centerYAnchor),
stackView.widthAnchor.constraint(equalTo: widthAnchor),
stackView.heightAnchor.constraint(equalTo: heightAnchor)
])
}
override func setImage(_ image: UIImage?, for state: UIControl.State) {
let imageView = UIImageView(image: image)
imageView.contentMode = .scaleAspectFit
stackView.addArrangedSubview(imageView)
}
override func setTitle(_ title: String?, for state: UIControl.State) {
let titleLabel = UILabel()
titleLabel.text = title
titleLabel.textAlignment = .center
titleLabel.font = self.titleLabel?.font
stackView.addArrangedSubview(titleLabel)
}
override func layoutSubviews() {
super.layoutSubviews()
stackView.frame = bounds
}
}
使用方法:
@IBOutlet weak var btnOutlet: VerticalButton!
btnOutlet.setImage(UIImage(named: "Image-Name"), for: .normal)
btnOutlet.setTitle("Title", for: .normal)