我想创建一个解决方案,告诉我用户何时完成调整视图大小。目前,我正在为此使用计时器,但我对我的方法并不满意,因为它感觉不像惯用的 SwiftUI 编码。我正在寻找一种更原生的方法来检测调整大小结束时视图的最终大小。当我们改变窗口大小时,我们的视图大小也会改变。
import SwiftUI
struct ContentView: View {
@State private var resizeTimer: Timer? = nil
var body: some View {
GeometryReader { geometryValue in
Color.white
.onChange(of: geometryValue.size) { newValue in
// Invalidate any existing timer
resizeTimer?.invalidate()
// Start a new timer to detect when resizing ends
resizeTimer = Timer.scheduledTimer(withTimeInterval: 0.01, repeats: false) { _ in // [weak self]
didEndResizing(size: newValue)
}
}
}
.padding()
}
private func didEndResizing(size: CGSize) {
print("View resizing ended. Final size: \(size)")
}
}
NSWindow.didEndLiveResizeNotification
。
.onReceive(NotificationCenter.default.publisher(for: NSWindow.didEndLiveResizeNotification)) { notification in
print("Resize did end!")
}
notification.object
告诉您哪个 NSWindow
已调整大小,因此如果您的应用程序有多个窗口,您可以检查它以仅响应视图自身窗口的大小调整。例如:
struct ContentView: View {
@State private var myWindow: NSWindow?
var body: some View {
Color.blue
.background { WindowAccessor(window: $myWindow) }
.onReceive(NotificationCenter.default.publisher(for: NSWindow.didEndLiveResizeNotification)) { notification in
if (notification.object as? NSWindow) == myWindow {
print("Did resize!")
}
}
}
}
struct WindowAccessor: NSViewRepresentable {
@Binding var window: NSWindow?
class MoveToWindowDetector: NSView {
var onMoveToWindow: (NSWindow?) -> Void = { _ in }
override func viewDidMoveToWindow() {
onMoveToWindow(window)
}
}
func makeNSView(context: Context) -> MoveToWindowDetector {
MoveToWindowDetector()
}
func updateNSView(_ nsView: MoveToWindowDetector, context: Context) {
nsView.onMoveToWindow = { window = $0 }
}
}
WindowAccessor
稍微修改了Asperi在这里的答案。