damus

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

commit 647c6f8428f489d36d004128d13b81224709a87e
parent 0608222cb02aafe1c8d61281d7b6bf72af3e6d49
Author: William Casarin <jb55@jb55.com>
Date:   Mon,  3 Apr 2023 09:22:48 -0700

Refactor dynamic image height and fix crashing

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

diff --git a/damus/Components/ImageCarousel.swift b/damus/Components/ImageCarousel.swift @@ -32,16 +32,16 @@ struct ShareSheet: UIViewControllerRepresentable { } +enum ImageShape { + case square + case landscape + case portrait + case unknown +} struct ImageCarousel: View { var urls: [URL] - enum ImageShape { - case square - case landscape - case portrait - case unknown - } @State private var open_sheet: Bool = false @State private var current_url: URL? = nil @@ -64,37 +64,14 @@ struct ImageCarousel: View { 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 fill = calculate_image_fill(geo: geo, img: img, maxHeight: maxHeight, minHeight: minHeight) + + DispatchQueue.main.async { + if let filling = fill.filling { + self.filling = filling } - }() - - 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) + + self.height = fill.height } }) .aspectRatio(contentMode: filling ? .fill : .fit) @@ -117,6 +94,54 @@ struct ImageCarousel: View { } } +func determine_image_shape(_ size: CGSize) -> ImageShape { + guard size.height > 0 else { + return .unknown + } + let imageRatio = size.width / size.height + switch imageRatio { + case 1.0: return .square + case ..<1.0: return .portrait + case 1.0...: return .landscape + default: return .unknown + } +} + +struct ImageFill { + let filling: Bool? + let height: CGFloat +} + +func calculate_image_fill(geo: GeometryProxy, img: UIImage, maxHeight: CGFloat, minHeight: CGFloat) -> ImageFill { + let shape = determine_image_shape(img.size) + + 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: + let filling = yfactor <= 1.0 + let scaled = img.size.height * xfactor + let height = filling ? maxHeight : max(scaled, minHeight) + return ImageFill(filling: filling, height: height) + case .square: + let filling = yfactor <= 1.0 && xfactor <= 1.0 + let scaled = img.size.height * xfactor + let height = filling ? maxHeight : max(scaled, minHeight) + return ImageFill(filling: filling, height: height) + case .landscape: + let scaled = img.size.height * xfactor + let filling = scaled > maxHeight || xfactor < 1.0 + let height = img.kf.imageFrameCount != nil ? scaled : filling ? min(maxHeight, scaled) : max(scaled, minHeight) + return ImageFill(filling: filling, height: height) + case .unknown: + let height = max(img.size.height, minHeight) + return ImageFill(filling: nil, height: height) + } +} + struct ImageCarousel_Previews: PreviewProvider { static var previews: some View { ImageCarousel(urls: [URL(string: "https://jb55.com/red-me.jpg")!,URL(string: "https://jb55.com/red-me.jpg")!])