当状态更改导致键盘在工作表中退出时,SwiftUI iOS应用程序崩溃 [英] SwiftUI iOS app crashes when state change causes keyboard to resign as first responder while in a sheet

查看:115
本文介绍了当状态更改导致键盘在工作表中退出时,SwiftUI iOS应用程序崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在具有多个页面"的工作表中创建一个视图.该视图包含一个枚举的 @State 变量,并且我使用

I'm trying to create a view in a sheet with multiple "pages". The view holds a @State variable of an enum and I "switch" between pages with

if self.page == .text {...}
else if self.page == .image {...}
else {...}

但是,当在其中一个页面中的文本字段处于活动状态时设置了self.page时,该应用程序将崩溃,并且没有明确的错误消息.这似乎可以在模拟器上运行,但不能在设备上运行.

However, when self.page is set while a textfield is active in one of the pages, the app crashes with no clear error message. This seems to work on the simulator but not on a device.

这是转储:

Thread 1 Queue : com.apple.main-thread (serial)
#0  0x00000001f6dc702c in ViewRendererHost.render(interval:updateDisplayList:) ()
#1  0x00000001f6f427d8 in _UIHostingView.layoutSubviews() ()
#2  0x00000001f6f42808 in @objc _UIHostingView.layoutSubviews() ()
#3  0x00000001c3ec8ebc in -[UIView(CALayerDelegate) layoutSublayersOfLayer:] ()
#4  0x00000001bf63ca4c in -[NSObject performSelector:withObject:] ()
#5  0x00000001c64dd9dc in -[CALayer layoutSublayers] ()
#6  0x00000001c64dde2c in CA::Layer::layout_if_needed(CA::Transaction*) ()
#7  0x00000001c3eb481c in -[UIView(Hierarchy) layoutBelowIfNeeded] ()
#8  0x00000001c32fe69c in -[_UISheetPresentationController _sheetLayoutInfoLayout:] ()
#9  0x00000001c32fbdc4 in -[_UISheetLayoutInfo _layout] ()
#10 0x00000001c32ff560 in __74-[_UISheetPresentationController _handleKeyboardNotification:aboutToHide:]_block_invoke ()
#11 0x00000001c3ebb360 in +[UIView(Animation) performWithoutAnimation:] ()
#12 0x00000001c32ff338 in -[_UISheetPresentationController _handleKeyboardNotification:aboutToHide:] ()
#13 0x00000001c32ff768 in -[_UISheetPresentationController _keyboardAboutToChangeFrame:] ()
#14 0x00000001bfcf306c in __57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke_2 ()
#15 0x00000001bf88099c in __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ ()
#16 0x00000001bf8809ec in ___CFXRegistrationPost1_block_invoke ()
#17 0x00000001bf87fce4 in _CFXRegistrationPost1 ()
#18 0x00000001bf87f97c in ___CFXNotificationPost_block_invoke ()
#19 0x00000001bf7f8910 in -[_CFXNotificationRegistrar find:object:observer:enumerator:] ()
#20 0x00000001bf87f2ac in _CFXNotificationPost ()
#21 0x00000001bfbe1bfc in -[NSNotificationCenter postNotificationName:object:userInfo:] ()
#22 0x00000001c37f43c4 in __68-[UIInputWindowController postValidatedStartNotifications:withInfo:]_block_invoke ()
#23 0x00000001c37f3fc8 in -[UIInputWindowController postValidatedStartNotifications:withInfo:] ()
#24 0x00000001c37f77a4 in __77-[UIInputWindowController moveFromPlacement:toPlacement:starting:completion:]_block_invoke.905 ()
#25 0x00000001c3ebcafc in +[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:] ()
#26 0x00000001c3ebd050 in +[UIView(UIViewAnimationWithBlocks) _animateWithDuration:delay:options:animations:start:completion:] ()
#27 0x00000001c37f727c in -[UIInputWindowController moveFromPlacement:toPlacement:starting:completion:] ()
#28 0x00000001c37fc354 in -[UIInputWindowController setInputViewSet:] ()
#29 0x00000001c37f6730 in -[UIInputWindowController performOperations:withAnimationStyle:] ()
#30 0x00000001c3511a00 in -[UIInputResponderController setKeyWindowSceneInputViews:animationStyle:] ()
#31 0x00000001c3511150 in -[UIInputResponderController setInputViews:animationStyle:] ()
#32 0x00000001c3512264 in -[UIInputResponderController setInputViews:animated:] ()
#33 0x00000001c35122d4 in -[UIInputResponderController setInputViews:] ()
#34 0x00000001c350feb0 in -[UIInputResponderController _reloadInputViewsForKeyWindowSceneResponder:] ()
#35 0x00000001c350f238 in -[UIInputResponderController _reloadInputViewsForResponder:] ()
#36 0x00000001c3a44168 in -[UIResponder _finishResignFirstResponder] ()
#37 0x00000001c3ce8610 in -[UITextField _finishResignFirstResponder] ()
#38 0x00000001c3a4425c in -[UIResponder resignFirstResponder] ()
#39 0x00000001c3ce8474 in -[UITextField resignFirstResponder] ()
#40 0x00000001c3eb0bfc in -[UIView(Hierarchy) _removeFirstResponderFromSubtree] ()
#41 0x00000001c3eb1108 in __UIViewWillBeRemovedFromSuperview ()
#42 0x00000001c3eb0f50 in -[UIView(Hierarchy) removeFromSuperview] ()
#43 0x00000001f6bd7f48 in PlatformViewHost.removeFromSuperview() ()
#44 0x00000001f6bd7f80 in @objc PlatformViewHost.removeFromSuperview() ()
#45 0x00000001f6c2f830 in DisplayList.ViewUpdater.Container.removeRemaining(viewCache:) ()
#46 0x00000001f6c2f434 in DisplayList.ViewUpdater.update(rootView:from:version:) ()
#47 0x00000001f69a4394 in _UIHostingView.renderDisplayList(_:version:) ()
#48 0x00000001f6dd1cdc in closure #1 in ViewRendererHost.render(interval:updateDisplayList:) ()
#49 0x00000001f6dc6f74 in ViewRendererHost.render(interval:updateDisplayList:) ()
#50 0x00000001f6f428e4 in _UIHostingView.displayLinkTimer(timestamp:) ()
#51 0x00000001f69a4950 in DisplayLink.displayLinkTimer(_:) ()
#52 0x00000001f69a49a8 in @objc DisplayLink.displayLinkTimer(_:) ()
#53 0x00000001c6399bb4 in CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) ()
#54 0x00000001c6468140 in display_timer_callback(__CFMachPort*, void*, long, void*) ()
#55 0x00000001bf879dac in __CFMachPortPerform ()
#56 0x00000001bf8a47c4 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ ()
#57 0x00000001bf8a3e90 in __CFRunLoopDoSource1 ()
#58 0x00000001bf89eac8 in __CFRunLoopRun ()
#59 0x00000001bf89df40 in CFRunLoopRunSpecific ()
#60 0x00000001c9b19534 in GSEventRunModal ()
#61 0x00000001c3a15e08 in UIApplicationMain ()
#62 0x00000001026f211c in main at /Users/XXXXXXXXX/Documents/AppProjects/TestKeyboard/TestKeyboard/AppDelegate.swift:12
#63 0x00000001bf71ce18 in start ()

