feat: add AI retouch before-after comparison
This commit is contained in:
@@ -434,8 +434,13 @@ final class TravelAlbumAIRetouchTemplateViewController: BaseViewController {
|
||||
}
|
||||
|
||||
private func showPreview(for template: TravelAlbumAIRetouchTemplate) {
|
||||
let controller = TravelAlbumAIRetouchTemplatePreviewViewController(template: template)
|
||||
controller.modalPresentationStyle = .fullScreen
|
||||
guard let content = template.comparisonContent else {
|
||||
showToast("暂无对比预览")
|
||||
return
|
||||
}
|
||||
let controller = BeforeAfterComparisonViewController(
|
||||
viewModel: BeforeAfterComparisonViewModel(content: content)
|
||||
)
|
||||
present(controller, animated: true)
|
||||
}
|
||||
}
|
||||
@@ -908,128 +913,6 @@ final class TravelAlbumAIRetouchSectionHeader: UICollectionReusableView {
|
||||
}
|
||||
}
|
||||
|
||||
/// AI 修图模板全屏预览,支持双指缩放查看模板细节。
|
||||
final class TravelAlbumAIRetouchTemplatePreviewViewController: UIViewController {
|
||||
private let template: TravelAlbumAIRetouchTemplate
|
||||
private let backButton = UIButton(type: .system)
|
||||
private let titleLabel = UILabel()
|
||||
private let subtitleLabel = UILabel()
|
||||
private let scrollView = UIScrollView()
|
||||
private let imageView = UIImageView()
|
||||
|
||||
/// 创建指定模板的全屏预览页。
|
||||
init(template: TravelAlbumAIRetouchTemplate) {
|
||||
self.template = template
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
modalPresentationStyle = .fullScreen
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
setupUI()
|
||||
setupConstraints()
|
||||
loadPreview()
|
||||
}
|
||||
|
||||
private func setupUI() {
|
||||
view.backgroundColor = .black
|
||||
view.accessibilityIdentifier = "travelAlbum.aiRetouchTemplatePreview"
|
||||
|
||||
var backConfiguration = UIButton.Configuration.filled()
|
||||
backConfiguration.image = UIImage(systemName: "chevron.left")
|
||||
backConfiguration.baseForegroundColor = .white
|
||||
backConfiguration.baseBackgroundColor = UIColor.white.withAlphaComponent(0.12)
|
||||
backConfiguration.background.cornerRadius = 24
|
||||
backButton.configuration = backConfiguration
|
||||
backButton.accessibilityLabel = "返回模板选择"
|
||||
backButton.accessibilityIdentifier = "travelAlbum.aiRetouchTemplatePreviewBackButton"
|
||||
backButton.addTarget(self, action: #selector(backTapped), for: .touchUpInside)
|
||||
|
||||
titleLabel.text = template.name
|
||||
titleLabel.textColor = .white
|
||||
titleLabel.font = .systemFont(ofSize: 20, weight: .semibold)
|
||||
titleLabel.textAlignment = .center
|
||||
titleLabel.lineBreakMode = .byTruncatingTail
|
||||
|
||||
subtitleLabel.text = "双指缩放查看细节"
|
||||
subtitleLabel.textColor = UIColor.white.withAlphaComponent(0.52)
|
||||
subtitleLabel.font = .systemFont(ofSize: 14, weight: .regular)
|
||||
subtitleLabel.textAlignment = .center
|
||||
|
||||
scrollView.minimumZoomScale = 1
|
||||
scrollView.maximumZoomScale = 4
|
||||
scrollView.delegate = self
|
||||
scrollView.showsHorizontalScrollIndicator = false
|
||||
scrollView.showsVerticalScrollIndicator = false
|
||||
scrollView.accessibilityIdentifier = "travelAlbum.aiRetouchTemplatePreviewScrollView"
|
||||
imageView.contentMode = .scaleAspectFit
|
||||
imageView.clipsToBounds = true
|
||||
imageView.backgroundColor = UIColor(hex: 0x111111)
|
||||
imageView.accessibilityLabel = "\(template.name)模板预览图"
|
||||
|
||||
view.addSubview(backButton)
|
||||
view.addSubview(titleLabel)
|
||||
view.addSubview(subtitleLabel)
|
||||
view.addSubview(scrollView)
|
||||
scrollView.addSubview(imageView)
|
||||
}
|
||||
|
||||
private func setupConstraints() {
|
||||
backButton.snp.makeConstraints { make in
|
||||
make.top.equalTo(view.safeAreaLayoutGuide).offset(20)
|
||||
make.leading.equalToSuperview().offset(18)
|
||||
make.size.equalTo(48)
|
||||
}
|
||||
titleLabel.snp.makeConstraints { make in
|
||||
make.top.equalTo(view.safeAreaLayoutGuide).offset(20)
|
||||
make.leading.greaterThanOrEqualTo(backButton.snp.trailing).offset(12)
|
||||
make.centerX.equalToSuperview()
|
||||
make.trailing.lessThanOrEqualToSuperview().offset(-66)
|
||||
make.height.equalTo(26)
|
||||
}
|
||||
subtitleLabel.snp.makeConstraints { make in
|
||||
make.top.equalTo(titleLabel.snp.bottom).offset(2)
|
||||
make.centerX.equalToSuperview()
|
||||
}
|
||||
scrollView.snp.makeConstraints { make in
|
||||
make.top.equalTo(subtitleLabel.snp.bottom).offset(18)
|
||||
make.leading.trailing.bottom.equalToSuperview()
|
||||
}
|
||||
imageView.snp.makeConstraints { make in
|
||||
make.center.equalTo(scrollView.frameLayoutGuide)
|
||||
make.width.equalTo(scrollView.frameLayoutGuide)
|
||||
make.height.equalTo(imageView.snp.width).multipliedBy(0.75)
|
||||
}
|
||||
}
|
||||
|
||||
private func loadPreview() {
|
||||
let placeholder = UIImage(named: "ai_retouch_template_placeholder")
|
||||
guard let url = URL(string: template.previewURL), !template.previewURL.isEmpty else {
|
||||
imageView.image = placeholder
|
||||
return
|
||||
}
|
||||
imageView.kf.setImage(
|
||||
with: url,
|
||||
placeholder: placeholder
|
||||
)
|
||||
}
|
||||
|
||||
@objc private func backTapped() {
|
||||
dismiss(animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
extension TravelAlbumAIRetouchTemplatePreviewViewController: UIScrollViewDelegate {
|
||||
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
|
||||
imageView
|
||||
}
|
||||
}
|
||||
|
||||
/// AI 修图模板页视觉常量。
|
||||
private enum AIRetouchTemplateStyle {
|
||||
static let primary = UIColor(hex: 0x1677FF)
|
||||
|
||||
Reference in New Issue
Block a user