damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

commit 0608222cb02aafe1c8d61281d7b6bf72af3e6d49
parent b83204898bf42eba5bd539161de213dcf9f0bfe3
Author: mainvolume <sina@mainvolume.com>
Date:   Sun,  2 Apr 2023 16:24:20 +0200

Dynamic Image View

A dynamic image modifier to adjust height from image format and ratio

Diffstat:
Mdamus/Components/ImageCarousel.swift | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
1 file changed, 61 insertions(+), 20 deletions(-)

diff --git a/damus/Components/ImageCarousel.swift b/damus/Components/ImageCarousel.swift @@ -36,8 +36,19 @@ struct ShareSheet: UIViewControllerRepresentable { struct ImageCarousel: View { var urls: [URL] - @State var open_sheet: Bool = false - @State var current_url: URL? = nil + enum ImageShape { + case square + case landscape + case portrait + case unknown + } + + @State private var open_sheet: Bool = false + @State private var current_url: URL? = nil + @State private var height: CGFloat = .zero + @State private var minHeight: CGFloat = 150 + @State private var maxHeight: CGFloat = 500 + @State private var filling: Bool = false var body: some View { TabView { @@ -45,30 +56,60 @@ struct ImageCarousel: View { Rectangle() .foregroundColor(Color.clear) .overlay { - KFAnimatedImage(url) - .imageContext(.note) - .cancelOnDisappear(true) - .configure { view in - view.framePreloadCount = 3 - } - .aspectRatio(contentMode: .fill) - //.cornerRadius(10) - .tabItem { - Text(url.absoluteString) - } - .id(url.absoluteString) -// .contextMenu { -// Button(NSLocalizedString("Copy Image", comment: "Context menu option to copy an image to clipboard.")) { -// UIPasteboard.general.string = url.absoluteString -// } -// } + GeometryReader { geo in + KFAnimatedImage(url) + .imageContext(.note) + .cancelOnDisappear(true) + .configure { view in + view.framePreloadCount = 3 + } + .imageModifier({ img in + // get the fitting scale factor + let shape: ImageShape = { + let imageRatio = img.size.width / img.size.height + switch imageRatio { + case 1.0: return .square + case ..<1.0: return .portrait + case 1.0...: return .landscape + default: return .unknown + } + }() + + let xfactor = geo.size.width / img.size.width + let yfactor = maxHeight / img.size.height + // calculate scaled image height + // set scale factor and constrain images to minimum 150 + // and animations to scaled factor for dynamic size adjustment + switch shape { + case .portrait: + filling = yfactor <= 1.0 + let scaled = img.size.height * xfactor + height = filling ? maxHeight : max(scaled, minHeight) + case .square: + filling = yfactor <= 1.0 && xfactor <= 1.0 + let scaled = img.size.height * xfactor + height = filling ? maxHeight : max(scaled, minHeight) + case .landscape: + let scaled = img.size.height * xfactor + filling = scaled > maxHeight || xfactor < 1.0 + height = img.kf.imageFrameCount != nil ? scaled : filling ? min(maxHeight, scaled) : max(scaled, minHeight) + case .unknown: + height = max(img.size.height, minHeight) + } + }) + .aspectRatio(contentMode: filling ? .fill : .fit) + .tabItem { + Text(url.absoluteString) + } + .id(url.absoluteString) + } } } } .fullScreenCover(isPresented: $open_sheet) { ImageView(urls: urls) } - .frame(height: 350) + .frame(height: height) .onTapGesture { open_sheet = true }