ios - 当状态更改导致键盘在工作表中退出作为第一响应者时,SwiftUI iOS 应用程序崩溃

标签 ios swift xcode swiftui

我正在尝试创建具有多个“页面”的工作表中的 View 。该 View 包含枚举的 @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")
                    })
                }

            }

        })
    }
}

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

谢谢。

最佳答案

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

以下代码行关闭键盘:

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

关于ios - 当状态更改导致键盘在工作表中退出作为第一响应者时,SwiftUI iOS 应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58952203/

相关文章:

ios - Swift iOS 应用存档错误

ios - UICollectionView + 自定义单元格

ios - 有什么可靠的方法可以确定某个应用程序是否已在设备上卸载?

ios - 构建 flutter 项目时架构 x86_64 的 undefined symbol

ios - 无法在 NSUserDefaults 中设置数组

arrays - 将 NSTableView 中显示的数组行传递到 Swift 中的另一个数组

ios - phonegap iOS 应用程序可在模拟器上运行,但不能在设备上运行。如何调试

使用 xCode 5.1.1 进行 iOS 编程

iphone - 关于如何实现图像幻灯片/轮播的建议? ( iOS )

ios - 如何根据选择的日期显示 UITableView?