import UIKit
// MARK: - CircleButton.Configuration
extension CircleButton {
struct Configuration {
/// Diameter of circular button adjusted for current content size
var scaledMediumSize: CGFloat {
let defaultMediumSize: CGFloat = 52
return UIFontMetrics.default.scaledValue(for: defaultMediumSize)
}
}
}
/// Circle button with an icon in the center and a background
///
/// Use as-is and provide all configuration during initialization. Using `UIButton` methods might lead to unexpected
/// side-effects.
final class CircleButton: ThemedCodeButton {
// Potential future improvements:
// - Scale icon along with size
// - Provide second `small` configuration
// - Also change background when highlighted
// - Define separate `Colors` property for background color independent of chat bubble color
private let buttonConfiguration = Configuration()
private lazy var sizeConstraint: NSLayoutConstraint = widthAnchor
.constraint(equalToConstant: buttonConfiguration.scaledMediumSize)
// MARK: - Lifecycle
/// Create a new button
///
/// - Parameters:
/// - sfSymbolName: Name of SF Symbol to show. Use just the SF Symbol name.
/// You should put a semibold L variant into the asset catalog.
/// - accessibilityLabel: Description of the button action for accessibility users.
/// - action: Action called when the button is tapped.
init(
sfSymbolName: String,
accessibilityLabel: String,
action: @escaping Action
) {
// Setting the actual frame size fixes an Auto Layout error that probably occurs when
// there is no superview
let initFrame = CGRect(
x: 0, y: 0,
width: buttonConfiguration.scaledMediumSize,
height: buttonConfiguration.scaledMediumSize
)
super.init(frame: initFrame, action: action)
configureButton(with: sfSymbolName)
registerObservers()
updateSize()
self.accessibilityLabel = accessibilityLabel
}
// MARK: - Configure
private func configureButton(with sfSymbolName: String) {
// Content
var image = UIImage(systemName: sfSymbolName)
if image == nil {
image = UIImage(named: sfSymbolName)
}
image = image?.applying(symbolWeight: .semibold, symbolScale: .large)
assert(image != nil, "Symbol not found")
setImage(image, for: .normal)
backgroundColor = .backgroundCircleButton
// Layout
NSLayoutConstraint.activate([
sizeConstraint,
heightAnchor.constraint(equalTo: widthAnchor),
])
}
private func registerObservers() {
NotificationCenter.default.addObserver(
self,
selector: #selector(contentSizeCategoryDidChange),
name: UIContentSizeCategory.didChangeNotification,
object: nil
)
}
// MARK: - Updates
private func updateSize() {
sizeConstraint.constant = buttonConfiguration.scaledMediumSize
layer.cornerRadius = buttonConfiguration.scaledMediumSize / 2
}
// MARK: - Notifications
@objc private func contentSizeCategoryDidChange() {
updateSize()
}
}
¤ Dauer der Verarbeitung: 0.2 Sekunden
¤
*© Formatika GbR, Deutschland