重置偏移量,onTapGesture有效,但是onRotated不起作用,为什么?

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

我希望屏幕的底部包含2个矩形的浮动视图,无论方向是纵向还是横向。

代码是一个测试,当directionDidChangeNotification发生时,我发现UIDevice.current.orientation.isPortrait和UIScreen.main.bounds.height通常具有错误的值,为什么?

无论如何,测试代码只是在onRotated()中重置offset = 0。但它不起作用;否则onTapGesture可以正常工作。

Q1:SwiftUI是否使用错误的方式? SceneDelegate.orientationDidChangeNotification-> contentView.onRotated()?

Q2:为什么UIDevice.current.orientation.isPortrait和UIScreen.main.bounds.height通常具有错误的值?

Q3:如何使视图以纵向和横向都漂浮在屏幕底部?

let height: CGFloat = 100

struct TestView: View {
    @State var offset = (UIScreen.main.bounds.height - height) / 2

    var body: some View {
        ZStack {
            Text("+")
            VStack(spacing: 0) {
                Rectangle().fill(Color.blue)
                Rectangle().fill(Color.red)
            }
            .frame(width: 100, height: height)
            .offset(y: offset)
            .onTapGesture {
                self.offset = 0
            }
        }
    }

    func onRotated() {
//        let isPortrait =  UIDevice.current.orientation.isPortrait
        offset = 0//(UIScreen.main.bounds.height - height) / 2
//        print("\(isPortrait), screen height = \(UIScreen.main.bounds.height)")
    }
}

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        let contentView = TestView()
        if let windowScene = scene as? UIWindowScene {
            NotificationCenter.default.addObserver(forName: UIDevice.orientationDidChangeNotification, object: nil, queue: nil) { notification in
                contentView.onRotated()
            }

            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: contentView)
            self.window = window
            window.makeKeyAndVisible()
        }
    }
    ...
}
rotation swiftui
1个回答
1
投票

[contentView不是引用,它是一个值,因此您只在回调中使用的.onRotated值的自己副本上调用contentView

    let contentView = TestView() 
    if let windowScene = scene as? UIWindowScene {
        NotificationCenter.default.addObserver(forName: UIDevice.orientationDidChangeNotification, object: nil, queue: nil) { notification in
            contentView.onRotated() // local copy!!!
        }

而不是在TestView中为通知发布者创建侦听器,因此它可以在内部进行自我更改。

[此外,目的并不明确,但是SwiftUI可以通过EnvironmentValues.horizontalSizeClassEnvironmentValues.verticalSizeClass跟踪尺寸类别,这些尺寸类别会在设备方向上自动更改,因此甚至可以根据这些环境值来制作视图布局/ o通知。

See here good example on how to use size classes

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