feat: 优化AI修图模板选择界面

This commit is contained in:
2026-08-11 17:04:51 +08:00
parent aca19a53fb
commit 010add828b
4 changed files with 593 additions and 77 deletions
@@ -296,7 +296,33 @@ final class TravelAlbumDetailViewControllerTests: XCTestCase {
await waitUntil { confirmButton.isEnabled }
controller.view.layoutIfNeeded()
let selectionCountLabel = try XCTUnwrap(
controller.view.findSubview {
$0.accessibilityIdentifier == "travelAlbum.aiRetouchSelectionCountLabel"
} as? UILabel
)
let tipsLabel = try XCTUnwrap(
controller.view.findSubview {
$0.accessibilityIdentifier == "travelAlbum.aiRetouchTipsLabel"
} as? UILabel
)
let tipsContainer = try XCTUnwrap(
controller.view.findSubview {
$0.accessibilityIdentifier == "travelAlbum.aiRetouchTipsContainer"
}
)
XCTAssertTrue(collectionView.collectionViewLayout is UICollectionViewCompositionalLayout)
XCTAssertEqual(selectionCountLabel.text, "已选择 4 张照片")
XCTAssertEqual(
tipsLabel.text,
"Tips:本次显示 3 类风格。每张照片生成「精修后 + 氛围感」2 个结果,第一张照片另生成所选封面结果。"
)
XCTAssertFalse(tipsContainer.isHidden)
XCTAssertEqual(tipsContainer.backgroundColor?.travelAlbumTestHexRGB, 0xEAF3FF)
XCTAssertEqual(tipsLabel.textColor.travelAlbumTestHexRGB, 0x385778)
XCTAssertEqual(tipsContainer.layer.cornerRadius, 10)
XCTAssertTrue(tipsContainer.isDescendant(of: collectionView))
XCTAssertFalse(bottomBar.isDescendant(of: collectionView))
XCTAssertEqual(cancelButton.configuration?.title, "取消")
XCTAssertEqual(confirmButton.configuration?.title, "确定")
@@ -327,29 +353,47 @@ final class TravelAlbumDetailViewControllerTests: XCTestCase {
await waitUntil { !viewModel.isLoading && api.aiRetouchTemplateScenicIds.count == 1 }
controller.view.layoutIfNeeded()
let collectionView = try XCTUnwrap(
controller.view.findSubview {
$0.accessibilityIdentifier == "travelAlbum.aiRetouchTemplateCollection"
} as? UICollectionView
)
let accessibleLabels = controller.view.allAccessibilityLabels()
XCTAssertTrue(accessibleLabels.contains("原图精修"))
XCTAssertTrue(accessibleLabels.contains("氛围感修图,选填"))
XCTAssertTrue(accessibleLabels.contains("封面风格模板"))
XCTAssertTrue(accessibleLabels.contains("封面风格模板,赠送 · 不占精修张数"))
collectionView.scrollToItem(
at: IndexPath(item: 0, section: 4),
at: .top,
animated: false
)
controller.view.layoutIfNeeded()
let quotaLabel = try XCTUnwrap(
controller.view.findSubview {
$0.accessibilityIdentifier == "travelAlbum.aiRetouchRemainingQuotaLabel"
} as? UILabel
)
XCTAssertEqual(quotaLabel.text, "剩余 8 次")
XCTAssertEqual(quotaLabel.accessibilityLabel, "剩余8次修图额度")
XCTAssertEqual(quotaLabel.text, "剩余 8 张")
XCTAssertEqual(quotaLabel.accessibilityLabel, "剩余8张修图额度")
}
func testAIRetouchTemplateCellExposesSelectedState() {
let cell = TravelAlbumAIRetouchTemplateCell(frame: .zero)
let template = TravelAlbumAIRetouchTemplate(id: 1, name: "清透", previewURL: "")
var previewTapped = false
cell.onPreviewTapped = { previewTapped = true }
cell.apply(template: template, selected: true)
let previewButton = cell.findSubview {
$0.accessibilityIdentifier == "travelAlbum.aiRetouchTemplatePreviewButton"
} as? UIButton
previewButton?.sendActions(for: .touchUpInside)
XCTAssertEqual(cell.contentView.layer.borderWidth, 2)
XCTAssertTrue(cell.accessibilityTraits.contains(.selected))
XCTAssertEqual(cell.accessibilityValue, "已选择")
XCTAssertTrue(previewTapped)
cell.apply(template: template, selected: false)
@@ -358,6 +402,37 @@ final class TravelAlbumDetailViewControllerTests: XCTestCase {
XCTAssertEqual(cell.accessibilityValue, "未选择")
}
func testAIRetouchTemplatePreviewUsesImmersiveZoomableLayout() throws {
let template = TravelAlbumAIRetouchTemplate(
id: 2,
name: "简约留白",
previewURL: ""
)
let controller = TravelAlbumAIRetouchTemplatePreviewViewController(template: template)
controller.loadViewIfNeeded()
controller.view.frame = CGRect(x: 0, y: 0, width: 390, height: 844)
controller.view.layoutIfNeeded()
let scrollView = try XCTUnwrap(
controller.view.findSubview {
$0.accessibilityIdentifier == "travelAlbum.aiRetouchTemplatePreviewScrollView"
} as? UIScrollView
)
let backButton = try XCTUnwrap(
controller.view.findSubview {
$0.accessibilityIdentifier == "travelAlbum.aiRetouchTemplatePreviewBackButton"
} as? UIButton
)
XCTAssertEqual(controller.view.backgroundColor, .black)
XCTAssertTrue(controller.view.allLabels().contains { $0.text == "简约留白" })
XCTAssertTrue(controller.view.allLabels().contains { $0.text == "双指缩放查看细节" })
XCTAssertEqual(scrollView.minimumZoomScale, 1)
XCTAssertEqual(scrollView.maximumZoomScale, 4)
XCTAssertGreaterThanOrEqual(backButton.bounds.width, 44)
XCTAssertGreaterThanOrEqual(backButton.bounds.height, 44)
}
func testPreviewAIRetouchUsesSelectedRetouchedTabWorkflowAndStaysPresented() async throws {
UIView.setAnimationsEnabled(false)
defer { UIView.setAnimationsEnabled(true) }
@@ -424,9 +499,29 @@ final class TravelAlbumDetailViewControllerTests: XCTestCase {
sheet.view.frame = CGRect(x: 0, y: 0, width: 390, height: 844)
sheet.view.layoutIfNeeded()
let labels = sheet.view.allAccessibilityLabels()
XCTAssertTrue(labels.contains("原图精修"))
XCTAssertFalse(labels.contains { $0.contains("氛围感修图") })
let visibleLabelTexts = sheet.view.allLabels().compactMap { label in
label.isHidden ? nil : label.text
}
XCTAssertTrue(visibleLabelTexts.contains("原图精修"))
XCTAssertFalse(visibleLabelTexts.contains { $0.contains("氛围感修图") })
let selectionCountLabel = try XCTUnwrap(
sheet.view.findSubview {
$0.accessibilityIdentifier == "travelAlbum.aiRetouchSelectionCountLabel"
} as? UILabel
)
let tipsLabel = try XCTUnwrap(
sheet.view.findSubview {
$0.accessibilityIdentifier == "travelAlbum.aiRetouchTipsLabel"
} as? UILabel
)
let tipsContainer = try XCTUnwrap(
sheet.view.findSubview {
$0.accessibilityIdentifier == "travelAlbum.aiRetouchTipsContainer"
}
)
XCTAssertEqual(selectionCountLabel.text, "已选择 1 张照片")
XCTAssertTrue(tipsContainer.isHidden)
XCTAssertTrue(tipsLabel.isHidden)
confirmButton.sendActions(for: .touchUpInside)
await waitUntil { api.aiReretouchRequests.count == 1 }
await waitUntil { controller.presentedViewController == nil }