如何检测视图调整大小何时完成?

问题描述 投票:0回答:1

我想创建一个解决方案,告诉我用户何时完成调整视图大小。目前,我正在为此使用计时器,但我对我的方法并不满意,因为它感觉不像惯用的 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)")
    }
}
swift swiftui
1个回答
0
投票

要检测窗口大小调整会话的结束,您可以观察

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在这里的答案

© www.soinside.com 2019 - 2024. All rights reserved.