I’m having some issues with KFImage. It works fine with the placeholder image, until the remote image is loaded. It seems to be some interaction between .aspectRatio() and .layoutPriority(-1).
I have a kind of card with an image, and a couple text blocks beneath it. I want the image to be clipped to a view that has a specific aspect ratio, and whose width is dictated by the container (in the real app these live in a grid, and size will vary from device to device. I want the image to grow, rather than the spacing to grow).
Here’s what I get with the placeholder (the bubbles) and the loaded image (the aspect ratio test image). The placeholder image is 654 x 768, and the loaded image is 1080 x 1920. The aspect ratio of the placeholder is properly maintained, and it is clipped to the desired aspect ratio.
But as you can see, the loaded image is scaled non-uniformly to fit in the same aspect-ratio as the placeholder. The normal solution to that is to add .aspectRatio(.fill). But if I do that on KFImage, it blows up everything:
Here’s the code. Note the .aspectRatio(contentMode: .fill) on KFImage is commented out. If you uncomment it, you get the second image above.
import SwiftUI
import Kingfisher
struct
SellerShowCell: View
{
let title : String
let secondary : String?
var startTime : Date? = nil
var thumbnailURL : URL? = nil
var
body: some View {
VStack(alignment: .leading, spacing: 0.0) {
ZStack(alignment: .topLeading) {
// Thumbnail background…
ZStack {
KFImage(self.thumbnailURL)
.cancelOnDisappear(true)
.placeholder {
ZStack {
Color(.black)
Image("image_placeholder_background")
.resizable()
.aspectRatio(contentMode: .fill)
.layoutPriority(-1)
}
}
.resizable()
// .aspectRatio(contentMode: .fill) // Uncommenting this ruins the placeholder and allows the loaded image to dictate the parent size
// .layoutPriority(-1) // This does not have any obvious effect on KFImage
}
.aspectRatio(158.0 / 220.0, contentMode: .fit)
.cornerRadius(16.0)
Text("A Note")
.foregroundColor(.white)
.padding(8.0)
.background(Color.purple)
.clipShape(Capsule())
.padding([.top, .leading], 10.0)
}
// Title…
Text("\(self.title)")
.multilineTextAlignment(.leading)
.lineLimit(2)
.font(.custom("Helvetica", size: 16.0).weight(.semibold))
.foregroundColor(.black)
.padding(.top, 12.0)
// Secondary…
if let secondary = self.secondary {
Text("\(secondary)")
.multilineTextAlignment(.leading)
.font(.custom("Helvetica Neue", size: 12.0).weight(.medium))
.foregroundColor(Color("secondary-color"))
.padding(.top, 12.0)
}
}
.border(Color.green)
}
}
struct SellerShowCell_Previews: PreviewProvider {
static var previews: some View {
ZStack {
Color("main-tab-background")
.ignoresSafeArea()
VStack(spacing: 20.0) {
SellerShowCell(title: "Here is a caption of sufficient length to be a couple of lines",
secondary: "Secondary Text",
thumbnailURL: nil)
.padding(.horizontal, 80)
SellerShowCell(title: "Here is a caption of sufficient length to be a couple of lines",
secondary: "Secondary Text",
thumbnailURL: URL(string: "https://i.imgur.com/iH7Xe20.jpg")!)
.padding(.horizontal, 80)
}
}
}
}

