From 109ec3dad07067029880d54c7a8967702e8146ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B1=89=E7=A7=8B?= <497055328@qq.com> Date: Thu, 13 Aug 2026 14:23:10 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=BE=8E=E5=8C=96=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E9=A2=84=E8=A7=88=E5=B7=A5=E5=85=B7=E6=A0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ravelAlbumPhotoPreviewViewController.swift | 64 ++++++++++++++----- ...TravelAlbumDetailViewControllerTests.swift | 35 +++++++++- 2 files changed, 80 insertions(+), 19 deletions(-) diff --git a/suixinkan/UI/TravelAlbum/TravelAlbumPhotoPreviewViewController.swift b/suixinkan/UI/TravelAlbum/TravelAlbumPhotoPreviewViewController.swift index b770127..59f7272 100644 --- a/suixinkan/UI/TravelAlbum/TravelAlbumPhotoPreviewViewController.swift +++ b/suixinkan/UI/TravelAlbum/TravelAlbumPhotoPreviewViewController.swift @@ -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 } diff --git a/suixinkanTests/TravelAlbumDetailViewControllerTests.swift b/suixinkanTests/TravelAlbumDetailViewControllerTests.swift index 3b493f5..c207b5e 100644 --- a/suixinkanTests/TravelAlbumDetailViewControllerTests.swift +++ b/suixinkanTests/TravelAlbumDetailViewControllerTests.swift @@ -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)