
主要变更: 1. 新增 EPLoginViewController 和 EPLoginTypesViewController,提供新的登录界面和功能。 2. 引入 EPLoginInputView 和 EPLoginButton 组件,支持输入框和按钮的自定义。 3. 实现 EPLoginService 和 EPLoginManager,封装登录逻辑和 API 请求。 4. 添加 EPLoginConfig 和 EPLoginState,统一配置和状态管理。 5. 更新 Bridging Header,确保 Swift 和 Objective-C 代码的互操作性。 此更新旨在提升用户登录体验,简化登录流程,并提供更好的代码结构和可维护性。
132 lines
3.8 KiB
Swift
132 lines
3.8 KiB
Swift
//
|
||
// EPLoginButton.swift
|
||
// YuMi
|
||
//
|
||
// Created by AI on 2025-01-27.
|
||
// 登录按钮组件 - 使用 StackView 实现 icon 左侧固定 + title 居中
|
||
//
|
||
|
||
import UIKit
|
||
import SnapKit
|
||
|
||
/// 登录按钮点击代理
|
||
protocol EPLoginButtonDelegate: AnyObject {
|
||
func loginButtonDidTap(_ button: EPLoginButton)
|
||
}
|
||
|
||
/// 登录按钮组件
|
||
class EPLoginButton: UIControl {
|
||
|
||
// MARK: - Properties
|
||
|
||
weak var delegate: EPLoginButtonDelegate?
|
||
|
||
private let stackView = UIStackView()
|
||
private let iconImageView = UIImageView()
|
||
private let titleLabel = UILabel()
|
||
private let leftSpacer = UIView()
|
||
private let rightSpacer = UIView()
|
||
|
||
// MARK: - Initialization
|
||
|
||
override init(frame: CGRect) {
|
||
super.init(frame: frame)
|
||
setupUI()
|
||
}
|
||
|
||
required init?(coder: NSCoder) {
|
||
fatalError("init(coder:) has not been implemented")
|
||
}
|
||
|
||
// MARK: - Setup
|
||
|
||
private func setupUI() {
|
||
backgroundColor = EPLoginConfig.Colors.background
|
||
layer.cornerRadius = EPLoginConfig.Layout.cornerRadius
|
||
|
||
// StackView 配置
|
||
stackView.axis = .horizontal
|
||
stackView.alignment = .center
|
||
stackView.distribution = .fill
|
||
stackView.spacing = 0
|
||
stackView.isUserInteractionEnabled = false
|
||
addSubview(stackView)
|
||
|
||
// Icon
|
||
iconImageView.contentMode = .scaleAspectFit
|
||
|
||
// Title
|
||
titleLabel.font = .systemFont(ofSize: EPLoginConfig.Layout.inputFontSize, weight: .semibold)
|
||
titleLabel.textColor = EPLoginConfig.Colors.text
|
||
titleLabel.textAlignment = .center
|
||
|
||
// Spacers - 让 title 居中
|
||
leftSpacer.setContentHuggingPriority(.defaultLow, for: .horizontal)
|
||
rightSpacer.setContentHuggingPriority(.defaultLow, for: .horizontal)
|
||
|
||
// 布局顺序: [Leading 33] + [Icon] + [Flexible Spacer] + [Title] + [Flexible Spacer] + [Trailing 33]
|
||
let leadingPadding = UIView()
|
||
let trailingPadding = UIView()
|
||
|
||
stackView.addArrangedSubview(leadingPadding)
|
||
stackView.addArrangedSubview(iconImageView)
|
||
stackView.addArrangedSubview(leftSpacer)
|
||
stackView.addArrangedSubview(titleLabel)
|
||
stackView.addArrangedSubview(rightSpacer)
|
||
stackView.addArrangedSubview(trailingPadding)
|
||
|
||
// 约束
|
||
stackView.snp.makeConstraints { make in
|
||
make.edges.equalToSuperview()
|
||
}
|
||
|
||
leadingPadding.snp.makeConstraints { make in
|
||
make.width.equalTo(EPLoginConfig.Layout.loginButtonIconLeading)
|
||
}
|
||
|
||
iconImageView.snp.makeConstraints { make in
|
||
make.size.equalTo(EPLoginConfig.Layout.loginButtonIconSize)
|
||
}
|
||
|
||
trailingPadding.snp.makeConstraints { make in
|
||
make.width.equalTo(EPLoginConfig.Layout.loginButtonIconLeading)
|
||
}
|
||
|
||
// 设置 leftSpacer 和 rightSpacer 宽度相等,实现 title 居中
|
||
leftSpacer.snp.makeConstraints { make in
|
||
make.width.equalTo(rightSpacer)
|
||
}
|
||
|
||
// 添加点击事件
|
||
addTarget(self, action: #selector(handleTap), for: .touchUpInside)
|
||
}
|
||
|
||
// MARK: - Configuration
|
||
|
||
/// 配置按钮
|
||
/// - Parameters:
|
||
/// - icon: 图标名称
|
||
/// - title: 标题文字
|
||
func configure(icon: String, title: String) {
|
||
iconImageView.image = kImage(icon)
|
||
titleLabel.text = title
|
||
}
|
||
|
||
// MARK: - Actions
|
||
|
||
@objc private func handleTap() {
|
||
delegate?.loginButtonDidTap(self)
|
||
}
|
||
|
||
// MARK: - Touch Feedback
|
||
|
||
override var isHighlighted: Bool {
|
||
didSet {
|
||
UIView.animate(withDuration: 0.1) {
|
||
self.alpha = self.isHighlighted ? 0.7 : 1.0
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|