feat: 优化相册图片预览交互

This commit is contained in:
2026-08-12 10:58:53 +08:00
parent 010add828b
commit 05cfdc3662
2 changed files with 356 additions and 81 deletions
@@ -184,12 +184,13 @@ final class TravelAlbumDetailViewControllerTests: XCTestCase {
controller.view.frame = CGRect(x: 0, y: 0, width: 390, height: 844)
controller.view.layoutIfNeeded()
let retouchedButton = try XCTUnwrap(
let segmentedControl = try XCTUnwrap(
controller.view.findSubview {
($0 as? UIButton)?.accessibilityLabel == "精修后"
} as? UIButton
$0.accessibilityIdentifier == "travelAlbum.previewVariantSegmentedControl"
} as? UISegmentedControl
)
retouchedButton.sendActions(for: .touchUpInside)
segmentedControl.selectedSegmentIndex = 1
segmentedControl.sendActions(for: .valueChanged)
controller.view.layoutIfNeeded()
let imageView = try XCTUnwrap(
@@ -205,6 +206,148 @@ final class TravelAlbumDetailViewControllerTests: XCTestCase {
XCTAssertFalse(imageView.constraintsAffectingLayout(for: .vertical).isEmpty)
}
func testPreviewUsesScreenshotChromeAndConstrainedImageViewport() throws {
UIView.setAnimationsEnabled(false)
defer { UIView.setAnimationsEnabled(true) }
let project = TravelAlbumPreviewProject(
originalMaterialId: 1,
assets: [
TravelAlbumPreviewAsset(
id: "original-1",
kind: .original,
fileURL: "https://example.com/original.jpg",
coverURL: "https://example.com/cover.jpg",
fileName: "IMG_0002.jpeg",
fileSize: 2_516_582
),
TravelAlbumPreviewAsset(
id: "retouched-1",
kind: .retouched,
fileURL: "",
coverURL: "",
fileName: "IMG_0002.jpeg",
fileSize: 2_516_582
),
TravelAlbumPreviewAsset(
id: "atmosphere-1",
kind: .atmosphere,
fileURL: "",
coverURL: "",
fileName: "IMG_0002.jpeg",
fileSize: 2_516_582
),
]
)
let controller = TravelAlbumPhotoPreviewViewController(
projects: [project],
totalCount: 10,
startProjectIndex: 0
)
controller.loadViewIfNeeded()
controller.view.frame = CGRect(x: 0, y: 0, width: 390, height: 844)
controller.view.layoutIfNeeded()
let topChrome = try XCTUnwrap(
controller.view.findSubview {
$0.accessibilityIdentifier == "travelAlbum.previewTopChrome"
}
)
let bottomChrome = try XCTUnwrap(
controller.view.findSubview {
$0.accessibilityIdentifier == "travelAlbum.previewBottomChrome"
}
)
let collectionView = try XCTUnwrap(
controller.view.findSubview {
$0.accessibilityIdentifier == "travelAlbum.previewCollectionView"
} as? UICollectionView
)
let highResolutionButton = try XCTUnwrap(
controller.view.findSubview {
$0.accessibilityIdentifier == "travelAlbum.previewHighResolutionButton"
} as? UIButton
)
let segmentedControl = try XCTUnwrap(
controller.view.findSubview {
$0.accessibilityIdentifier == "travelAlbum.previewVariantSegmentedControl"
} as? UISegmentedControl
)
let backButton = try XCTUnwrap(
controller.view.findSubview {
$0.accessibilityIdentifier == "travelAlbum.previewBackButton"
} as? UIButton
)
XCTAssertFalse(controller.prefersStatusBarHidden)
XCTAssertEqual(topChrome.backgroundColor, .black)
XCTAssertEqual(bottomChrome.backgroundColor, .black)
XCTAssertEqual(highResolutionButton.configuration?.title, "查看高清图")
XCTAssertEqual(segmentedControl.numberOfSegments, 3)
XCTAssertEqual(segmentedControl.selectedSegmentIndex, 0)
XCTAssertEqual(backButton.bounds.size, CGSize(width: 44, height: 44))
XCTAssertNil(backButton.configuration?.baseBackgroundColor)
XCTAssertEqual(collectionView.frame.minY, topChrome.frame.maxY, accuracy: 0.5)
XCTAssertEqual(collectionView.frame.maxY, bottomChrome.frame.minY, accuracy: 0.5)
XCTAssertTrue(controller.view.allLabels().contains { $0.text == "IMG_0002.jpeg" })
XCTAssertTrue(controller.view.allLabels().contains { $0.text == "2.4MB" })
XCTAssertTrue(controller.view.allLabels().contains { $0.text == "1/10" })
highResolutionButton.sendActions(for: .touchUpInside)
XCTAssertEqual(topChrome.alpha, 0)
XCTAssertEqual(bottomChrome.alpha, 0)
}
func testPreviewHidesVariantControlsAndHighResolutionButtonWithoutVariants() throws {
let project = TravelAlbumPreviewProject(
originalMaterialId: 1,
assets: [
TravelAlbumPreviewAsset(
id: "original-1",
kind: .original,
fileURL: "https://example.com/original.jpg",
coverURL: "https://example.com/cover.jpg",
fileName: "IMG_0002.jpeg",
fileSize: 2_516_582
),
]
)
let controller = TravelAlbumPhotoPreviewViewController(
projects: [project],
totalCount: 1,
startProjectIndex: 0
)
controller.loadViewIfNeeded()
controller.view.frame = CGRect(x: 0, y: 0, width: 390, height: 844)
controller.view.layoutIfNeeded()
let segmentedControl = try XCTUnwrap(
controller.view.findSubview {
$0.accessibilityIdentifier == "travelAlbum.previewVariantSegmentedControl"
} as? UISegmentedControl
)
let highResolutionButton = try XCTUnwrap(
controller.view.findSubview {
$0.accessibilityIdentifier == "travelAlbum.previewHighResolutionButton"
} as? UIButton
)
let collectionView = try XCTUnwrap(
controller.view.findSubview {
$0.accessibilityIdentifier == "travelAlbum.previewCollectionView"
} as? UICollectionView
)
let bottomChrome = try XCTUnwrap(
controller.view.findSubview {
$0.accessibilityIdentifier == "travelAlbum.previewBottomChrome"
}
)
XCTAssertTrue(segmentedControl.isHidden)
XCTAssertTrue(highResolutionButton.isHidden)
XCTAssertEqual(bottomChrome.frame.minY - collectionView.frame.maxY, 56, accuracy: 0.5)
}
func testSelectionModeShowsAIRetouchOnLeftAndDeleteOnRight() async throws {
let controller = TravelAlbumDetailViewController(albumId: 0)
controller.loadViewIfNeeded()
@@ -479,10 +622,13 @@ final class TravelAlbumDetailViewControllerTests: XCTestCase {
controller.loadViewIfNeeded()
controller.view.layoutIfNeeded()
let retouchedButton = try XCTUnwrap(
controller.view.findSubview { ($0 as? UIButton)?.accessibilityLabel == "精修后" } as? UIButton
let segmentedControl = try XCTUnwrap(
controller.view.findSubview {
$0.accessibilityIdentifier == "travelAlbum.previewVariantSegmentedControl"
} as? UISegmentedControl
)
retouchedButton.sendActions(for: .touchUpInside)
segmentedControl.selectedSegmentIndex = 1
segmentedControl.sendActions(for: .valueChanged)
let aiButton = try XCTUnwrap(
controller.view.findSubview { ($0 as? UIButton)?.accessibilityLabel == "AI修图" } as? UIButton
)
@@ -563,10 +709,13 @@ final class TravelAlbumDetailViewControllerTests: XCTestCase {
controller.loadViewIfNeeded()
controller.view.frame = CGRect(x: 0, y: 0, width: 390, height: 844)
controller.view.layoutIfNeeded()
let retouchedButton = try XCTUnwrap(
controller.view.findSubview { ($0 as? UIButton)?.accessibilityLabel == "精修后" } as? UIButton
let segmentedControl = try XCTUnwrap(
controller.view.findSubview {
$0.accessibilityIdentifier == "travelAlbum.previewVariantSegmentedControl"
} as? UISegmentedControl
)
retouchedButton.sendActions(for: .touchUpInside)
segmentedControl.selectedSegmentIndex = 1
segmentedControl.sendActions(for: .valueChanged)
let refreshButton = try XCTUnwrap(
controller.view.findSubview {
$0.accessibilityIdentifier == "travelAlbum.previewRefreshButton"
@@ -575,18 +724,12 @@ final class TravelAlbumDetailViewControllerTests: XCTestCase {
refreshButton.sendActions(for: .touchUpInside)
await waitUntil { reloadCount == 1 && refreshButton.isEnabled }
XCTAssertTrue(
controller.view.findSubview {
($0 as? UIButton)?.accessibilityLabel == "精修后"
&& $0.accessibilityTraits.contains(.selected)
} != nil
)
XCTAssertEqual(segmentedControl.selectedSegmentIndex, 1)
refreshButton.sendActions(for: .touchUpInside)
await waitUntil { reloadCount == 2 && refreshButton.isEnabled }
XCTAssertNil(
controller.view.findSubview { ($0 as? UIButton)?.accessibilityLabel == "精修后" }
)
XCTAssertTrue(segmentedControl.isHidden)
XCTAssertEqual(segmentedControl.numberOfSegments, 0)
XCTAssertTrue(controller.view.allLabels().contains { $0.text == "原图.jpg" })
}