Dynamic Image View
A dynamic image modifier to adjust height from image format and ratio
This commit is contained in:
committed by
William Casarin
parent
b83204898b
commit
0608222cb0
@@ -36,8 +36,19 @@ struct ShareSheet: UIViewControllerRepresentable {
|
|||||||
struct ImageCarousel: View {
|
struct ImageCarousel: View {
|
||||||
var urls: [URL]
|
var urls: [URL]
|
||||||
|
|
||||||
@State var open_sheet: Bool = false
|
enum ImageShape {
|
||||||
@State var current_url: URL? = nil
|
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 {
|
var body: some View {
|
||||||
TabView {
|
TabView {
|
||||||
@@ -45,30 +56,60 @@ struct ImageCarousel: View {
|
|||||||
Rectangle()
|
Rectangle()
|
||||||
.foregroundColor(Color.clear)
|
.foregroundColor(Color.clear)
|
||||||
.overlay {
|
.overlay {
|
||||||
KFAnimatedImage(url)
|
GeometryReader { geo in
|
||||||
.imageContext(.note)
|
KFAnimatedImage(url)
|
||||||
.cancelOnDisappear(true)
|
.imageContext(.note)
|
||||||
.configure { view in
|
.cancelOnDisappear(true)
|
||||||
view.framePreloadCount = 3
|
.configure { view in
|
||||||
}
|
view.framePreloadCount = 3
|
||||||
.aspectRatio(contentMode: .fill)
|
}
|
||||||
//.cornerRadius(10)
|
.imageModifier({ img in
|
||||||
.tabItem {
|
// get the fitting scale factor
|
||||||
Text(url.absoluteString)
|
let shape: ImageShape = {
|
||||||
}
|
let imageRatio = img.size.width / img.size.height
|
||||||
.id(url.absoluteString)
|
switch imageRatio {
|
||||||
// .contextMenu {
|
case 1.0: return .square
|
||||||
// Button(NSLocalizedString("Copy Image", comment: "Context menu option to copy an image to clipboard.")) {
|
case ..<1.0: return .portrait
|
||||||
// UIPasteboard.general.string = url.absoluteString
|
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) {
|
.fullScreenCover(isPresented: $open_sheet) {
|
||||||
ImageView(urls: urls)
|
ImageView(urls: urls)
|
||||||
}
|
}
|
||||||
.frame(height: 350)
|
.frame(height: height)
|
||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
open_sheet = true
|
open_sheet = true
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user