// A simple segmented control with underline indicator for four tabs import UIKit import SnapKit final class EPMessageSegmentView: UIView { enum Segment: Int, CaseIterable { case message=0, friend, following, fans } var titles: [String] = [ YMLocalizedString("XPSessionMainViewController0"), YMLocalizedString("XPSessionMainViewController1"), YMLocalizedString("XPSessionMainViewController2"), YMLocalizedString("XPSessionMainViewController3") ] var didSelect: ((Int)->Void)? private var buttons: [UIButton] = [] private let indicator = UIView() override init(frame: CGRect) { super.init(frame: frame) setup() } required init?(coder: NSCoder) { super.init(coder: coder); setup() } private func setup() { backgroundColor = .clear let stack = UIStackView() stack.axis = .horizontal stack.alignment = .fill stack.distribution = .fillEqually stack.spacing = 0 addSubview(stack) stack.snp.makeConstraints { $0.edges.equalToSuperview() } for (idx, title) in titles.enumerated() { let b = UIButton(type: .custom) b.tag = idx b.setTitle(title, for: .normal) b.setTitleColor(UIColor.white.withAlphaComponent(0.6), for: .normal) b.setTitleColor(.white, for: .selected) b.titleLabel?.font = .systemFont(ofSize: 24, weight: idx == 0 ? .heavy : .regular) b.addTarget(self, action: #selector(onTap(_:)), for: .touchUpInside) buttons.append(b) stack.addArrangedSubview(b) } indicator.backgroundColor = UIColor.systemPink addSubview(indicator) layoutIfNeeded() select(index: 0, animated: false) } @objc private func onTap(_ sender: UIButton) { select(index: sender.tag, animated: true) didSelect?(sender.tag) } func select(index: Int, animated: Bool) { guard index >= 0 && index < buttons.count else { return } for (i,b) in buttons.enumerated() { b.isSelected = (i == index) b.titleLabel?.font = .systemFont(ofSize: 24, weight: b.isSelected ? .heavy : .regular) } let target = buttons[index] let width = target.bounds.width let y = bounds.height - 4 let frame = CGRect(x: CGFloat(index) * width + width*0.15, y: y, width: width*0.7, height: 3) if animated { UIView.animate(withDuration: 0.2) { self.indicator.frame = frame } } else { indicator.frame = frame } } }