繁体   English   中英

SwiftUI iOS 应用程序在 state 更改导致键盘在工作表中辞去第一响应者时崩溃

[英]SwiftUI iOS app crashes when state change causes keyboard to resign as first responder while in a sheet

我正在尝试在具有多个“页面”的工作表中创建一个视图 该视图包含一个枚举的@State变量,我在页面之间“切换”

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

但是,如果在其中一个页面中的文本字段处于活动状态时设置了 self.page,则应用程序会崩溃,并且没有明确的错误消息。 这似乎适用于模拟器,但不适用于设备。

这是转储:

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 文件中)

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")
                    })
                }

            }

        })
    }
}

我想知道这是一个已知的错误还是我错误地使用了工作表。 如果这是一个错误,你们目前正在使用哪些解决方法?

谢谢。

在显示新视图之前尝试关闭键盘。 发生的情况是,当您打字时,键盘位于另一个视图上,该视图消失了。 因此,当您要加载新视图或在您的情况下为“页面”时,请尝试关闭键盘。

以下代码行关闭键盘:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM