feat: 美化图片预览工具栏

This commit is contained in:
2026-08-13 14:23:10 +08:00
parent f2a005e008
commit 109ec3dad0
2 changed files with 80 additions and 19 deletions
@@ -129,9 +129,9 @@ final class TravelAlbumPhotoPreviewViewController: UIViewController {
forCellWithReuseIdentifier: TravelAlbumPreviewImageCell.reuseIdentifier
)
topChrome.backgroundColor = .black
topChrome.backgroundColor = UIColor.black.withAlphaComponent(0.82)
topChrome.accessibilityIdentifier = "travelAlbum.previewTopChrome"
bottomChrome.backgroundColor = .black
bottomChrome.backgroundColor = UIColor.black.withAlphaComponent(0.82)
bottomChrome.accessibilityIdentifier = "travelAlbum.previewBottomChrome"
divider.backgroundColor = UIColor.white.withAlphaComponent(0.12)
@@ -179,6 +179,15 @@ final class TravelAlbumPhotoPreviewViewController: UIViewController {
actionStack.axis = .horizontal
actionStack.distribution = .fillEqually
actionStack.alignment = .fill
actionStack.spacing = 10
actionStack.isLayoutMarginsRelativeArrangement = true
actionStack.directionalLayoutMargins = NSDirectionalEdgeInsets(
top: 9,
leading: 0,
bottom: 9,
trailing: 0
)
actionStack.accessibilityIdentifier = "travelAlbum.previewActionStack"
configureHighResolutionButton()
configureActions()
@@ -251,7 +260,7 @@ final class TravelAlbumPhotoPreviewViewController: UIViewController {
}
actionStack.snp.makeConstraints { make in
make.top.equalTo(variantControls.snp.bottom)
make.leading.trailing.equalToSuperview().inset(8)
make.leading.trailing.equalToSuperview().inset(16)
make.height.equalTo(70)
make.bottom.equalTo(view.safeAreaLayoutGuide)
}
@@ -275,19 +284,30 @@ final class TravelAlbumPhotoPreviewViewController: UIViewController {
}
private func configureActions() {
let aiButton = makeActionButton(title: "AI修图", systemName: "tag", color: .white)
let aiButton = makeActionButton(
title: "AI修图",
systemName: "wand.and.stars",
foregroundColor: .white,
backgroundColor: UIColor(hex: 0x1677FF),
strokeColor: UIColor(hex: 0x4096FF)
)
aiButton.accessibilityIdentifier = "travelAlbum.previewAIRetouchButton"
let deleteConfiguration = makeActionButton(
title: "删除",
systemName: "trash",
color: .white
foregroundColor: UIColor(hex: 0xFF6B6B),
backgroundColor: UIColor(hex: 0x211719),
strokeColor: UIColor(hex: 0x4A292D)
).configuration
deleteButton.configuration = deleteConfiguration
deleteButton.accessibilityLabel = "删除"
deleteButton.accessibilityIdentifier = "travelAlbum.previewDeleteButton"
refreshButton.configuration = makeActionButton(
title: "刷新",
systemName: "arrow.counterclockwise.circle",
color: .white
systemName: "arrow.clockwise",
foregroundColor: UIColor.white.withAlphaComponent(0.92),
backgroundColor: UIColor(hex: 0x1C1C1E),
strokeColor: UIColor.white.withAlphaComponent(0.1)
).configuration
refreshButton.accessibilityLabel = "刷新"
refreshButton.accessibilityIdentifier = "travelAlbum.previewRefreshButton"
@@ -297,21 +317,31 @@ final class TravelAlbumPhotoPreviewViewController: UIViewController {
[aiButton, deleteButton, refreshButton].forEach(actionStack.addArrangedSubview)
}
private func makeActionButton(title: String, systemName: String, color: UIColor) -> UIButton {
var configuration = UIButton.Configuration.plain()
private func makeActionButton(
title: String,
systemName: String,
foregroundColor: UIColor,
backgroundColor: UIColor,
strokeColor: UIColor
) -> UIButton {
var configuration = UIButton.Configuration.filled()
configuration.title = title
configuration.image = UIImage(systemName: systemName)
configuration.imagePlacement = .top
configuration.imagePadding = 8
configuration.imagePlacement = .leading
configuration.imagePadding = 7
configuration.preferredSymbolConfigurationForImage = UIImage.SymbolConfiguration(
pointSize: 25,
weight: .regular
pointSize: 18,
weight: .semibold
)
configuration.baseForegroundColor = color
configuration.contentInsets = NSDirectionalEdgeInsets(top: 5, leading: 6, bottom: 8, trailing: 6)
configuration.baseForegroundColor = foregroundColor
configuration.baseBackgroundColor = backgroundColor
configuration.background.cornerRadius = 14
configuration.background.strokeColor = strokeColor
configuration.background.strokeWidth = 1
configuration.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 10, bottom: 0, trailing: 10)
configuration.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer { attributes in
var attributes = attributes
attributes.font = .systemFont(ofSize: 14, weight: .regular)
attributes.font = .systemFont(ofSize: 14, weight: .semibold)
return attributes
}
let button = UIButton(configuration: configuration)
@@ -792,7 +822,7 @@ final class TravelAlbumPhotoPreviewViewController: UIViewController {
refreshButton.accessibilityValue = isRefreshingProject ? "刷新中" : nil
var configuration = refreshButton.configuration
configuration?.showsActivityIndicator = isRefreshingProject
configuration?.image = isRefreshingProject ? nil : UIImage(systemName: "arrow.counterclockwise.circle")
configuration?.image = isRefreshingProject ? nil : UIImage(systemName: "arrow.clockwise")
configuration?.title = isRefreshingProject ? "刷新中" : "刷新"
refreshButton.configuration = configuration
}
@@ -278,15 +278,46 @@ final class TravelAlbumDetailViewControllerTests: XCTestCase {
$0.accessibilityIdentifier == "travelAlbum.previewBackButton"
} as? UIButton
)
let actionStack = try XCTUnwrap(
controller.view.findSubview {
$0.accessibilityIdentifier == "travelAlbum.previewActionStack"
} as? UIStackView
)
let aiRetouchButton = try XCTUnwrap(
controller.view.findSubview {
$0.accessibilityIdentifier == "travelAlbum.previewAIRetouchButton"
} as? UIButton
)
let deleteButton = try XCTUnwrap(
controller.view.findSubview {
$0.accessibilityIdentifier == "travelAlbum.previewDeleteButton"
} as? UIButton
)
let refreshButton = try XCTUnwrap(
controller.view.findSubview {
$0.accessibilityIdentifier == "travelAlbum.previewRefreshButton"
} as? UIButton
)
XCTAssertFalse(controller.prefersStatusBarHidden)
XCTAssertEqual(topChrome.backgroundColor, .black)
XCTAssertEqual(bottomChrome.backgroundColor, .black)
XCTAssertEqual(topChrome.backgroundColor, UIColor.black.withAlphaComponent(0.82))
XCTAssertEqual(bottomChrome.backgroundColor, UIColor.black.withAlphaComponent(0.82))
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(actionStack.spacing, 10)
XCTAssertTrue(actionStack.isLayoutMarginsRelativeArrangement)
XCTAssertEqual(actionStack.directionalLayoutMargins.top, 9)
XCTAssertEqual(actionStack.arrangedSubviews, [aiRetouchButton, deleteButton, refreshButton])
XCTAssertEqual(aiRetouchButton.bounds.height, 52, accuracy: 0.5)
XCTAssertEqual(deleteButton.bounds.height, 52, accuracy: 0.5)
XCTAssertEqual(refreshButton.bounds.height, 52, accuracy: 0.5)
XCTAssertEqual(aiRetouchButton.configuration?.baseBackgroundColor?.travelAlbumTestHexRGB, 0x1677FF)
XCTAssertEqual(deleteButton.configuration?.baseForegroundColor?.travelAlbumTestHexRGB, 0xFF6B6B)
XCTAssertEqual(refreshButton.configuration?.baseBackgroundColor?.travelAlbumTestHexRGB, 0x1C1C1E)
XCTAssertEqual(aiRetouchButton.configuration?.imagePlacement, .leading)
XCTAssertEqual(collectionView.frame, controller.view.bounds)
XCTAssertLessThan(collectionView.frame.minY, topChrome.frame.maxY)
XCTAssertGreaterThan(collectionView.frame.maxY, bottomChrome.frame.minY)