如果可以避免,我不想使用子视图。我想要一个带有背景图像,文本和图像的UIButton。现在,当我这样做的时候,图像在文本的左边。背景图像、文本和图像都有不同的高亮状态。
当前回答
一个快速的选项,做什么你想要不玩任何插图:
class RightImageButton: UIButton {
override func layoutSubviews() {
super.layoutSubviews()
if let textSize = titleLabel?.intrinsicContentSize(),
imageSize = imageView?.intrinsicContentSize() {
let wholeWidth = textSize.width + K.textImageGap + imageSize.width
titleLabel?.frame = CGRect(
x: round(bounds.width/2 - wholeWidth/2),
y: 0,
width: ceil(textSize.width),
height: bounds.height)
imageView?.frame = CGRect(
x: round(bounds.width/2 + wholeWidth/2 - imageSize.width),
y: RoundRetina(bounds.height/2 - imageSize.height/2),
width: imageSize.width,
height: imageSize.height)
}
}
struct K {
static let textImageGap: CGFloat = 5
}
}
其他回答
Xcode 11.4 Swift 5.2
对于任何试图镜像后退按钮样式的人,像这样的雪佛龙:
import UIKit
class NextBarButton: UIBarButtonItem {
convenience init(target: Any, selector: Selector) {
// Create UIButton
let button = UIButton(frame: .zero)
// Set Title
button.setTitle("Next", for: .normal)
button.setTitleColor(.systemBlue, for: .normal)
button.titleLabel?.font = UIFont.systemFont(ofSize: 17)
// Configure Symbol
let config = UIImage.SymbolConfiguration(pointSize: 19.0, weight: .semibold, scale: .large)
let image = UIImage(systemName: "chevron.right", withConfiguration: config)
button.setImage(image, for: .normal)
// Add Target
button.addTarget(target, action: selector, for: .touchUpInside)
// Put the Image on the right hand side of the button
// Credit to liau-jian-jie for this part
button.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
button.titleLabel?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
button.imageView?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
// Customise spacing to match system Back button
button.imageEdgeInsets = UIEdgeInsets(top: 0.0, left: -18.0, bottom: 0.0, right: 0.0)
button.titleEdgeInsets = UIEdgeInsets(top: 0.0, left: -12.0, bottom: 0.0, right: 0.0)
self.init(customView: button)
}
}
实现:
override func viewDidLoad() {
super.viewDidLoad()
let nextButton = NextBarButton(target: self, selector: #selector(nextTapped))
navigationItem.rightBarButtonItem = nextButton
}
@objc func nextTapped() {
// your code
}
更新:Swift 3
class ButtonIconRight: UIButton {
override func imageRect(forContentRect contentRect:CGRect) -> CGRect {
var imageFrame = super.imageRect(forContentRect: contentRect)
imageFrame.origin.x = super.titleRect(forContentRect: contentRect).maxX - imageFrame.width
return imageFrame
}
override func titleRect(forContentRect contentRect:CGRect) -> CGRect {
var titleFrame = super.titleRect(forContentRect: contentRect)
if (self.currentImage != nil) {
titleFrame.origin.x = super.imageRect(forContentRect: contentRect).minX
}
return titleFrame
}
}
Swift 2的原始答案:
一个解决方案,处理所有水平对齐,与一个Swift实现示例。如果需要,只需翻译成Objective-C即可。
class ButtonIconRight: UIButton {
override func imageRectForContentRect(contentRect:CGRect) -> CGRect {
var imageFrame = super.imageRectForContentRect(contentRect)
imageFrame.origin.x = CGRectGetMaxX(super.titleRectForContentRect(contentRect)) - CGRectGetWidth(imageFrame)
return imageFrame
}
override func titleRectForContentRect(contentRect:CGRect) -> CGRect {
var titleFrame = super.titleRectForContentRect(contentRect)
if (self.currentImage != nil) {
titleFrame.origin.x = CGRectGetMinX(super.imageRectForContentRect(contentRect))
}
return titleFrame
}
}
同样值得注意的是,它处理相当好图像和标题插入。
灵感来自jasongregori的回答;)
做你自己。Xcode10 swift4,
用于编程UI设计
lazy var buttonFilter : ButtonRightImageLeftTitle = {
var button = ButtonRightImageLeftTitle()
button.setTitle("Playfir", for: UIControl.State.normal)
button.setImage(UIImage(named: "filter"), for: UIControl.State.normal)
button.backgroundColor = UIColor.red
button.contentHorizontalAlignment = .left
button.titleLabel?.font = UIFont.systemFont(ofSize: 16)
return button
}()
边缘插入值应用于矩形以收缩或展开 用矩形表示的面积。通常,使用边缘嵌入 在视图布局期间修改视图的框架。积极的价值观 将被插入(或缩小)指定数量的帧。负 值使帧由指定的对象开始(或展开) 量。
class ButtonRightImageLeftTitle: UIButton {
override func layoutSubviews() {
super.layoutSubviews()
guard imageView != nil else { return }
imageEdgeInsets = UIEdgeInsets(top: 5, left: (bounds.width - 35), bottom: 5, right: 5)
titleEdgeInsets = UIEdgeInsets(top: 0, left: -((imageView?.bounds.width)! + 10), bottom: 0, right: 0 )
}
}
用于StoryBoard UI设计
iOS 15带来了一个更新,现在你可以用一种更简单而不混乱的方式来处理按钮中的图像放置。没有insets。
在XIB /故事板: 简单地设置按钮的“位置”属性为领先/训练/顶部/底部后,添加一个图像属性按钮。由于它是领导/培训,所以它支持RTL有一个额外的优势
**在代码中(编程方式):** 以编程方式使用“按钮配置”属性
这不是一个向后兼容的功能,只能在iOS15+中工作,正如WWDC '21 - https://developer.apple.com/videos/play/wwdc2021/10064/?time=236所演示的那样
开发人员文档:https://developer.apple.com/documentation/uikit/uibutton/configuration?changes=_4
约束条件呢?与semanticContentAttribute不同,它们不会改变语义。也许是这样的:
button.rightAnchorconstraint(equalTo: button.rightAnchor).isActive = true
或者在Objective-C中:
[button.imageView.rightAnchor constraintEqualToAnchor:button.rightAnchor].isActive = YES;
警告:未经测试,iOS 9+
推荐文章
- iPhone上UIView和UILabels的渐变
- keychain上的分发证书中缺少私钥
- 在实现API时,我如何避免在块中捕获自我?
- 以编程方式设置TextView的布局权重
- 如何创建一个Swift Date对象?
- Xcode 4在目标设备上说“finished running <my app>”——什么都没有发生
- 从另一个应用程序打开设置应用程序
- 快速提取正则表达式匹配
- 如何应用梯度的背景视图的iOS Swift应用程序
- 图书馆吗?静态的?动态吗?或框架?另一个项目中的项目
- 如何用SwiftUI调整图像大小?
- Xcode 6 gitignore文件应该包括什么?
- 如何在iPhone/iOS上删除电话号码的蓝色样式?
- 检测视网膜显示
- 如何在UIImageView中动画图像的变化?