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:
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")!])