ios SwiftUI导航栏项目框架在工作表关闭后未对齐

gfttwv5a  于 2023-08-08  发布在  iOS
关注(0)|答案(3)|浏览(89)

在SwiftUI中关闭工作表后,导航栏按钮不可点击。以下是重现该问题的步骤
1.呈上一张单子
1.将应用程序移动到后台一小段时间(2秒)
1.恢复应用程序并通过向下滑动关闭工作表
现在导航栏按钮框架未对齐。点击在与按钮可见帧不同的帧工作。这在iOS 16模拟器上很容易重现,但在实际的iOS设备上会间歇性出现。下面是重现该问题的最小代码

struct ContentView: View {
    @State private var showSheetView = false

    var body: some View {
        NavigationView {
            VStack {
                navigationBarView
                Color.blue
            }
            .sheet(isPresented: $showSheetView) {
                FilterView()
            }
            .navigationBarHidden(true)
        }
        .navigationViewStyle(.stack)
    }
    
    private var navigationBarView: some View {
        HStack(spacing: 0) {
            Spacer()
            Button {
                showSheetView = true
            } label: {
                Text("Filter")
                    .padding()
                    .background(Color.red)
            }
        }
    }
}

struct FilterView: View {
    var body: some View {
        Color.green
    }
}

字符串

yks3o0rb

yks3o0rb1#

我也为这个问题纠结了很久,这显然是苹果的一个bug。
我发现了一个丑陋的黑客来解决这个问题。但要使它工作,我必须重绘我的主视图,每次我进入背景。对于我的项目来说,这是确定的,直到他们修复一个实际的错误。我希望它也能帮助你
当您检测到应用程序正在移动到后台时,您可以强制应用程序基于UUID()重新绘制

struct BackgroundModeSheetBugApp: App {

    @State private var id = UUID()

    var body: some Scene {
        WindowGroup {
            ContentView()
                .onReceive(NotificationCenter.default.publisher(for: UIApplication.didEnterBackgroundNotification)) { _ in
                    id = UUID()
                }
                .id(id)
        }
    }
}

字符串
我已经用你的代码测试过了,它在模拟器和设备上都能正常工作
我也鼓起勇气用你的例子向苹果提交了一个bug
P.P.S.对于我的应用程序,我还不得不 Package 我的主视图来破解UIViewControllerRepresentable来修复填充问题。

struct UIHackMainTabView: UIViewControllerRepresentable {

    func makeUIViewController(context: Context) -> UIHostingController<MainTabView> {
        let mainTab = MainTabView()
        return UIHostingController(rootView: mainTab)
    }

    func updateUIViewController(_ pageViewController: UIHostingController<MainTabView>, context: Context) {
    }
}

pgccezyw

pgccezyw2#

现在的另一个解决方法是使用presentationDetents()它有点破坏UI,因为我们失去了很好的收缩效果,它只在iOS 16上工作,但至少应用程序将在那里工作:(

struct SheetHackModifier: ViewModifier {

    func body(content: Content) -> some View {
        if #available(iOS 16.0, *) {
            content
                .presentationDetents([.fraction(0.99)])
        } else {
            content
        }
    }
}

extension View {
    func sheetHackModifier() -> some View {
        self.modifier(SheetHackModifier())
    }
}

字符串

7xllpg7q

7xllpg7q3#

终于解决了这个问题。有些人说使用id,但当NavigationView中有scroll时,我们刷新这个id,滚动到顶部。
您可以使用下面的解决方案。

content
        .onDisappear {
            let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene
            if let viewFrame = scene?.windows.first?.rootViewController?.view.frame {
                scene?.windows.first?.rootViewController?.view.frame = .zero
                scene?.windows.first?.rootViewController?.view.frame = viewFrame
            }
        }

字符串

相关问题