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 {...}
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.
Here's the dump:
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 ()
(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?
Thanks.
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".
The following line of code dismisses the keyboard:
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to:nil, from:nil, for:nil)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With