如果可以避免,我不想使用子视图。我想要一个带有背景图像,文本和图像的UIButton。现在,当我这样做的时候,图像在文本的左边。背景图像、文本和图像都有不同的高亮状态。
当前回答
在Piotr Tomasik的优雅解决方案的基础上:如果你想在按钮标签和图像之间有一点间距,那么包括在你的边缘嵌入如下(复制我的代码在这里完美地为我工作):
CGFloat spacing = 3;
CGFloat insetAmount = 0.5 * spacing;
// First set overall size of the button:
button.contentEdgeInsets = UIEdgeInsetsMake(0, insetAmount, 0, insetAmount);
[button sizeToFit];
// Then adjust title and image insets so image is flipped to the right and there is spacing between title and image:
button.titleEdgeInsets = UIEdgeInsetsMake(0, -button.imageView.frame.size.width - insetAmount, 0, button.imageView.frame.size.width + insetAmount);
button.imageEdgeInsets = UIEdgeInsetsMake(0, button.titleLabel.frame.size.width + insetAmount, 0, -button.titleLabel.frame.size.width - insetAmount);
感谢Piotr的解决方案!
Erik
其他回答
swift 3.0迁移 jasongregori给出的解
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
}
要在UIButton内右对齐图像,请尝试下面的代码
btn.contentHorizontalAlignment = .right
当标题发生变化时,只需更新插图即可。你需要在另一侧用等量的、相反的插页来补偿插页。
[thebutton setTitle:title forState:UIControlStateNormal];
thebutton.titleEdgeInsets = UIEdgeInsetsMake(0, -thebutton.imageView.frame.size.width, 0, thebutton.imageView.frame.size.width);
thebutton.imageEdgeInsets = UIEdgeInsetsMake(0, thebutton.titleLabel.frame.size.width, 0, -thebutton.titleLabel.frame.size.width);
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
}
这里提到的解决方案停止工作,一旦我启用自动布局。我不得不提出我自己的想法:
子类UIButton和覆盖layoutSubviews方法:
//
// MIThemeButtonImageAtRight.m
// Created by Lukasz Margielewski on 7/9/13.
//
#import "MIThemeButtonImageAtRight.h"
static CGRect CGRectByApplyingUIEdgeInsets(CGRect frame, UIEdgeInsets insets);
@implementation MIThemeButtonImageAtRight
- (void)layoutSubviews
{
[super layoutSubviews];
CGRect contentFrame = CGRectByApplyingUIEdgeInsets(self.bounds, self.contentEdgeInsets);
CGRect frameIcon = self.imageView.frame;
CGRect frameText = self.titleLabel.frame;
frameText.origin.x = CGRectGetMinX(contentFrame) + self.titleEdgeInsets.left;
frameIcon.origin.x = CGRectGetMaxX(contentFrame) - CGRectGetWidth(frameIcon);
self.imageView.frame = frameIcon;
self.titleLabel.frame = frameText;
}
@end
static CGRect CGRectByApplyingUIEdgeInsets(CGRect frame, UIEdgeInsets insets){
CGRect f = frame;
f.origin.x += insets.left;
f.size.width -= (insets.left + insets.right);
f.origin.y += (insets.top);
f.size.height -= (insets.top + insets.bottom);
return f;
}
结果:
推荐文章
- 改变UISegmentedControl的字体大小
- 我可以强制UITableView隐藏分隔符之间的空单元格吗?
- 获取用户当前位置/坐标
- 获得推送通知,而应用程序在前台iOS
- 如何取消选定的UITableView单元格?
- 设置自定义UITableViewCells的高度
- 在SwiftUI中创建一个VStack填充屏幕宽度
- 移动文本字段时,键盘出现迅速
- 让iPhone震动
- 将NSString转换为NSDate(然后再转换回来)
- linux的图形化DIFF程序
- 如何在swift中逆向循环迭代?
- applicationwillenter前台vs. applicationDidBecomeActive, applicationWillResignActive vs. applicationDidEnterBackground
- 如何在扑动中格式化日期时间
- Xcode 8 / Swift 3: "Expression of type UIViewController?未使用”警告