use*_*721 57 uibutton uiimage ios
我见过有关正确对齐的帖子,但我无法让左对齐工作.我希望按钮占据屏幕的宽度,左侧是图像,中间是标题/文字.
这不起作用(至少可靠):
button.titleLabel.textAlignment = UITextAlignmentCenter;
[button setImageEdgeInsets:UIEdgeInsetsMake(0, -60.0, 0, 0)];
button.frame = CGRectMake((self.view.frame.size.width - w ) / 2, self.view.frame.size.height - 140.0, self.view.frame.size.width - 10.0, 40.0);
Run Code Online (Sandbox Code Playgroud)
red*_*t84 54
此解决方案适用于Swift 3并尊重原始内容和图像边缘插入,同时保持标题标签始终位于可用空间的中心,这样可以更轻松地调整边距.
它会覆盖titleRect(forContentRect:)方法并返回正确的框架:
@IBDesignable
class LeftAlignedIconButton: UIButton {
override func titleRect(forContentRect contentRect: CGRect) -> CGRect {
let titleRect = super.titleRect(forContentRect: contentRect)
let imageSize = currentImage?.size ?? .zero
let availableWidth = contentRect.width - imageEdgeInsets.right - imageSize.width - titleRect.width
return titleRect.offsetBy(dx: round(availableWidth / 2), dy: 0)
}
}
Run Code Online (Sandbox Code Playgroud)
以下内容:
会导致这个:
不推荐使用先前的答案
这适用于大多数情况,但是某些布局会导致layoutSubviews以无限循环递归调用自身,因此请谨慎使用.
@IBDesignable
class LeftAlignedIconButton: UIButton {
override func layoutSubviews() {
super.layoutSubviews()
contentHorizontalAlignment = .left
let availableSpace = UIEdgeInsetsInsetRect(bounds, contentEdgeInsets)
let availableWidth = availableSpace.width - imageEdgeInsets.right - (imageView?.frame.width ?? 0) - (titleLabel?.frame.width ?? 0)
titleEdgeInsets = UIEdgeInsets(top: 0, left: availableWidth / 2, bottom: 0, right: 0)
}
}
Run Code Online (Sandbox Code Playgroud)
此代码将执行相同操作但将图标与右边缘对齐:
@IBDesignable
class RightAlignedIconButton: UIButton {
override func layoutSubviews() {
super.layoutSubviews()
semanticContentAttribute = .forceRightToLeft
contentHorizontalAlignment = .right
let availableSpace = UIEdgeInsetsInsetRect(bounds, contentEdgeInsets)
let availableWidth = availableSpace.width - imageEdgeInsets.left - (imageView?.frame.width ?? 0) - (titleLabel?.frame.width ?? 0)
titleEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: availableWidth / 2)
}
}
Run Code Online (Sandbox Code Playgroud)
正确的allignment版本使用semanticContentAttribute它需要iOS 9+.
toy*_*toy 46
在我的最后,我使用UIEdgeInsetsMake做了这个,计算左角到中心.我不确定是否有什么东西可以使文本在中心对齐,但这对我有用.确保通过计算宽度将左角设置到所需位置.例如 UIEdgeInsetsMake(0.0f, 42.0f, 0.0f, 0.0f)
UIButton *scanBarCodeButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
scanBarCodeButton.frame = CGRectMake(center, 10.0f, fieldWidth, 40.0f);
[scanBarCodeButton setImage:[UIImage imageNamed:@"BarCodeIcon.png"] forState:UIControlStateNormal];
[scanBarCodeButton setTitle:@"Scan the Barcode" forState:UIControlStateNormal];
scanBarCodeButton.titleEdgeInsets = UIEdgeInsetsMake(0.0f, 42.0f, 0.0f, 0.0f);
[scanBarCodeButton setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
[scanBarCodeButton addTarget:self action:@selector(scanBarCode:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:scanBarCodeButton];
Run Code Online (Sandbox Code Playgroud)
输出看起来像,
带图像的居中文本http://i43.tinypic.com/33mbxxi.png
在Swift中:
var scanBarCodeButton: UIButton = UIButton(type: .roundedRect)
scanBarCodeButton.frame = CGRectMake(center, 10.0, fieldWidth, 40.0)
scanBarCodeButton.setImage(UIImage(named: "BarCodeIcon.png"), for: UIControlStateNormal)
scanBarCodeButton.setTitle("Scan the Barcode", for: UIControlStateNormal)
scanBarCodeButton.titleEdgeInsets = UIEdgeInsetsMake(0.0, 42.0, 0.0, 0.0)
scanBarCodeButton.contentHorizontalAlignment = .left
scanBarCodeButton.addTarget(self, action: "scanBarCode:", for: UIControlEventTouchUpInside)
self.view.addSubview(scanBarCodeButton)
Run Code Online (Sandbox Code Playgroud)
Ann*_*awn 12
对于Swift 4.0,这是一个有效的扩展 -
extension UIButton {
func leftImage(image: UIImage, renderMode: UIImageRenderingMode) {
self.setImage(image.withRenderingMode(renderMode), for: .normal)
self.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: image.size.width / 2)
self.contentHorizontalAlignment = .left
self.imageView?.contentMode = .scaleAspectFit
}
func rightImage(image: UIImage, renderMode: UIImageRenderingMode){
self.setImage(image.withRenderingMode(renderMode), for: .normal)
self.imageEdgeInsets = UIEdgeInsets(top: 0, left:image.size.width / 2, bottom: 0, right: 0)
self.contentHorizontalAlignment = .right
self.imageView?.contentMode = .scaleAspectFit
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
myButton.rightImage(image: UIImage(named: "image_name")!, renderMode: .alwaysOriginal)
myButton.leftImage(image: UIImage(named: "image_name")!, renderMode: .alwaysOriginal)
Run Code Online (Sandbox Code Playgroud)
renderMode可以是.alwaysTemplate或.alwaysOriginal.另外,myButton应该是一种custom类型UIButton.
这个扩展的leftImage并且rightImage也可以用在UIButton在UIBarButtonItem的UINavigationBar(注:由于iOS的11,导航栏下面自动布局,所以你需要宽度/高度限制添加到UIBarButtonItem).要在导航栏上使用,请确保遵循Apple推荐的@ 2x和@ 3x图像尺寸(即50x50,75x75)并在iPhone 6,7,8,6s,7s,8s,Plus版本和iPhone上具有更好的可访问性x UIBarButton可以是高度的宽度和高度- 25和宽度 - 55(或者您的应用需要的任何数字,这些数字是一些基本数字,适用于大多数情况).
更新:在Swift 4.2中,UIImageRenderingMode已重命名为UIImage.RenderingMode
extension UIButton {
func leftImage(image: UIImage, renderMode: UIImage.RenderingMode) {
self.setImage(image.withRenderingMode(renderMode), for: .normal)
self.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: image.size.width / 2)
self.contentHorizontalAlignment = .left
self.imageView?.contentMode = .scaleAspectFit
}
func rightImage(image: UIImage, renderMode: UIImage.RenderingMode){
self.setImage(image.withRenderingMode(renderMode), for: .normal)
self.imageEdgeInsets = UIEdgeInsets(top: 0, left:image.size.width / 2, bottom: 0, right: 0)
self.contentHorizontalAlignment = .right
self.imageView?.contentMode = .scaleAspectFit
}
}
Run Code Online (Sandbox Code Playgroud)
我已经尝试了上面几乎所有的解决方案,但没有一个像我预期的那样工作(我有两个按钮,每个按钮都有不同的标题和不同的图像宽度)。所以我为 UIButton 编写了我自己的扩展,它可以完美地处理不同的图像宽度和不同的标题。
extension UIButton {
func moveImageLeftTextCenter(imagePadding: CGFloat = 30.0, titlePadding: CGFloat = 0.0, minImageTitleDistance: CGFloat = 10.0){
guard let imageViewWidth = imageView?.frame.width else{return}
guard let titleLabelWidth = titleLabel?.intrinsicContentSize.width else{return}
contentHorizontalAlignment = .left
let imageLeftInset = imagePadding - imageViewWidth / 2
var titleLeftInset = (bounds.width - titleLabelWidth) / 2 - imageViewWidth + titlePadding
if titleLeftInset - imageLeftInset < minImageTitleDistance{
titleLeftInset = imageLeftInset + minImageTitleDistance
}
imageEdgeInsets = UIEdgeInsets(top: 0.0, left: imageLeftInset, bottom: 0.0, right: 0.0)
titleEdgeInsets = UIEdgeInsets(top: 0.0, left: titleLeftInset, bottom: 0.0, right: 0.0)
}
}
Run Code Online (Sandbox Code Playgroud)
用法: myButton.moveImageLeftTextCenter()
创建按钮并将文本对齐方式设置为居中,然后添加:
UIImage *image = [UIImage imageNamed:@"..."];
CGSize imageSize = image.size;
CGFloat offsetY = floor((self.layer.bounds.size.height - imageSize.height) / 2.0);
CALayer *imageLayer = [CALayer layer];
imageLayer.contents = (__bridge id) image.CGImage;
imageLayer.contentsGravity = kCAGravityBottom;
imageLayer.contentsScale = [UIScreen mainScreen].scale;
imageLayer.frame = CGRectMake(offsetY, offsetY, imageSize.width, imageSize.height);
[self.layer addSublayer:imageLayer];
Run Code Online (Sandbox Code Playgroud)
我认为,好的解决方案必须对任何文本都有用,没有用于插入的硬编码值(这是关于toytoy提供的解决方案).我使用类似这样的代码:
NSString *sometitle = @"blabla button title";
NSString *someimage = @"blablaimage";
UIImage *image = [[UIImage imageNamed:someimage];
int buttonWidth = A;
int buttonHeight = B;
int imageWidth =image.size.width;
int imageHeight = image.size.height;
int titleWidth = buttonWidth - imageWidth;
// create button and set image and title
buttonView = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, buttonWidth, buttonHeight)];
[buttonView setImage:image forState:UIControlStateNormal];
[buttonView setTitle:sometitle forState:UIControlStateNormal];
// make button all content to be left aligned
[buttonView setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
// set title font
[buttonView.titleLabel setFont:[UIFont fontWithName:@"HelveticaNeue" size:14]];
// calculate font text width with selected font
CGSize stringBoundingBox = [number sizeWithFont:[buttonView.titleLabel font]];
// make title inset with some value from left
// it place the title right on the center of space for the title
int titleLeft = (titleWidth - stringBoundingBox.width) / 2;
[buttonView setTitleEdgeInsets:UIEdgeInsetsMake(0, titleLeft, 0, 0)];
Run Code Online (Sandbox Code Playgroud)
在使用stringBoundingBox init的字符串之后,我还添加了一些这样的字符串:
if (stringBoundingBox.width > titleWidth)
{
[_backgroundView.titleLabel setFont:[UIFont fontWithName:@"HelveticaNeue" size:13]];
stringBoundingBox = [number sizeWithFont:[_backgroundView.titleLabel font]];
}
if (stringBoundingBox.width > titleWidth)
{
[_backgroundView.titleLabel setFont:[UIFont fontWithName:@"HelveticaNeue" size:12]];
stringBoundingBox = [number sizeWithFont:[_backgroundView.titleLabel font]];
}
Run Code Online (Sandbox Code Playgroud)
它允许我通过选择一些较小的字体来设置比可用空间更长的标题.我这样做是因为另一种方式:
[buttonView.titleLabel setAdjustsFontSizeToFitWidth:YES];
Run Code Online (Sandbox Code Playgroud)
效果不是很好,看起来它的字体大小一步缩小3-4个点,所以有些不那么长的线条变得比它必须要小.
此代码允许我们将按钮标题空间中的任何文本正好放在中心.
[self.button setImage:[UIImage imageNamed:@"image.png"] forState:UIControlStateNormal];
[self.button setTitleEdgeInsets:UIEdgeInsetsMake(0.0, self.button.center.x/2 , 0.0, 0.0)];
[self.button setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
Run Code Online (Sandbox Code Playgroud)
如果它不起作用,请告诉我.
在没有运气的情况下尝试了大多数答案。大多数时候我得到的是蓝色图像,或者标题不在中心。使用了一些答案中的代码并编写了这个扩展,就像一个魅力。
斯威夫特 4.2:
import UIKit
extension UIButton {
func moveImageLeftTextCenter(image : UIImage, imagePadding: CGFloat, renderingMode: UIImage.RenderingMode){
self.setImage(image.withRenderingMode(renderingMode), for: .normal)
guard let imageViewWidth = self.imageView?.frame.width else{return}
guard let titleLabelWidth = self.titleLabel?.intrinsicContentSize.width else{return}
self.contentHorizontalAlignment = .left
let imageLeft = imagePadding - imageViewWidth / 2
let titleLeft = (bounds.width - titleLabelWidth) / 2 - imageViewWidth
imageEdgeInsets = UIEdgeInsets(top: 0.0, left: imageLeft, bottom: 0.0, right: 0.0)
titleEdgeInsets = UIEdgeInsets(top: 0.0, left: titleLeft , bottom: 0.0, right: 0.0)
}
}
Run Code Online (Sandbox Code Playgroud)
希望对一些人有所帮助!
这对我来说效果很好,对于几个具有不同图像宽度和不同标题长度的按钮:
子类UIButton,并添加以下方法:
override func layoutSubviews() {
super.layoutSubviews()
if let image = imageView?.image {
let margin = 30 - image.size.width / 2
let titleRect = titleRectForContentRect(bounds)
let titleOffset = (bounds.width - titleRect.width - image.size.width - margin) / 2
contentHorizontalAlignment = UIControlContentHorizontalAlignment.Left
imageEdgeInsets = UIEdgeInsetsMake(0, margin, 0, 0)
titleEdgeInsets = UIEdgeInsetsMake(0, (bounds.width - titleRect.width - image.size.width - margin) / 2, 0, 0)
}
}
Run Code Online (Sandbox Code Playgroud)
我写了一个UIButton扩展.
extension UIButton {
/// Add image on left view
func leftImage(image: UIImage) {
self.setImage(image, for: .normal)
self.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: image.size.width)
}
}
Run Code Online (Sandbox Code Playgroud)
你可以像这样使用:
yourButton.leftImage(image: yourImage)
Run Code Online (Sandbox Code Playgroud)
瞧!
| 归档时间: |
|
| 查看次数: |
64000 次 |
| 最近记录: |