以下代码可用来复制问题:

(启动一个新的单页应用程序并使用swiftUI,然后将其复制到ContentView文件中)

Here's code to replicate the issue:

(Start a new single page app and use swiftUI then copy this into the ContentView file)

import SwiftUI

enum ContentViewPage {
    case none
    case textField
}

struct ContentView: View {

    @State var showSheet = false
    @State var name = ""
    @State var page = ContentViewPage.textField
    var body: some View {
        VStack {
            Text("Hello, World!")
            Button(action: {
                self.showSheet.toggle()
            }, label: {
                Text("SHOW SHEET")
            })
        }
        .sheet(isPresented: self.$showSheet, content: {
            if self.page == .textField {
                HStack {
                    TextField("Enter some text", text: self.$name)
                    Button(action: {
                        self.page = .none
                    }, label: {
                        Text("Change Page after typing something (Crash happens here)")
                    })
                }
            } else {
                HStack {
                    Button(action: {
                        self.showSheet.toggle()
                    }, label: {
                        Text("Hide Sheet")
                    })
                }

            }

        })
    }
}

我想知道这是一个已知的错误还是我错误地使用了工作表.如果这是一个错误,那么您目前正在使用哪些变通办法?

I'm wondering if this is a known bug or am I using sheets wrongly. If this is a bug, what are some workarounds you guys are using at the moment?

谢谢.

推荐答案

在显示新视图之前尝试关闭键盘.发生的情况是,当您键入内容时,键盘在另一个视图上,该视图消失了.因此,当您要加载新视图或页面"时,请尝试关闭键盘.

Try to dismiss the keyboard before showing a new view. What happens is when you're typing, the keyboard is on the other view, which disappears. So try to close the keyboard when you want to load the new view or in your case "page".

以下代码可关闭键盘:

UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to:nil, from:nil, for:nil)

这篇关于当状态更改导致键盘在工作表中退出时,SwiftUI iOS应用程序崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