From 7e164ecf04d4084adf23a1ee1f6f145492e76e0f Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Mon, 30 Jan 2023 17:08:01 +1100 Subject: [PATCH] wrap up carousel view --- .../MediaInfoVC+MediaPreviewView.swift | 29 ++++--------- .../Media Viewing & Editing/MediaInfoVC.swift | 21 ++++++---- Session/Shared/SessionCarouselView+Info.swift | 42 ++++++++++++++++--- Session/Shared/SessionCarouselView.swift | 21 ++++++++-- SessionUIKit/Utilities/UIView+Utilities.swift | 10 ----- 5 files changed, 74 insertions(+), 49 deletions(-) diff --git a/Session/Media Viewing & Editing/MediaInfoVC+MediaPreviewView.swift b/Session/Media Viewing & Editing/MediaInfoVC+MediaPreviewView.swift index a5bb0f1ca..3bac68e67 100644 --- a/Session/Media Viewing & Editing/MediaInfoVC+MediaPreviewView.swift +++ b/Session/Media Viewing & Editing/MediaInfoVC+MediaPreviewView.swift @@ -55,28 +55,7 @@ extension MediaInfoVC { } required init?(coder: NSCoder) { - guard let attachment = coder.decodeObject(forKey: "attachment") as? Attachment else { - print("No attachment") - return nil - } - guard let isOutgoing = coder.decodeObject(forKey: "isOutgoing") as? Bool else { - print("No isOutgoing") - return nil - } - - self.attachment = attachment - self.isOutgoing = isOutgoing - - super.init(coder: coder) - self.accessibilityLabel = "Media info" - setUpViewHierarchy() - } - - override func encode(with coder: NSCoder) { - super.encode(with: coder) -// coder.encode(self.attachment, forKey: "attachment") - coder.encode(self.isOutgoing, forKey: "isOutgoing") - + preconditionFailure("Use init(attachment:) instead.") } private func setUpViewHierarchy() { @@ -94,8 +73,14 @@ extension MediaInfoVC { } // MARK: - Interaction + @objc func showMediaFullScreen() { } + + // MARK: - Copy + func copyView() -> MediaPreviewView { + return MediaPreviewView(attachment: self.attachment, isOutgoing: self.isOutgoing) + } } } diff --git a/Session/Media Viewing & Editing/MediaInfoVC.swift b/Session/Media Viewing & Editing/MediaInfoVC.swift index 044d31844..5c8353b1c 100644 --- a/Session/Media Viewing & Editing/MediaInfoVC.swift +++ b/Session/Media Viewing & Editing/MediaInfoVC.swift @@ -13,20 +13,27 @@ final class MediaInfoVC: BaseVC { // MARK: - UI private lazy var mediaInfoView: MediaInfoView = MediaInfoView(attachment: nil) private lazy var mediaCarouselView: SessionCarouselView = { + let slices: [MediaPreviewView] = self.attachments.map { + MediaPreviewView( + attachment: $0, + isOutgoing: self.isOutgoing + ) + } let result: SessionCarouselView = SessionCarouselView( info: SessionCarouselView.Info( - slices: self.attachments.map { - MediaPreviewView( - attachment: $0, - isOutgoing: self.isOutgoing - ) - }, + slices: slices, + copyOfFirstSlice: slices.first?.copyView(), + copyOfLastSlice: slices.last?.copyView(), sliceSize: CGSize( width: Self.mediaSize, height: Self.mediaSize ), shouldShowPageControl: true, - pageControlHeight: 10, + pageControlStyle: SessionCarouselView.PageControlStyle( + size: .medium, + backgroundColor: .init(white: 0, alpha: 0.4), + bottomInset: Values.mediumSpacing + ), shouldShowArrows: true, arrowsSize: CGSize( width: 20, diff --git a/Session/Shared/SessionCarouselView+Info.swift b/Session/Shared/SessionCarouselView+Info.swift index 8aef9cda8..f87d69c86 100644 --- a/Session/Shared/SessionCarouselView+Info.swift +++ b/Session/Shared/SessionCarouselView+Info.swift @@ -7,11 +7,12 @@ import SessionUtilitiesKit extension SessionCarouselView { public struct Info { let slices: [UIView] + let copyOfFirstSlice: UIView? + let copyOfLastSlice: UIView? let sliceSize: CGSize let sliceCount: Int let shouldShowPageControl: Bool - let pageControlHeight: CGFloat - let pageControlScale: CGFloat // This is to control the size of the dots + let pageControlStyle: PageControlStyle let shouldShowArrows: Bool let arrowsSize: CGSize @@ -19,21 +20,50 @@ extension SessionCarouselView { init( slices: [UIView] = [], + copyOfFirstSlice: UIView? = nil, + copyOfLastSlice: UIView? = nil, sliceSize: CGSize = .zero, shouldShowPageControl: Bool = true, - pageControlHeight: CGFloat = 0, - pageControlScale: CGFloat = 1, + pageControlStyle: PageControlStyle, shouldShowArrows: Bool = true, arrowsSize: CGSize = .zero ) { self.slices = slices + self.copyOfFirstSlice = copyOfFirstSlice + self.copyOfLastSlice = copyOfLastSlice self.sliceSize = sliceSize self.sliceCount = slices.count self.shouldShowPageControl = shouldShowPageControl && (self.sliceCount > 1) - self.pageControlHeight = pageControlHeight - self.pageControlScale = pageControlScale + self.pageControlStyle = pageControlStyle self.shouldShowArrows = shouldShowArrows && (self.sliceCount > 1) self.arrowsSize = arrowsSize } } + + public struct PageControlStyle { + enum DotSize: CGFloat { + case mini = 0.5 + case medium = 0.8 + case original = 1 + } + + let height: CGFloat? + let size: DotSize + let backgroundColor: UIColor + let bottomInset: CGFloat + + // MARK: - Initialization + + init( + height: CGFloat? = nil, + size: DotSize = .original, + backgroundColor: UIColor = .clear, + bottomInset: CGFloat = 0 + ) { + self.height = height + self.size = size + self.backgroundColor = backgroundColor + self.bottomInset = bottomInset + } + } } diff --git a/Session/Shared/SessionCarouselView.swift b/Session/Shared/SessionCarouselView.swift index 39accc837..2d102fc3a 100644 --- a/Session/Shared/SessionCarouselView.swift +++ b/Session/Shared/SessionCarouselView.swift @@ -28,8 +28,10 @@ final class SessionCarouselView: UIView, UIScrollViewDelegate { result.numberOfPages = self.info.sliceCount result.currentPage = 0 result.isHidden = !self.info.shouldShowPageControl - result.set(.height, to: self.info.pageControlHeight) - result.transform = CGAffineTransform(scaleX: self.info.pageControlScale, y: self.info.pageControlScale) + result.transform = CGAffineTransform( + scaleX: self.info.pageControlStyle.size.rawValue, + y: self.info.pageControlStyle.size.rawValue + ) return result }() @@ -59,11 +61,12 @@ final class SessionCarouselView: UIView, UIScrollViewDelegate { }() // MARK: - Lifecycle + init(info: SessionCarouselView.Info) { self.info = info if self.info.sliceCount > 1, - let copyOfFirstSlice: UIView = self.info.slices.first?.copyView(), - let copyOfLastSlice: UIView = self.info.slices.last?.copyView() + let copyOfFirstSlice: UIView = self.info.copyOfFirstSlice, + let copyOfLastSlice: UIView = self.info.copyOfLastSlice { self.slicesForLoop = [copyOfLastSlice] .appending(contentsOf: self.info.slices) @@ -120,6 +123,7 @@ final class SessionCarouselView: UIView, UIScrollViewDelegate { } // MARK: - UIScrollViewDelegate + func scrollViewDidScroll(_ scrollView: UIScrollView) { let pageIndex: Int = { let maybeCurrentPageIndex: Int = Int(round(scrollView.contentOffset.x/self.info.sliceSize.width)) @@ -139,6 +143,14 @@ final class SessionCarouselView: UIView, UIScrollViewDelegate { } func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { + setCorrectCotentOffsetIfNeeded(scrollView) + } + + func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) { + setCorrectCotentOffsetIfNeeded(scrollView) + } + + private func setCorrectCotentOffsetIfNeeded(_ scrollView: UIScrollView) { if pageControl.currentPage == 0 { scrollView.setContentOffset( CGPoint( @@ -162,6 +174,7 @@ final class SessionCarouselView: UIView, UIScrollViewDelegate { } // MARK: - Interaction + @objc func scrollToNextSlice() { self.scrollView.setContentOffset( CGPoint( diff --git a/SessionUIKit/Utilities/UIView+Utilities.swift b/SessionUIKit/Utilities/UIView+Utilities.swift index 2ce766308..7d37a2185 100644 --- a/SessionUIKit/Utilities/UIView+Utilities.swift +++ b/SessionUIKit/Utilities/UIView+Utilities.swift @@ -72,14 +72,4 @@ public extension UIView { return result } - - func copyView() -> T? { - do { - return try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(NSKeyedArchiver.archivedData(withRootObject:self, requiringSecureCoding:false)) as? T - } catch { - print("\(error)") - return nil - } - - } }