Swiftui iOS App Crashes When State Change Causes Keyboard to Resign as First Responder While in a Sheet

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

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)

SwiftUI app crashes when trying to expand/collapse sections on a sheet

In case anyone lands here from google, it ended up being the same problem as here SwiftUI iOS app crashes when state change causes keyboard to resign as first responder while in a sheet

In my case however the stack was unhelpfully empty and only after countless attempts did I get one that had ViewRendererHost.render on top apart from generic 'main' event loop. Sure enough googling it immediately produced the above link

Reported this to Apple. It's clearly a bug in SwiftUI

SwiftUI - Intermittent crash when presenting sheet on a sheet

I ran into a similar problem a few weeks ago. Turns out that when I presented the new sheet with the keyboard open it would lead to a crash.

I found using UIApplication.shared.endEditing() before showing the second sheet would solve the problem

UPDATE

For iOS 14 I’ve created an extension because the above function is no longer available

extension UIApplication {

static func endEditing() {
let resign = #selector(UIResponder.resignFirstResponder)
UIApplication.shared.sendAction(resign, to: nil, from: nil, for: nil)
}

}

The usage is similar UIApplication.endEditing()

SwiftUI: How to make TextField become first responder?

iOS 15.0+

macOS 12.0+,

Mac Catalyst 15.0+,

tvOS 15.0+,

watchOS 8.0+

Use focused(_:) if you have a single TextField.

focused(_:)

Modifies this view by binding its focus state to the given Boolean state value.

struct NameForm: View {

@FocusState private var isFocused: Bool

@State private var name = ""

var body: some View {
TextField("Name", text: $name)
.focused($isFocused)

Button("Submit") {
if name.isEmpty {
isFocued = true
}
}
}
}

Use focused(_:equals:) should you have multiple TextFields.

focused(_:equals:)

Modifies this view by binding its focus state to the given state value.

struct LoginForm: View {
enum Field: Hashable {
case usernameField
case passwordField
}

@State private var username = ""
@State private var password = ""
@FocusState private var focusedField: Field?

var body: some View {
Form {
TextField("Username", text: $username)
.focused($focusedField, equals: .usernameField)

SecureField("Password", text: $password)
.focused($focusedField, equals: .passwordField)

Button("Sign In") {
if username.isEmpty {
focusedField = .usernameField
} else if password.isEmpty {
focusedField = .passwordField
} else {
handleLogin(username, password)
}
}
}
}
}

SwiftUI Documentation

  • focused(_:)
  • focused(_:equals:)
  • @FocusState


Update

I tested this in Xcode version 13.0 beta 5 (13A5212g). It works

AsyncImage not loading inside VStack

try this, replacing EmptyView() : (note there is no need for the "!" for the url)

struct ContentView: View {
var body: some View {
VStack {
AsyncImage(url: URL(string: "https://i.scdn.co/image/ab6761610000e5ebb78f77c5583ae99472dd4a49")) { phase in
switch phase {
case .success(let image):
image
default: Color.clear // <-- here
}
}
}
}
}

SwiftUI: Dismiss all active sheet views

You can use this line to dismissing all the presented sheets.

UIApplication.shared.windows.first?.rootViewController?.dismiss(animated: true, completion: nil)

Is there a way to change dark to light theme and vice versa just like using a toggle programmitically in swift UI?

WindowGroup {
switch currentThemeRawValue {
case Theme.dark.rawValue:
ContentView().environment(\.colorScheme, .dark)
case Theme.light.rawValue:
ContentView().environment(\.colorScheme, .light)
default:
ContentView().environment(\.colorScheme, .dark)
}
}

The switch statement means that SwiftUI is populating the view with conditional content, so it would rebuild the entire hierarchy if the value changes. You only really want to change the environment value itself, so something like this would probably be better:

WindowGroup {
ContentView()
.environment(\.colorScheme, currentThemeRawValue == "dark" ?? .dark : .light)
}


Related Topics



Leave a reply



Submit