自定义UIButton只需要在layoutSubviews方法中根据想要的布局位置重新计算UIButton中的ImageView和Label位置即可。但是有一点需要注意,计算出来的imgeView和Label的总宽度和总高度不能大于UIButton自身的大小,否则点击超过UIButton自身大小区域时会不响应事件。
Swift大致代码如下:
1.先定义ImageView和Lable之间的间距和位置关系
private let spacing: CGFloat enum SSImagePosition{ case top case left case bottom case right }
2.重写layoutSubviews
override func layoutSubviews() { super.layoutSubviews() if self.bounds.isEmpty { return } let btnSize = self.bounds.size let textSize = self.titleLabel?.sizeThatFits(btnSize) ?? CGSize.zero let imageSize = self.imageView?.image?.size ?? CGSize.zero switch self.position { case .top: let elementsHeight = textSize.height + imageSize.height + self.spacing var imageY: CGFloat = 0 var textY: CGFloat = btnSize.height - textSize.height if elementsHeight <= btnSize.height { imageY = (btnSize.height - elementsHeight)/CGFloat(2) textY = imageY + imageSize.height + self.spacing } self.titleLabel?.frame = CGRect(x: (btnSize.width - textSize.width)/CGFloat(2), y: textY, width: textSize.width, height: textSize.height) self.imageView?.frame = CGRect(x: (btnSize.width - imageSize.width)/CGFloat(2), y: imageY, width: imageSize.width, height: imageSize.height) case .left: let elementsWidth = textSize.width + imageSize.width + self.spacing if elementsWidth >= btnSize.width { return } let imageX = (btnSize.width - elementsWidth)/CGFloat(2) let textX = imageX + imageSize.width + self.spacing self.titleLabel?.frame = CGRect(x: textX, y: (btnSize.height - textSize.height)/CGFloat(2), width: textSize.width, height: textSize.height) self.imageView?.frame = CGRect(x: imageX , y: (btnSize.height - imageSize.height)/CGFloat(2.0), width: imageSize.width, height: imageSize.height) case .bottom: let elementsHeight = textSize.height + imageSize.height + self.spacing var imageY: CGFloat = btnSize.height - imageSize.height var textY: CGFloat = 0 if elementsHeight <= btnSize.height { textY = (btnSize.height - elementsHeight)/CGFloat(2) imageY = textY + textSize.height + self.spacing } self.titleLabel?.frame = CGRect(x: (btnSize.width - textSize.width)/CGFloat(2), y: textY, width: textSize.width, height: textSize.height) self.imageView?.frame = CGRect(x: (btnSize.width - imageSize.width)/CGFloat(2), y: imageY, width: imageSize.width, height: imageSize.height) case .right: let elementsWidth = textSize.width + imageSize.width + self.spacing var imageX: CGFloat = 0 var textX: CGFloat = btnSize.width - textSize.width if elementsWidth <= btnSize.width { textX = (btnSize.width - elementsWidth)/CGFloat(2) imageX = textX + textSize.width + self.spacing } self.titleLabel?.frame = CGRect(x: textX, y: (btnSize.height - textSize.height)/CGFloat(2), width: textSize.width, height: textSize.height) self.imageView?.frame = CGRect(x: imageX , y: (btnSize.height - imageSize.height)/CGFloat(2.0), width: imageSize.width, height: imageSize.height) } }