如果我只将一个图像放在按钮中,并将imageEdgeInsets设置得更靠近顶部,图像将保持居中,并且所有内容都按预期工作:

[button setImage:image forState:UIControlStateNormal];
[button setImageEdgeInsets:UIEdgeInsetsMake(-15.0, 0.0, 0.0, 0.0)];

如果我在按钮中只放入一个文本,并将title EdgeInsets设置得更靠近底部,文本将保持居中,并且所有内容都按预期工作:

[button setTitle:title forState:UIControlStateNormal];
[button setTitleEdgeInsets:UIEdgeInsetsMake(0.0, 0.0, -30, 0.0)];

但是,如果我把这4行放在一起,文本会干扰图像,并且两者都失go 了中心对齐.

我的所有图像都有30像素的宽度,如果我将30放入setTitleEdgeInsets的UIEdgeInsetMake的Left参数中,文本将再次居中.问题是图像永远不会居中,因为它似乎依赖于Button.titleLabel大小.我已经try 了很多关于按钮大小、图像大小、标题标签大小的计算,但始终没有完全居中.

有人已经有同样的问题了?

推荐答案

无论如何,这里有一个通用的解决方案,可以在不使用任何幻数的情况下将图像定位在文本上方.Note that the following code is outdated and you should probably use one of the updated versions below:

// the space between the image and text
CGFloat spacing = 6.0;

// lower the text and push it left so it appears centered 
//  below the image
CGSize imageSize = button.imageView.frame.size;
button.titleEdgeInsets = UIEdgeInsetsMake(
  0.0, - imageSize.width, - (imageSize.height + spacing), 0.0);

// raise the image and push it right so it appears centered
//  above the text
CGSize titleSize = button.titleLabel.frame.size;
button.imageEdgeInsets = UIEdgeInsetsMake(
  - (titleSize.height + spacing), 0.0, 0.0, - titleSize.width);

以下版本包含以下 comments 中建议的支持iOS 7+的更改.我自己还没有测试过这段代码,所以我不确定它工作得有多好,或者如果在以前版本的iOS下使用,它是否会崩溃.

// the space between the image and text
CGFloat spacing = 6.0;

// lower the text and push it left so it appears centered 
//  below the image
CGSize imageSize = button.imageView.image.size;
button.titleEdgeInsets = UIEdgeInsetsMake(
  0.0, - imageSize.width, - (imageSize.height + spacing), 0.0);

// raise the image and push it right so it appears centered
//  above the text
CGSize titleSize = [button.titleLabel.text sizeWithAttributes:@{NSFontAttributeName: button.titleLabel.font}];
button.imageEdgeInsets = UIEdgeInsetsMake(
  - (titleSize.height + spacing), 0.0, 0.0, - titleSize.width);

// increase the content height to avoid clipping
CGFloat edgeOffset = fabsf(titleSize.height - imageSize.height) / 2.0;
button.contentEdgeInsets = UIEdgeInsetsMake(edgeOffset, 0.0, edgeOffset, 0.0);

Swift 5.0

extension UIButton {
  func alignVertical(spacing: CGFloat = 6.0) {
    guard let imageSize = imageView?.image?.size,
      let text = titleLabel?.text,
      let font = titleLabel?.font
    else { return }

    titleEdgeInsets = UIEdgeInsets(
      top: 0.0,
      left: -imageSize.width,
      bottom: -(imageSize.height + spacing),
      right: 0.0
    )

    let titleSize = text.size(withAttributes: [.font: font])
    imageEdgeInsets = UIEdgeInsets(
      top: -(titleSize.height + spacing),
      left: 0.0,
      bottom: 0.0,
      right: -titleSize.width
    )

    let edgeOffset = abs(titleSize.height - imageSize.height) / 2.0
    contentEdgeInsets = UIEdgeInsets(
      top: edgeOffset,
      left: 0.0,
      bottom: edgeOffset,
      right: 0.0
    )
  }
}

Ios相关问答推荐

无法在fastlane和github操作中从react-native 应用程序构建ios

AlGolia InstantSearch Swift Package Manager引发编译错误

如何使视图完全适合屏幕,而不会在旋转时溢出手机屏幕的边界?

自定义油漆圆角三角形

SWIFT用户界面检测手势的开始和结束

快速相机放大手势不能正常工作

如何结合`@dynamicMemberLookup`和`ExpressibleByStringInterpolation`来实现方法链?

如何解码没有名称的 JSON 数组?

SwiftUI:如何用拇指移动滑块值

TextField 重复输入 SwiftUI

`Task` 在内部调用异步函数时阻塞主线程

Swift 共享数据模型在页面之间进行通信.这个怎么运作

UICollectionView - 动态单元格高度?

NSURLConnection 的 Xcode 4 警告未使用表达式结果

通过 segue 传递数据

在原生和 phonegap 之间挣扎,简单的应用需求

使用未知类型创建图像格式是一个错误与 UIImagePickerController

从 Swift 转换为 Objective-c 的工具

xcode 5.1:libCordova.a 架构问题

ARC - __unsafe_unretained 的含义?