// // TravelAlbumTransferModeSheetViewController.swift // suixinkan // import SnapKit import UIKit /// 相册管理上传入口的传输模式选择弹窗。 final class TravelAlbumTransferModeSheetViewController: UIViewController { /// 用户选择传输模式后的回调;弹窗关闭后触发。 var onModeSelected: ((TravelAlbumOTGTransferMode) -> Void)? private let titleLabel = UILabel() private let subtitleLabel = UILabel() private let optionsStack = UIStackView() private let cancelButton = UIButton(type: .system) override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) modalPresentationStyle = .pageSheet if let sheetPresentationController { let identifier = UISheetPresentationController.Detent.Identifier("transferMode") sheetPresentationController.detents = [ .custom(identifier: identifier) { context in min(356, context.maximumDetentValue) }, ] sheetPresentationController.selectedDetentIdentifier = identifier sheetPresentationController.prefersGrabberVisible = true sheetPresentationController.preferredCornerRadius = 22 } } @available(*, unavailable) required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() setupUI() setupConstraints() } private func setupUI() { view.backgroundColor = .white titleLabel.text = "选择传输模式" titleLabel.font = .systemFont(ofSize: 19, weight: .semibold) titleLabel.textColor = AppColor.textPrimary titleLabel.textAlignment = .center subtitleLabel.text = "选择后进入对应的照片传输页面" subtitleLabel.font = .systemFont(ofSize: 13) subtitleLabel.textColor = AppColor.textSecondary subtitleLabel.textAlignment = .center optionsStack.axis = .vertical optionsStack.spacing = 12 TravelAlbumOTGTransferMode.allCases.enumerated().forEach { index, mode in optionsStack.addArrangedSubview(makeOptionView(mode: mode, index: index)) } cancelButton.setTitle("取消", for: .normal) cancelButton.setTitleColor(AppColor.textSecondary, for: .normal) cancelButton.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium) cancelButton.backgroundColor = UIColor(hex: 0xF4F5F7) cancelButton.layer.cornerRadius = 12 cancelButton.addTarget(self, action: #selector(cancelTapped), for: .touchUpInside) view.addSubview(titleLabel) view.addSubview(subtitleLabel) view.addSubview(optionsStack) view.addSubview(cancelButton) } private func setupConstraints() { titleLabel.snp.makeConstraints { make in make.top.equalTo(view.safeAreaLayoutGuide).offset(14) make.leading.trailing.equalToSuperview().inset(20) } subtitleLabel.snp.makeConstraints { make in make.top.equalTo(titleLabel.snp.bottom).offset(7) make.leading.trailing.equalToSuperview().inset(20) } optionsStack.snp.makeConstraints { make in make.top.equalTo(subtitleLabel.snp.bottom).offset(18) make.leading.trailing.equalToSuperview().inset(16) } cancelButton.snp.makeConstraints { make in make.top.equalTo(optionsStack.snp.bottom).offset(14) make.leading.trailing.equalTo(optionsStack) make.height.equalTo(48) make.bottom.lessThanOrEqualTo(view.safeAreaLayoutGuide).offset(-10) } } /// 创建无需二次确认的模式选项,点击后直接进入下一页。 private func makeOptionView(mode: TravelAlbumOTGTransferMode, index: Int) -> UIView { let container = UIView() container.backgroundColor = UIColor(hex: 0xF7F9FC) container.layer.cornerRadius = 12 container.layer.borderWidth = 1 container.layer.borderColor = UIColor(hex: 0xE6ECF5).cgColor let titleLabel = UILabel() titleLabel.text = mode.title titleLabel.font = .systemFont(ofSize: 16, weight: .semibold) titleLabel.textColor = AppColor.textPrimary let detailLabel = UILabel() detailLabel.text = mode.detailText detailLabel.font = .systemFont(ofSize: 12) detailLabel.textColor = AppColor.textSecondary detailLabel.numberOfLines = 2 let enterLabel = UILabel() enterLabel.text = "进入" enterLabel.font = .systemFont(ofSize: 13, weight: .medium) enterLabel.textColor = AppColor.primary enterLabel.textAlignment = .right let button = UIButton(type: .custom) button.tag = index button.accessibilityLabel = "\(mode.title),\(mode.detailText)" button.addTarget(self, action: #selector(modeTapped(_:)), for: .touchUpInside) container.addSubview(titleLabel) container.addSubview(detailLabel) container.addSubview(enterLabel) container.addSubview(button) titleLabel.snp.makeConstraints { make in make.top.equalToSuperview().offset(13) make.leading.equalToSuperview().offset(16) make.trailing.lessThanOrEqualTo(enterLabel.snp.leading).offset(-12) } detailLabel.snp.makeConstraints { make in make.top.equalTo(titleLabel.snp.bottom).offset(5) make.leading.equalTo(titleLabel) make.trailing.lessThanOrEqualTo(enterLabel.snp.leading).offset(-12) make.bottom.lessThanOrEqualToSuperview().offset(-12) } enterLabel.snp.makeConstraints { make in make.trailing.equalToSuperview().offset(-16) make.centerY.equalToSuperview() make.width.equalTo(34) } button.snp.makeConstraints { make in make.edges.equalToSuperview() } container.snp.makeConstraints { make in make.height.equalTo(78) } return container } @objc private func modeTapped(_ sender: UIButton) { guard TravelAlbumOTGTransferMode.allCases.indices.contains(sender.tag) else { return } let mode = TravelAlbumOTGTransferMode.allCases[sender.tag] // 先保留回调,避免弹窗关闭释放后无法进入对应模式页面。 let completion = onModeSelected dismiss(animated: true) { completion?(mode) } } @objc private func cancelTapped() { dismiss(animated: true) } }