// // LNEditProfilePhotoWallView.swift // Lanu // // Created by OneeChan on 2025/12/19. // import Foundation import UIKit import SnapKit protocol LNEditProfilePhotoWallViewDelegate: AnyObject { func onEditProfilePhotoWallViewDidChanged(view: LNEditProfilePhotoWallView) } class LNEditProfilePhotoWallView: UIView { private let maxCount = 9 private let stackView = UIStackView() private let addImageButton = UIButton() private let photoWallCountLabel = UILabel() weak var delegate: LNEditProfilePhotoWallViewDelegate? var curPhotos: [String] { let imageViews = stackView.arrangedSubviews.filter { $0 is LNImageUploadView } as! [LNImageUploadView] return imageViews.compactMap { $0.imageUrl } } override init(frame: CGRect) { super.init(frame: frame) setupViews() } func loadImages(_ urls: [String]) { for url in urls { let imageView = buildImageView() imageView.loadImage(url: url) stackView.addArrangedSubview(imageView) imageView.snp.makeConstraints { make in make.height.equalToSuperview() make.width.equalTo(imageView.snp.height) } } updateImageCount() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } } extension LNEditProfilePhotoWallView: LNImageUploadViewDelegate { func onImageUploadView(view: LNImageUploadView, didUploadImage url: String) { delegate?.onEditProfilePhotoWallViewDidChanged(view: self) } func onImageUploadViewDidClickDelete(view: LNImageUploadView) { stackView.removeArrangedSubview(view) view.removeFromSuperview() delegate?.onEditProfilePhotoWallViewDidChanged(view: self) updateImageCount() } } extension LNEditProfilePhotoWallView { private func updateImageCount() { let imageViews = stackView.arrangedSubviews.filter { $0 is LNImageUploadView } photoWallCountLabel.text = .init(key: "A00190", imageViews.count, 9) addImageButton.isHidden = imageViews.count >= maxCount } private func setupViews() { clipsToBounds = false photoWallCountLabel.font = .heading_h4 photoWallCountLabel.textColor = .text_5 photoWallCountLabel.text = .init(key: "A00190", 0, 9) addSubview(photoWallCountLabel) photoWallCountLabel.snp.makeConstraints { make in make.horizontalEdges.equalToSuperview() make.top.equalToSuperview().offset(10) } let descLabel = UILabel() descLabel.text = .init(key: "A00191") descLabel.font = .body_s descLabel.textColor = .text_4 descLabel.numberOfLines = 0 addSubview(descLabel) descLabel.snp.makeConstraints { make in make.horizontalEdges.equalToSuperview() make.top.equalTo(photoWallCountLabel.snp.bottom).offset(4) } let scrollView = UIScrollView() scrollView.showsVerticalScrollIndicator = false scrollView.showsHorizontalScrollIndicator = false scrollView.clipsToBounds = false addSubview(scrollView) scrollView.snp.makeConstraints { make in make.horizontalEdges.equalToSuperview() make.top.equalTo(descLabel.snp.bottom).offset(10) make.bottom.equalToSuperview() make.height.equalTo(100) } stackView.axis = .horizontal stackView.spacing = 6 scrollView.addSubview(stackView) stackView.snp.makeConstraints { make in make.horizontalEdges.equalToSuperview() make.verticalEdges.equalToSuperview() make.height.equalToSuperview() } let config = UIImage.SymbolConfiguration(pointSize: 17) addImageButton.backgroundColor = .fill_1 addImageButton.layer.cornerRadius = 8.33 addImageButton.setImage(.init(systemName: "plus", withConfiguration: config), for: .normal) addImageButton.tintColor = .text_3 addImageButton.addAction(UIAction(handler: { [weak self] _ in guard let self else { return } LNBottomSheetMenu.showImageSelectMenu(view: self) { [weak self] image, _ in guard let self else { return } guard let image = image?.compress(type: .photoWall) else { return } let imageView = buildImageView() imageView.uploadImage(image: image) stackView.insertArrangedSubview(imageView, at: 1) imageView.snp.makeConstraints { make in make.height.equalToSuperview() make.width.equalTo(imageView.snp.height) } updateImageCount() } }), for: .touchUpInside) stackView.addArrangedSubview(addImageButton) addImageButton.snp.makeConstraints { make in make.height.equalToSuperview() make.width.equalTo(addImageButton.snp.height) } } private func buildImageView() -> LNImageUploadView { let imageView = LNImageUploadView() imageView.uploadType = .cover imageView.layer.cornerRadius = 8.33 imageView.clipsToBounds = true imageView.showClearButton = true imageView.delegate = self return imageView } }