Improve travel album list selection layout

This commit is contained in:
2026-07-10 11:33:44 +08:00
parent b6d3207665
commit c03a625409
2 changed files with 53 additions and 15 deletions

View File

@ -23,8 +23,10 @@ final class TravelAlbumDetailViewController: BaseViewController {
private var collectionView: UICollectionView!
private var dataSource: UICollectionViewDiffableDataSource<Int, TravelAlbumMaterial>!
private let bottomBar = UIView()
private let bottomActionStack = UIStackView()
private let deleteSelectedButton = UIButton(type: .system)
private let uploadButton = UIButton(type: .system)
private var isDeleteSelectedButtonVisible = false
init(albumId: Int, api: any TravelAlbumServing = NetworkServices.shared.travelAlbumAPI) {
viewModel = TravelAlbumDetailViewModel(albumId: albumId)
@ -85,9 +87,12 @@ final class TravelAlbumDetailViewController: BaseViewController {
}
bottomBar.backgroundColor = AppColor.pageBackground
bottomActionStack.axis = .vertical
bottomActionStack.spacing = 8
configureBottomButton(deleteSelectedButton, title: "删除选中(0)", color: UIColor(hex: 0xE53935))
configureBottomButton(uploadButton, title: "上传照片", color: AppColor.primary)
deleteSelectedButton.isHidden = true
deleteSelectedButton.alpha = 0
view.addSubview(scrollContainer)
scrollContainer.addSubview(infoCard)
@ -99,24 +104,25 @@ final class TravelAlbumDetailViewController: BaseViewController {
manageCard.addSubview(selectButton)
manageCard.addSubview(collectionView)
view.addSubview(bottomBar)
bottomBar.addSubview(deleteSelectedButton)
bottomBar.addSubview(uploadButton)
bottomBar.addSubview(bottomActionStack)
bottomActionStack.addArrangedSubview(deleteSelectedButton)
bottomActionStack.addArrangedSubview(uploadButton)
}
override func setupConstraints() {
bottomBar.snp.makeConstraints { make in
make.leading.trailing.bottom.equalToSuperview()
}
deleteSelectedButton.snp.makeConstraints { make in
bottomActionStack.snp.makeConstraints { make in
make.top.equalToSuperview().offset(12)
make.leading.trailing.equalToSuperview().inset(20)
make.height.equalTo(48)
make.bottom.equalTo(view.safeAreaLayoutGuide).offset(-12)
}
deleteSelectedButton.snp.makeConstraints { make in
make.height.equalTo(48).priority(.high)
}
uploadButton.snp.makeConstraints { make in
make.top.equalTo(deleteSelectedButton.snp.bottom).offset(8)
make.leading.trailing.equalTo(deleteSelectedButton)
make.height.equalTo(48)
make.bottom.equalTo(view.safeAreaLayoutGuide).offset(-12)
make.height.equalTo(48).priority(.high)
}
scrollContainer.snp.makeConstraints { make in
make.top.equalTo(view.safeAreaLayoutGuide).offset(12)
@ -189,12 +195,15 @@ final class TravelAlbumDetailViewController: BaseViewController {
selectButton.isHidden = viewModel.selectedTab != .all
selectButton.setImage(UIImage(systemName: viewModel.isSelectionMode ? "checkmark.circle.fill" : "circle"), for: .normal)
selectButton.tintColor = viewModel.isSelectionMode ? AppColor.primary : AppColor.textTertiary
deleteSelectedButton.isHidden = !(viewModel.isSelectionMode && !viewModel.selectedMaterialIds.isEmpty)
deleteSelectedButton.setTitle("删除选中(\(viewModel.selectedMaterialIds.count))", for: .normal)
setDeleteSelectedButtonVisible(viewModel.isSelectionMode && !viewModel.selectedMaterialIds.isEmpty)
var snapshot = NSDiffableDataSourceSnapshot<Int, TravelAlbumMaterial>()
snapshot.appendSections([0])
snapshot.appendItems(viewModel.materials)
if !snapshot.itemIdentifiers.isEmpty {
snapshot.reconfigureItems(snapshot.itemIdentifiers)
}
dataSource.apply(snapshot, animatingDifferences: true)
if viewModel.isLoading && viewModel.album == nil {
@ -231,6 +240,29 @@ final class TravelAlbumDetailViewController: BaseViewController {
button.layer.cornerRadius = 10
}
private func setDeleteSelectedButtonVisible(_ visible: Bool) {
guard visible != isDeleteSelectedButtonVisible else { return }
isDeleteSelectedButtonVisible = visible
let changes = {
self.deleteSelectedButton.isHidden = !visible
self.deleteSelectedButton.alpha = visible ? 1 : 0
self.view.layoutIfNeeded()
}
guard view.window != nil else {
changes()
return
}
view.layoutIfNeeded()
UIView.animate(
withDuration: 0.25,
delay: 0,
options: [.curveEaseInOut, .beginFromCurrentState],
animations: changes
)
}
private func makeLayout() -> UICollectionViewCompositionalLayout {
UICollectionViewCompositionalLayout { _, environment in
let spacing: CGFloat = 8