219 lines
6.9 KiB
Swift
219 lines
6.9 KiB
Swift
//
|
|
// JXButton.swift
|
|
// BoJia
|
|
//
|
|
// Created by 火山传媒 on 2024/5/31.
|
|
//
|
|
|
|
import UIKit
|
|
|
|
class JXButton: UIButton {
|
|
lazy var jx_font: UIFont? = self.titleLabel?.font {
|
|
didSet {
|
|
self.titleLabel?.font = jx_font
|
|
}
|
|
}
|
|
|
|
var maxTitleWidth: CGFloat = 0
|
|
var titleDirection: UITextLayoutDirection?
|
|
///左右边距
|
|
var leftAnyRightmargin: CGFloat = 0
|
|
|
|
///文字与图片的间距
|
|
var space: CGFloat = 0
|
|
|
|
private var imageRect: CGRect = .zero
|
|
private var titleRect: CGRect = .zero
|
|
|
|
|
|
override func layoutSubviews() {
|
|
super.layoutSubviews()
|
|
}
|
|
|
|
override var intrinsicContentSize: CGSize {
|
|
|
|
var width: CGFloat = 0
|
|
var height: CGFloat = 0
|
|
switch titleDirection {
|
|
case .left:
|
|
width = imageRect.width + titleRect.width + space
|
|
if imageRect.height > titleRect.height {
|
|
height = imageRect.height
|
|
} else {
|
|
height = titleRect.height
|
|
}
|
|
|
|
case .up:
|
|
if imageRect.width > titleRect.width {
|
|
width = imageRect.width
|
|
} else {
|
|
width = titleRect.width
|
|
}
|
|
height = titleRect.height + imageRect.height + space
|
|
|
|
case .down:
|
|
if imageRect.width > titleRect.width {
|
|
width = imageRect.width
|
|
} else {
|
|
width = titleRect.width
|
|
}
|
|
height = titleRect.height + imageRect.height + space
|
|
|
|
default:
|
|
width = imageRect.width + titleRect.width + space
|
|
if imageRect.height > titleRect.height {
|
|
height = imageRect.height
|
|
} else {
|
|
height = titleRect.height
|
|
}
|
|
}
|
|
|
|
let size = CGSize(width: width + leftAnyRightmargin * 2, height: height)
|
|
return size
|
|
}
|
|
|
|
override func imageRect(forContentRect contentRect: CGRect) -> CGRect {
|
|
let imageSize = currentImage?.size ?? .zero
|
|
let textSize = self._textSize()
|
|
let contentWidth = self.frame.size.width
|
|
let contentHeight = self.frame.size.height
|
|
|
|
var x: CGFloat = 0
|
|
var y: CGFloat = 0
|
|
var width: CGFloat = 0
|
|
var height: CGFloat = 0
|
|
|
|
switch titleDirection {
|
|
case .left:
|
|
x = (contentWidth - space) / 2 - imageSize.width / 2 + textSize.width / 2 + space
|
|
y = contentHeight / 2 - imageSize.height / 2
|
|
width = imageSize.width
|
|
height = imageSize.height
|
|
|
|
case .up:
|
|
x = contentWidth / 2 - imageSize.width / 2
|
|
y = (contentHeight - space) / 2 - imageSize.height / 2 + textSize.height / 2 + space
|
|
width = imageSize.width
|
|
height = imageSize.height
|
|
|
|
case .down:
|
|
x = contentWidth / 2 - imageSize.width / 2
|
|
y = (contentHeight - space) / 2 - imageSize.height / 2 - textSize.height / 2
|
|
width = imageSize.width
|
|
height = imageSize.height
|
|
|
|
default:
|
|
x = (contentWidth - space) / 2 - imageSize.width / 2 - textSize.width / 2
|
|
y = contentHeight / 2 - imageSize.height / 2
|
|
width = imageSize.width
|
|
height = imageSize.height
|
|
}
|
|
self.imageRect = CGRect(x: x, y: y, width: width, height: height)
|
|
|
|
return self.imageRect
|
|
}
|
|
|
|
|
|
override func titleRect(forContentRect contentRect: CGRect) -> CGRect {
|
|
let imageSize = currentImage?.size ?? .zero
|
|
let textSize = self._textSize()
|
|
let contentWidth = self.frame.size.width
|
|
let contentHeight = self.frame.size.height
|
|
|
|
var x: CGFloat = 0
|
|
var y: CGFloat = 0
|
|
var width: CGFloat = 0
|
|
var height: CGFloat = 0
|
|
|
|
switch titleDirection {
|
|
case .left:
|
|
x = (contentWidth - space) / 2 - imageSize.width / 2 - textSize.width / 2
|
|
y = contentHeight / 2 - textSize.height / 2
|
|
width = textSize.width
|
|
height = textSize.height
|
|
|
|
case .up:
|
|
x = contentWidth / 2 - textSize.width / 2
|
|
y = (contentHeight - space) / 2 - textSize.height / 2 - imageSize.height / 2
|
|
width = textSize.width
|
|
height = textSize.height
|
|
|
|
case .down:
|
|
x = contentWidth / 2 - textSize.width / 2
|
|
y = (contentHeight - space) / 2 - textSize.height / 2 + imageSize.height / 2 + space
|
|
width = textSize.width
|
|
height = textSize.height
|
|
|
|
default:
|
|
x = (contentWidth - space) / 2 + imageSize.width / 2 - textSize.width / 2 + space
|
|
y = contentHeight / 2 - textSize.height / 2
|
|
width = textSize.width
|
|
height = textSize.height
|
|
}
|
|
|
|
self.titleRect = CGRect(x: x, y: y, width: width, height: height)
|
|
return self.titleRect
|
|
}
|
|
|
|
|
|
private var borderColors: [UInt : UIColor] = [:]
|
|
|
|
func jx_setBorderColor(_ color: UIColor?, for state: UIControl.State) {
|
|
var arr = self.borderColors
|
|
let index = state.rawValue
|
|
arr[index] = color
|
|
if state == .selected {
|
|
let i = index + UIControl.State.highlighted.rawValue
|
|
arr[i] = color
|
|
}
|
|
self.borderColors = arr
|
|
updateStatus()
|
|
}
|
|
|
|
func updateStatus() {
|
|
var color = self.borderColors[self.state.rawValue]?.cgColor
|
|
if (color == nil) {
|
|
color = self.borderColors[UIControl.State.normal.rawValue]?.cgColor
|
|
}
|
|
self.layer.borderColor = color
|
|
}
|
|
|
|
override var isSelected: Bool {
|
|
didSet {
|
|
updateStatus()
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
extension JXButton {
|
|
|
|
private func _textSize() -> CGSize {
|
|
// let size = CGSize(width: self.bounds.size.width, height: self.bounds.size.height)
|
|
|
|
var attr: [NSAttributedString.Key : Any] = [:]
|
|
attr[NSAttributedString.Key.font] = jx_font
|
|
|
|
let paragraphStyle = NSMutableParagraphStyle()
|
|
paragraphStyle.lineBreakMode = .byTruncatingMiddle
|
|
attr[NSAttributedString.Key.paragraphStyle] = paragraphStyle
|
|
|
|
// var rect = self.currentTitle?.ocString.boundingRect(with: size, options: [.usesLineFragmentOrigin, .usesFontLeading], attributes: attr, context: nil) ?? .zero
|
|
|
|
if let font = jx_font {
|
|
var size = self.currentTitle?.size(font: font) ?? .zero
|
|
|
|
if maxTitleWidth != 0 && maxTitleWidth < size.width {
|
|
size = CGSize(width: maxTitleWidth, height: size.height)
|
|
}
|
|
// if maxTitleWidth != 0 && maxTitleWidth < rect.size.width {
|
|
// rect.size = CGSize(width: maxTitleWidth, height: rect.size.height)
|
|
// }
|
|
return size
|
|
} else {
|
|
return .zero
|
|
}
|
|
}
|
|
|
|
}
|