我在网上搜了一堆的代码,写法基本一样,有个明显的Bug,因为使用文本宽度计算的偏移量,当文本长度超出Button后就不太好了(⊙o⊙)…还有很多只调整titleEdgeInsets和imageEdgeInsets,没有处理contentEdgeInsets...给Button以及Button的label和image添加了背景色之后就能发现端倪,具体就不上图了,大家可以研究研究。
于是我想着自己来实现这个效果。
iOS15:比较简单了(苹果为啥到了iOS15才想起来按钮还需要这个功能呢)。Button新增UIButton.Configuration用来配置
if #available(iOS 15.0, *) {
var config = UIButton.Configuration.plain()
///这里imagePlacement图片的位置 .leading .trailing .bottom .top
config.imagePlacement = .top
config.imagePadding = 10
config.image = UIImage(named: "imgname")
testButton.configuration = config
}
iOS15之前,需要extension UIButton
enum ButtonImageStyle {
case top /// image在上,label在下
case left /// image在左,label在右
case bottom /// image在下,label在上
case right /// image在右,label在左
}
extension UIButton {
func layoutButtonImage(style:ButtonImageStyle=ButtonImageStyle.left,space:CGFloat = 5){
let imageWith = self.imageView?.bounds.width ?? 0
let imageHeight = self.imageView?.bounds.height ?? 0
let labelWidth = self.titleLabel?.intrinsicContentSize.width ?? 0
let labelHeight = self.titleLabel?.intrinsicContentSize.height ?? 0
var imageEdgeInsets = UIEdgeInsets.zero
var labelEdgeInsets = UIEdgeInsets.zero
var contentEdgeInsets = UIEdgeInsets.zero
let bWidth = self.bounds.width
let min_height = min(imageHeight, labelHeight)
switch style {
case .left:
self.contentVerticalAlignment = .center
imageEdgeInsets = UIEdgeInsets(top: 0,
left: 0,
bottom: 0,
right: 0)
labelEdgeInsets = UIEdgeInsets(top: 0,
left: space,
bottom: 0,
right: -space)
contentEdgeInsets = UIEdgeInsets(top: 0,left: 0,bottom: 0,right: space)
case .right:
self.contentVerticalAlignment = .center
var w_di = labelWidth + space/2
if (labelWidth+imageWith+space) > bWidth{
let labelWidth_f = self.titleLabel?.frame.width ?? 0
w_di = labelWidth_f + space/2
}
imageEdgeInsets = UIEdgeInsets(top: 0,
left: w_di,
bottom: 0,
right: -w_di)
labelEdgeInsets = UIEdgeInsets(top: 0,
left: -(imageWith+space/2),
bottom: 0,
right: imageWith+space/2)
contentEdgeInsets = UIEdgeInsets(top: 0, left: space/2, bottom: 0, right: space/2.0)
case .top:
//img在上或者在下 一版按钮是水平垂直居中的
self.contentHorizontalAlignment = .center
self.contentVerticalAlignment = .center
var w_di = labelWidth/2.0
//如果内容宽度大于button宽度 改变计算方式
if (labelWidth+imageWith+space) > bWidth{
w_di = (bWidth - imageWith)/2
}
//考虑图片+显示文字宽度大于按钮总宽度的情况
let labelWidth_f = self.titleLabel?.frame.width ?? 0
if (imageWith+labelWidth_f+space)>bWidth{
w_di = (bWidth - imageWith)/2
}
imageEdgeInsets = UIEdgeInsets(top: -(labelHeight+space),
left: w_di,
bottom: 0,
right: -w_di)
labelEdgeInsets = UIEdgeInsets(top: 0,
left: -imageWith,
bottom:-(space+imageHeight),
right: 0)
let h_di = (min_height+space)/2.0
contentEdgeInsets = UIEdgeInsets(top:h_di,left: 0,bottom:h_di,right: 0)
case .bottom:
//img在上或者在下 一版按钮是水平垂直居中的
self.contentHorizontalAlignment = .center
self.contentVerticalAlignment = .center
var w_di = labelWidth/2
//如果内容宽度大于button宽度 改变计算方式
if (labelWidth+imageWith+space) > bWidth{
w_di = (bWidth - imageWith)/2
}
//考虑图片+显示文字宽度大于按钮总宽度的情况
let labelWidth_f = self.titleLabel?.frame.width ?? 0
if (imageWith+labelWidth_f+space)>bWidth{
w_di = (bWidth - imageWith)/2
}
imageEdgeInsets = UIEdgeInsets(top: 0,
left: w_di,
bottom: -(labelHeight+space),
right: -w_di)
labelEdgeInsets = UIEdgeInsets(top: -(space+imageHeight),
left: -imageWith,
bottom: 0,
right: 0)
let h_di = (min_height+space)/2.0
contentEdgeInsets = UIEdgeInsets(top:h_di, left: 0,bottom:h_di,right: 0)
}
self.contentEdgeInsets = contentEdgeInsets
self.titleEdgeInsets = labelEdgeInsets
self.imageEdgeInsets = imageEdgeInsets
}
}
使用:
testButton.layoutButtonImage(style: .right, space: 10)
网友评论