我正在尝试使用基本的 @State/@Binding 方法操作来更新 View 参数,但它不起作用。这是查看代码:
import SwiftUI
struct StreamingImageView: View {
@State var imageURL: URL = URL(string: "file:\(NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true)[0])/../img_01.jpg")!
var body: some View {
let _ = FileMonitor(fileURL: $imageURL)
GeometryReader { geometry in
AsyncImage(url: imageURL)
.frame(maxWidth: geometry.size.width, maxHeight: geometry.size.height)
}
}
}
FileMonitor 在图像刷新时重新分配 imageURL(已验证)。但是,我没有看到显示的视图已更新。
这是 FileMonitor 中的代码:
class FileMonitor {
@Binding var fileURL: URL
let localFileURL: URL
let fileDescriptor: CInt
let fileMonitorQueue: DispatchQueue
let fileMonitorSource: DispatchSourceFileSystemObject
init(fileURL: Binding<URL>) {
localFileURL = URL(string: fileURL.wrappedValue.path)!
self._fileURL = fileURL
fileDescriptor = open(fileURL.wrappedValue.path(), O_EVTONLY)
fileMonitorQueue = DispatchQueue(label: "GB.IndigoPolarAlignAid_filemonitor")
fileMonitorSource = DispatchSource.makeFileSystemObjectSource(fileDescriptor: fileDescriptor, eventMask: .write, queue: fileMonitorQueue)
startMonitoring()
}
func startMonitoring() {
fileMonitorSource.setEventHandler {
print("File has been written!")
// Perform any desired actions here
self.fileURL = self.localFileURL
}
...
中断一段时间后我又回到了这个话题。我从编码员那里得到了帮助,但最终结果是黑客攻击(效果不佳)。仅使用 UUID 更新图像。这个想法是,如果源发生变化,视图就会更新,但仍然没有图像更新。这里使用 AsyncImage 是错误的吗?这是新代码:
import SwiftUI
struct StreamingImageView: View {
private var filePath : URL?
@StateObject private var monitor : FileMonitor
@State var id = UUID()
init(){
filePath = URL(string: "file:/Users/\(NSUserName())/Library/Containers/GB.IndigoPolarAlignAid/Data/img_01.jpg")!
let monitor = FileMonitor(filePath: filePath!)
self._monitor = StateObject(wrappedValue: monitor)
monitor.startMonitoring()
}
var body: some View {
GeometryReader { geometry in
AsyncImage(url: filePath) { image in
image.image?
.resizable().aspectRatio(contentMode: .fit)
.frame(maxWidth: geometry.size.width, maxHeight: geometry.size.height)
}.id(UUID())
Text("count \(monitor.fileUpdateCount) \(filePath!.absoluteString)")
}
}
}