Skip to content

Instantly share code, notes, and snippets.

@ltryee
Created December 29, 2023 01:11
2.4 依赖注入
import Foundation
import UIKit
import SnapKit
import SwiftUI
import Resolver
extension Resolver: ResolverRegistering {
public static func registerAllServices() {
register {
ConcreteElementGenerator()
}.scope(.application)
register {
AnotherElementGenerator()
}.scope(.application)
}
}
class StackViewController: UIViewController {
typealias EType = ElementType
lazy var stackView = {
let stackView = ElementStackView<ConcreteElementGenerator>()
stackView.axis = .vertical
stackView.distribution = .equalSpacing
stackView.alignment = .fill
stackView.backgroundColor = .lightGray.withAlphaComponent(0.1)
return stackView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
view.addSubview(stackView)
stackView.snp.makeConstraints { make in
make.left.equalTo(20)
make.right.equalTo(-20)
make.centerY.equalToSuperview().priority(.low)
make.top.greaterThanOrEqualToSuperview().offset(60)
make.bottom.lessThanOrEqualToSuperview().offset(-20)
}
stackView.addArrangedElements(loginElementList())
}
func loginElementList() -> [EType] {
return [
.segment(items: ["登录", "注册"], defaultIndex: 0, onTapped: nil),
.spacer(height: 15),
.scrollableContainer(height: 0, elements: [
.commonInput(label: "User Name: ", placeHolder: "Email/Phone/ID", onTextChanged: { text in
print("User Name: \(String(describing: text))")
}),
.spacer(height: 10),
.commonInput(label: "Password: ", placeHolder: "Password", onTextChanged: { text in
print("Password: \(String(describing: text))")
}),
.spacer(height: 10),
.checker(title: "记住用户名", checked: false, onTapped: { checked in
print("checked: \(checked)")
}),
.spacer(height: 10),
]),
.spacer(height: 15),
.button(title: "登录", onTapped: nil)
]
}
func setupSubviews() {
let elementList = loginElementList()
stackView.addArrangedElements(elementList)
}
}
#Preview {
StackViewController()
}
import UIKit
import RxSwift
import RxCocoa
import Resolver
enum ElementType {
/// 居中的文字
/// - Parameters:
/// - title: 居中显示的文字
case centeredText(title: String)
/// 输入框
/// - Parameters:
/// - label: 左侧说明文字
/// - placeHolder: 输入框中的提示文字
/// - onTextChanged: 文本发生改变时的回调
case commonInput(label: String, placeHolder: String?, onTextChanged: ((String?) -> Void)?)
/// 按钮
/// - Parameters:
/// - title: 按钮文字
/// - onTapped: 按钮点击回调
case button(title: String, onTapped: (() -> Void)?)
/// segment
/// - Parameters:
/// - items: 段列表
/// - defaultIndex: 默认选中的段
/// - onTapped: 点击回调
case segment(items: [Any], defaultIndex: Int, onTapped: ((Int) -> Void)?)
/// checker
/// - Parameters:
/// - title: checker 说明
/// - checked: 是否选中
/// - onTapped: 点击回调
case checker(title: String, checked: Bool, onTapped: ((Bool) -> Void)?)
/// 占位符
/// - Parameters:
/// - height: 高度
case spacer(height: CGFloat)
/// 可滚动容器
/// - Parameters:
/// - height: 容器高度
/// - elements: 容器中的元素列表
case scrollableContainer(height: CGFloat, elements: [ElementType])
}
class ElementStackView<T: ElementGenerator>: UIStackView {
typealias EType = T.EType
@LazyInjected var elementGenerator: T
func addArrangedElements<E>(_ elements: [E]) -> Void where E == EType {
elementGenerator.addArrangedElements(elements, to: self)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment