BlueWallet/blue_modules/Views/SegmentedControl/ios/SegmentedControlView.swift
2026-04-27 21:20:35 -05:00

99 lines
2.8 KiB
Swift

import UIKit
import React
@objc(SegmentedControlView)
final class SegmentedControlView: UIView {
private let segmentedControl = UISegmentedControl()
// MARK: - Lifecycle
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setup()
}
private func setup() {
segmentedControl.addTarget(self, action: #selector(handleValueChanged(_:)), for: .valueChanged)
addSubview(segmentedControl)
segmentedControl.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
segmentedControl.leadingAnchor.constraint(equalTo: leadingAnchor),
segmentedControl.trailingAnchor.constraint(equalTo: trailingAnchor),
segmentedControl.topAnchor.constraint(equalTo: topAnchor),
segmentedControl.bottomAnchor.constraint(equalTo: bottomAnchor),
])
}
// MARK: - Prop setters
@objc var values: NSArray = [] {
didSet { rebuildSegments() }
}
@objc var selectedIndex: Int = 0 {
didSet {
guard segmentedControl.numberOfSegments > 0 else { return }
let clamped = min(max(selectedIndex, 0), segmentedControl.numberOfSegments - 1)
if segmentedControl.selectedSegmentIndex != clamped {
segmentedControl.selectedSegmentIndex = clamped
}
}
}
@objc var enabled: Bool = true {
didSet { segmentedControl.isEnabled = enabled }
}
@objc var momentary: Bool = false {
didSet { segmentedControl.isMomentary = momentary }
}
@objc var textColor: UIColor? {
didSet { applyTextAttributes() }
}
@objc var onChange: RCTBubblingEventBlock?
override var tintColor: UIColor! {
didSet { segmentedControl.selectedSegmentTintColor = tintColor }
}
override var backgroundColor: UIColor? {
didSet { segmentedControl.backgroundColor = backgroundColor }
}
// MARK: - Private helpers
private func rebuildSegments() {
let titles = values as? [String] ?? []
segmentedControl.removeAllSegments()
for (i, title) in titles.enumerated() {
segmentedControl.insertSegment(withTitle: title, at: i, animated: false)
}
guard !titles.isEmpty else { return }
let clamped = min(max(selectedIndex, 0), titles.count - 1)
segmentedControl.selectedSegmentIndex = clamped
}
private func applyTextAttributes() {
if let color = textColor {
segmentedControl.setTitleTextAttributes([.foregroundColor: color], for: .normal)
segmentedControl.setTitleTextAttributes([.foregroundColor: UIColor.white], for: .selected)
} else {
segmentedControl.setTitleTextAttributes(nil, for: .normal)
segmentedControl.setTitleTextAttributes(nil, for: .selected)
}
}
@objc private func handleValueChanged(_ sender: UISegmentedControl) {
onChange?(["selectedIndex": sender.selectedSegmentIndex])
}
}