-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix infinite loop in iOS 14 when embedding NetworkImage inside HStack (…
…#27)
- Loading branch information
1 parent
f8b8ed0
commit c97f83e
Showing
2 changed files
with
66 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import Combine | ||
import CombineSchedulers | ||
import SwiftUI | ||
|
||
final class NetworkImageViewModel: ObservableObject { | ||
struct Context { | ||
var transaction: Transaction | ||
var imageLoader: NetworkImageLoader | ||
} | ||
|
||
enum State: Equatable { | ||
case empty(url: URL, scale: CGFloat) | ||
case success(Image) | ||
case failure | ||
|
||
var image: Image? { | ||
guard case .success(let image) = self else { | ||
return nil | ||
} | ||
return image | ||
} | ||
} | ||
|
||
@Published private(set) var state: State | ||
private var cancellable: AnyCancellable? | ||
|
||
init(url: URL?, scale: CGFloat) { | ||
if let url = url { | ||
self.state = .empty(url: url, scale: scale) | ||
} else { | ||
self.state = .failure | ||
} | ||
} | ||
|
||
func onAppear(context: Context) { | ||
guard case .empty(let url, let scale) = self.state else { | ||
return | ||
} | ||
|
||
self.cancellable = context.imageLoader.image(for: url, scale: scale) | ||
.map { .success(.init(platformImage: $0)) } | ||
.replaceError(with: .failure) | ||
.receive(on: UIScheduler.shared) | ||
.sink { [weak self] state in | ||
withTransaction(context.transaction) { | ||
self?.state = state | ||
} | ||
} | ||
} | ||
} |