-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Images not showing up reliably in List on iOS 16 #1988
Comments
Not sure what's going wrong, but it seems that when assigning a A very quick workaround, is just appending an empty List {
ForEach(1...100, id: \.self) { idx in
KFImage(Self.imgUrl)
.frame(width: 48, height: 48)
.onAppear()
}
} I will investigate how this can happen and if there is a way to make SwiftUI on iOS 16 happy... |
|
Apple's |
Removing the |
Great finds. It's sad how broken it is. To add more examples, this fails too with the
but works this way:
(it does not help with the nested I'm installing 16.1 Beta to check if they fixed it there. |
If you don't mind or if the layout can keep correctly, you can also try to change KFImage(Self.imgUrl)
- .frame(width: 48, height: 48)
+ .frame(maxWidth: 48, maxHeight: 48) And just for fun, if you create a random "offset" to the size, it seems to be going back to normal: var delta: CGFloat {
CGFloat.random(in: -10..<10)
}
KFImage(Self.imgUrl)
.frame(width: 48 + delta, height: 48 + delta) Again, it is not a recommended way or a useable workaround for most cases. But we can almost be sure it has something about the assigned frame. Maybe the frame size value is used as some kind of factor to determine whether the view should "onAppear". |
Another find. Add a @State private var toggle = false
var body: some View {
List {
Button("Tap me") { toggle.toggle() }
ForEach(1..<10) { sectionIndex in
Section {
ForEach(1..<10) { rowIndex in
KFImage(Self.imgUrl)
.frame(width: 48, height: 48)
}
}
}
}
} With this fact, you can setup a timer and toggle the state frequently to keep the view updated, until Apple can fix it. struct ContentView: View {
private static var imgUrl = URL(string: "https://cdn.iconscout.com/icon/premium/png-48-thumb/kingfisher-3765747-3140298.png")!
let timer = Timer.publish(every: 0.1, on: .main, in: .common).autoconnect()
@State private var toggle = false
var body: some View {
List {
ForEach(1..<10) { sectionIndex in
Section {
ForEach(1..<10) { rowIndex in
KFImage(Self.imgUrl)
.frame(width: 48, height: 48)
}
}
}
}
.onReceive(timer) { time in
toggle.toggle()
}
}
} It seems to be a workable way now, but please use it at your own risk. I cannot yet fully understand what is going on and the performance impact of this timer also requires checking. @windom I have to go and take some sleep now. Please let me know if you have any luck with iOS 16.1 beta. If no, are you going to send a feedback to Apple? Since the issue is now easy enough to reproduce even with |
Thank you for the many creative workarounds, we will evaluate what to go with. Sadly 16.1 beta 2 did not fix that much. It fixed this case:
but not this:
and nor this:
I've submitted feedback using |
I also submitted feedback for it: FB11564208 I will keep an eye on it, but now I have to say there is no good way to fix it on our end. |
This workaround worked perfectly for me. Thanks. |
The same problem is still happening under Xcode 14.1 RC and iOS 16.1 simulators. There is no response from Apple's Feedback yet. And the "workaround" (with performance cost) here is also still working. |
I installed the new iOS 16.1 stable version and it seems is working fine now, at least with my use case. |
Seems the example in this comment is still causing issue and the images are not loaded even in Xcode 14.1 RC2 and its iOS 16.1 simulator. Didn't have a chance to try on iOS 16.1 devices yet but I am not optimistic. |
Just tried using Xcode 14.1 RC2 and real iOS 16.1 device: the original issue with KFImage directly in List/ForEach seems to be fixed, however the case with nested ForEach-es and Sections is still broken. |
@windom May I know which version of Kingfisher are you trying? The original issue got a workaround in #1990 and it was already a part of version 7.4.0 and on the master branch. So if you are using these latest versions, I guess it is that workaround is doing its work. But the root cause is not yet addressed. |
I used 7.3.2 to avoid the workaround, so I think they fixed it for the simplest case. |
It's amazing this iOS 16/16.1 bug... I spent some time trying to find a workaround, but it seems very complicated. Only the workaround with the timer worked for me. But as it has an impact on the performance, I preferred to switch from |
Work for me List{
ForEach(items, id: \.id){ item in
ZStack{
NavigationLink(destination: { EmptyView() }, label: { EmptyView() })
.opacity(0.01)
//Yout code
}
}
} |
I was unfortunately unable to get the Similar to @noefroidevaux, I opted to go the |
I'm also in the List + Section scenario - the only implementation that works is removing frame modifier. In that case, it works beautifully however the images are of course woefully oversized 🥲 "Oh OK! So what if you set the max height of the list item and not the image itself? That way the image can still resize and look good!" - nope 😿 "Shoot, OH... what if you use a custom Any frame modification along the stack breaks the lifecycle. The largest/oldest thread (4.1k upvotes) I can find on the Apple Developer Forums also tracks with the comments here. I added a comment to that thread linking back to this discussion as I suspect it would be helpful for a subset of those (at least) 4100+ developers 😄 I suspect this has to do with the @onevcat you're a hero for all the work you've done to help figure this out. Thank you! I have a very small number (< 30) of small images to load (~1k). Is there a way to force Kingfisher to load them instead of its normal lifecycle? |
@rslifka Previously in the dark age of SwiftUI, there was once a |
I added a method in this I guess it can somehow play as a better workaround before Apple can fix the issue on the SwiftUI side. To use it:
KFImage(someURL)
+ .startLoadingBeforeViewAppear()
.resizable()
.frame(width: 200, height: 200) I need some help to try it in more complicate scenes. If it works fine, maybe we can consider including it in the master branch and tagging a release. |
@onevcat
|
I can confirm the issue is fixed with changes in |
I can also confirm that this is working. Used in a list view, where only the aggressive timed update workaround worked before. |
Thank you, all folks! Then let me prepare a release for this as a better workaround, before Apple can fix it someday later. |
A new version 7.5.0 was released in which this new modifier is contained. I am closing this for now and if Apple can fix it one day I will append some more comments here. Thank you all for reporting and helping verify it! |
I can confirm that this issue has been fixed by Apple in Xcode 14.3 (now still in beta) and iOS 16.4. Since that, I will try to add some version checks in the |
Check List
Thanks for considering to open an issue. Before you submit your issue, please confirm these boxes are checked.
Issue Description
What
On iOS 16 (Xcode 14.0.1),
KFImage
s frequently fail to show up when used insideList
/ForEach
. We're using them as part of a more complex list item view, but the bug is reproducible using the very simple code below.Reproduce
Scroll around a bit and images will disappear and/or fail to appear.
The text was updated successfully, but these errors were encountered: