diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 821dc8a60..37a4a52af 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -138,7 +138,7 @@ DB9D6BE925E4F5340051B173 /* SearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D6BE825E4F5340051B173 /* SearchViewController.swift */; }; DB9D6BF825E4F5690051B173 /* NotificationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D6BF725E4F5690051B173 /* NotificationViewController.swift */; }; DB9D6BFF25E4F5940051B173 /* ProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D6BFE25E4F5940051B173 /* ProfileViewController.swift */; }; - DB9D6C0E25E4F9780051B173 /* MosaicImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D6C0D25E4F9780051B173 /* MosaicImageView.swift */; }; + DB9D6C0E25E4F9780051B173 /* MosaicImageViewContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D6C0D25E4F9780051B173 /* MosaicImageViewContainer.swift */; }; DB9D6C2425E502C60051B173 /* MosaicImageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D6C2225E502C60051B173 /* MosaicImageViewModel.swift */; }; DB9D6C2E25E504AC0051B173 /* Attachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D6C2D25E504AC0051B173 /* Attachment.swift */; }; DB9D6C3825E508BE0051B173 /* Attachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D6C3725E508BE0051B173 /* Attachment.swift */; }; @@ -340,7 +340,7 @@ DB9D6BE825E4F5340051B173 /* SearchViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchViewController.swift; sourceTree = ""; }; DB9D6BF725E4F5690051B173 /* NotificationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationViewController.swift; sourceTree = ""; }; DB9D6BFE25E4F5940051B173 /* ProfileViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileViewController.swift; sourceTree = ""; }; - DB9D6C0D25E4F9780051B173 /* MosaicImageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MosaicImageView.swift; sourceTree = ""; }; + DB9D6C0D25E4F9780051B173 /* MosaicImageViewContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MosaicImageViewContainer.swift; sourceTree = ""; }; DB9D6C2225E502C60051B173 /* MosaicImageViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MosaicImageViewModel.swift; sourceTree = ""; }; DB9D6C2D25E504AC0051B173 /* Attachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Attachment.swift; sourceTree = ""; }; DB9D6C3725E508BE0051B173 /* Attachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Attachment.swift; sourceTree = ""; }; @@ -953,7 +953,7 @@ DB9D6C1325E4F97A0051B173 /* Container */ = { isa = PBXGroup; children = ( - DB9D6C0D25E4F9780051B173 /* MosaicImageView.swift */, + DB9D6C0D25E4F9780051B173 /* MosaicImageViewContainer.swift */, ); path = Container; sourceTree = ""; @@ -1388,7 +1388,7 @@ DB0140A825C40C1500F9F3CF /* MastodonPinBasedAuthenticationViewModelNavigationDelegateShim.swift in Sources */, DB2B3AE925E38850007045F9 /* UIViewPreview.swift in Sources */, DB427DD625BAA00100D1B89D /* AppDelegate.swift in Sources */, - DB9D6C0E25E4F9780051B173 /* MosaicImageView.swift in Sources */, + DB9D6C0E25E4F9780051B173 /* MosaicImageViewContainer.swift in Sources */, DB98338725C945ED00AD9700 /* Strings.swift in Sources */, DB45FAB625CA5485005A8AC7 /* UIAlertController.swift in Sources */, DBE0821525CD382600FD6BBD /* MastodonRegisterViewController.swift in Sources */, diff --git a/Mastodon/Diffiable/Section/StatusSection.swift b/Mastodon/Diffiable/Section/StatusSection.swift index 64b49ad2b..727f4074f 100644 --- a/Mastodon/Diffiable/Section/StatusSection.swift +++ b/Mastodon/Diffiable/Section/StatusSection.swift @@ -128,14 +128,14 @@ extension StatusSection { }() if mosiacImageViewModel.metas.count == 1 { let meta = mosiacImageViewModel.metas[0] - let imageView = cell.statusView.mosaicImageView.setupImageView(aspectRatio: meta.size, maxSize: imageViewMaxSize) + let imageView = cell.statusView.statusMosaicImageView.setupImageView(aspectRatio: meta.size, maxSize: imageViewMaxSize) imageView.af.setImage( withURL: meta.url, placeholderImage: UIImage.placeholder(color: .systemFill), imageTransition: .crossDissolve(0.2) ) } else { - let imageViews = cell.statusView.mosaicImageView.setupImageViews(count: mosiacImageViewModel.metas.count, maxHeight: imageViewMaxSize.height) + let imageViews = cell.statusView.statusMosaicImageView.setupImageViews(count: mosiacImageViewModel.metas.count, maxHeight: imageViewMaxSize.height) for (i, imageView) in imageViews.enumerated() { let meta = mosiacImageViewModel.metas[i] imageView.af.setImage( @@ -145,7 +145,7 @@ extension StatusSection { ) } } - cell.statusView.mosaicImageView.isHidden = mosiacImageViewModel.metas.isEmpty + cell.statusView.statusMosaicImageView.isHidden = mosiacImageViewModel.metas.isEmpty // toolbar let replyCountTitle: String = { diff --git a/Mastodon/Scene/Share/View/Container/MosaicImageView.swift b/Mastodon/Scene/Share/View/Container/MosaicImageViewContainer.swift similarity index 90% rename from Mastodon/Scene/Share/View/Container/MosaicImageView.swift rename to Mastodon/Scene/Share/View/Container/MosaicImageViewContainer.swift index 5f8c877db..14e2012e0 100644 --- a/Mastodon/Scene/Share/View/Container/MosaicImageView.swift +++ b/Mastodon/Scene/Share/View/Container/MosaicImageViewContainer.swift @@ -1,5 +1,5 @@ // -// MosaicImageView.swift +// MosaicImageViewContainer.swift // Mastodon // // Created by Cirno MainasuK on 2021-2-23. @@ -9,15 +9,15 @@ import os.log import func AVFoundation.AVMakeRect import UIKit -protocol MosaicImageViewPresentable: class { - var mosaicImageView: MosaicImageView { get } +protocol MosaicImageViewContainerPresentable: class { + var mosaicImageViewContainer: MosaicImageViewContainer { get } } protocol MosaicImageViewDelegate: class { - func mosaicImageView(_ mosaicImageView: MosaicImageView, didTapImageView imageView: UIImageView, atIndex index: Int) + func mosaicImageViewContainer(_ mosaicImageViewContainer: MosaicImageViewContainer, didTapImageView imageView: UIImageView, atIndex index: Int) } -final class MosaicImageView: UIView { +final class MosaicImageViewContainer: UIView { static let cornerRadius: CGFloat = 4 @@ -29,7 +29,7 @@ final class MosaicImageView: UIView { imageViews.forEach { imageView in imageView.isUserInteractionEnabled = true let tapGesture = UITapGestureRecognizer.singleTapGestureRecognizer - tapGesture.addTarget(self, action: #selector(MosaicImageView.photoTapGestureRecognizerHandler(_:))) + tapGesture.addTarget(self, action: #selector(MosaicImageViewContainer.photoTapGestureRecognizerHandler(_:))) imageView.addGestureRecognizer(tapGesture) } } @@ -49,7 +49,7 @@ final class MosaicImageView: UIView { } -extension MosaicImageView { +extension MosaicImageViewContainer { private func _init() { container.translatesAutoresizingMaskIntoConstraints = false @@ -69,7 +69,7 @@ extension MosaicImageView { } -extension MosaicImageView { +extension MosaicImageViewContainer { func reset() { container.arrangedSubviews.forEach { subview in @@ -99,7 +99,7 @@ extension MosaicImageView { let imageView = UIImageView() imageViews.append(imageView) imageView.layer.masksToBounds = true - imageView.layer.cornerRadius = MosaicImageView.cornerRadius + imageView.layer.cornerRadius = MosaicImageViewContainer.cornerRadius imageView.contentMode = .scaleAspectFill imageView.translatesAutoresizingMaskIntoConstraints = false @@ -142,7 +142,7 @@ extension MosaicImageView { self.imageViews.append(contentsOf: imageViews) imageViews.forEach { imageView in imageView.layer.masksToBounds = true - imageView.layer.cornerRadius = MosaicImageView.cornerRadius + imageView.layer.cornerRadius = MosaicImageViewContainer.cornerRadius imageView.layer.cornerCurve = .continuous imageView.contentMode = .scaleAspectFill } @@ -195,13 +195,13 @@ extension MosaicImageView { } } -extension MosaicImageView { +extension MosaicImageViewContainer { @objc private func photoTapGestureRecognizerHandler(_ sender: UITapGestureRecognizer) { guard let imageView = sender.view as? UIImageView else { return } guard let index = imageViews.firstIndex(of: imageView) else { return } os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: tap photo at index: %ld", ((#file as NSString).lastPathComponent), #line, #function, index) - delegate?.mosaicImageView(self, didTapImageView: imageView, atIndex: index) + delegate?.mosaicImageViewContainer(self, didTapImageView: imageView, atIndex: index) } } @@ -218,7 +218,7 @@ struct MosaicImageView_Previews: PreviewProvider { static var previews: some View { Group { UIViewPreview(width: 375) { - let view = MosaicImageView() + let view = MosaicImageViewContainer() let image = images[3] let imageView = view.setupImageView( aspectRatio: image.size, @@ -230,7 +230,7 @@ struct MosaicImageView_Previews: PreviewProvider { .previewLayout(.fixed(width: 375, height: 400)) .previewDisplayName("Portrait - one image") UIViewPreview(width: 375) { - let view = MosaicImageView() + let view = MosaicImageViewContainer() let image = images[1] let imageView = view.setupImageView( aspectRatio: image.size, @@ -245,7 +245,7 @@ struct MosaicImageView_Previews: PreviewProvider { .previewLayout(.fixed(width: 375, height: 400)) .previewDisplayName("Landscape - one image") UIViewPreview(width: 375) { - let view = MosaicImageView() + let view = MosaicImageViewContainer() let images = self.images.prefix(2) let imageViews = view.setupImageViews(count: images.count, maxHeight: 162) for (i, imageView) in imageViews.enumerated() { @@ -256,7 +256,7 @@ struct MosaicImageView_Previews: PreviewProvider { .previewLayout(.fixed(width: 375, height: 200)) .previewDisplayName("two image") UIViewPreview(width: 375) { - let view = MosaicImageView() + let view = MosaicImageViewContainer() let images = self.images.prefix(3) let imageViews = view.setupImageViews(count: images.count, maxHeight: 162) for (i, imageView) in imageViews.enumerated() { @@ -267,7 +267,7 @@ struct MosaicImageView_Previews: PreviewProvider { .previewLayout(.fixed(width: 375, height: 200)) .previewDisplayName("three image") UIViewPreview(width: 375) { - let view = MosaicImageView() + let view = MosaicImageViewContainer() let images = self.images.prefix(4) let imageViews = view.setupImageViews(count: images.count, maxHeight: 162) for (i, imageView) in imageViews.enumerated() { diff --git a/Mastodon/Scene/Share/View/Content/StatusView.swift b/Mastodon/Scene/Share/View/Content/StatusView.swift index d52def46c..2d8d966b9 100644 --- a/Mastodon/Scene/Share/View/Content/StatusView.swift +++ b/Mastodon/Scene/Share/View/Content/StatusView.swift @@ -99,7 +99,7 @@ final class StatusView: UIView { button.setTitle(L10n.Common.Controls.Status.showPost, for: .normal) return button }() - let mosaicImageView = MosaicImageView() + let statusMosaicImageView = MosaicImageViewContainer() // do not use visual effect view due to we blur text only without background let contentWarningBlurContentImageView: UIImageView = { @@ -257,7 +257,7 @@ extension StatusView { ]) statusContentWarningContainerStackView.addArrangedSubview(contentWarningTitle) statusContentWarningContainerStackView.addArrangedSubview(contentWarningActionButton) - statusContainerStackView.addArrangedSubview(mosaicImageView) + statusContainerStackView.addArrangedSubview(statusMosaicImageView) // action toolbar container @@ -265,7 +265,7 @@ extension StatusView { actionToolbarContainer.setContentCompressionResistancePriority(.defaultLow, for: .vertical) headerContainerStackView.isHidden = true - mosaicImageView.isHidden = true + statusMosaicImageView.isHidden = true contentWarningBlurContentImageView.isHidden = true statusContentWarningContainerStackView.isHidden = true statusContentWarningContainerStackViewBottomLayoutConstraint.isActive = false @@ -343,7 +343,7 @@ struct StatusView_Previews: PreviewProvider { } .previewLayout(.fixed(width: 375, height: 200)) UIViewPreview(width: 375) { - let statusView = StatusView() + let statusView = StatusView(frame: CGRect(x: 0, y: 0, width: 375, height: 500)) statusView.configure( with: AvatarConfigurableViewConfiguration( avatarImageURL: nil, @@ -351,9 +351,20 @@ struct StatusView_Previews: PreviewProvider { ) ) statusView.headerContainerStackView.isHidden = false + statusView.isStatusTextSensitive = true + statusView.setNeedsLayout() + statusView.layoutIfNeeded() + statusView.drawContentWarningImageView() + statusView.updateContentWarningDisplay(isHidden: false) + let images = MosaicImageView_Previews.images + let imageViews = statusView.statusMosaicImageView.setupImageViews(count: 4, maxHeight: 162) + for (i, imageView) in imageViews.enumerated() { + imageView.image = images[i] + } + statusView.statusMosaicImageView.isHidden = false return statusView } - .previewLayout(.fixed(width: 375, height: 200)) + .previewLayout(.fixed(width: 375, height: 380)) } }