Add login flow, session routing, and MainTab shell aligned with reference UI.
Implement token-based root routing, Android-matched login screen, five-slot MainTabBar with scan action, and placeholder tab pages. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
59
suixinkan/UI/Common/AppButton.swift
Normal file
59
suixinkan/UI/Common/AppButton.swift
Normal file
@ -0,0 +1,59 @@
|
||||
//
|
||||
// AppButton.swift
|
||||
// suixinkan
|
||||
//
|
||||
|
||||
import SnapKit
|
||||
import UIKit
|
||||
|
||||
/// 主按钮,对应 Android `AppButton`。
|
||||
final class AppButton: UIButton {
|
||||
|
||||
enum Style {
|
||||
case primary
|
||||
case secondary
|
||||
}
|
||||
|
||||
private let style: Style
|
||||
|
||||
init(title: String, style: Style = .primary) {
|
||||
self.style = style
|
||||
super.init(frame: .zero)
|
||||
setupUI(title: title)
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override var isEnabled: Bool {
|
||||
didSet { updateAppearance() }
|
||||
}
|
||||
|
||||
private func setupUI(title: String) {
|
||||
titleLabel?.font = .systemFont(ofSize: 14, weight: .regular)
|
||||
layer.cornerRadius = 10
|
||||
clipsToBounds = true
|
||||
setTitle(title, for: .normal)
|
||||
updateAppearance()
|
||||
|
||||
snp.makeConstraints { make in
|
||||
make.height.equalTo(46)
|
||||
}
|
||||
}
|
||||
|
||||
private func updateAppearance() {
|
||||
switch style {
|
||||
case .primary:
|
||||
backgroundColor = isEnabled ? AppColor.primary : AppColor.buttonDisabled
|
||||
setTitleColor(.white, for: .normal)
|
||||
setTitleColor(.white, for: .disabled)
|
||||
case .secondary:
|
||||
backgroundColor = AppColor.secondaryButtonBackground
|
||||
setTitleColor(AppColor.primary, for: .normal)
|
||||
setTitleColor(AppColor.primary, for: .disabled)
|
||||
alpha = isEnabled ? 1 : 0.6
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user