This problem appears only if use NavigationLink(isActive: , destination: , label: ). If use NavigationLink(destination:, label:) - NO problems
Post
Replies
Boosts
Views
Activity
This is minimal code to reproduce.
@main
struct ios15testApp: App {
var body: some Scene {
WindowGroup {
ContentView(viewModel: .init())
}
}
}
struct ContentView: View {
@StateObject var viewModel: ViewModel
var body: some View {
if viewModel.showNav {
NavigationView {
ZStack {
Color.yellow
Button(action: {
viewModel.goNext = true
}, label: {
Text("go to next view")
})
NavigationLink(isActive: $viewModel.goNext,
destination: {
View1(viewModel: .init())
},
label: {
EmptyView()
})
}
}
.navigationViewStyle(StackNavigationViewStyle())
}
else {
ZStack {
Color.red
Text("New View")
}
}
}
}
extension ContentView {
class ViewModel: ObservableObject {
@Published var showNav = true
@Published var goNext = false
var cancellable: Cancellable?
init() {
DeinitHelper.onInit(object: self)
cancellable = NotificationCenter.default
.publisher(for: Notification.Name("ChangeView"))
.sink() { _ in
self.showNav.toggle()
}
}
deinit {
DeinitHelper.onDeinit(object: self)
}
}
}
struct View1: View {
@StateObject var viewModel: ViewModel
var body: some View {
ZStack {
Button(action: {
viewModel.goNext = true
}, label: {
Text("Go Next")
})
NavigationLink(isActive: $viewModel.goNext,
destination: {
View2(viewModel: .init())
},
label: {
EmptyView()
})
}
}
}
extension View1 {
class ViewModel: ObservableObject {
@Published var goNext = false
init() {
DeinitHelper.onInit(object: self)
}
deinit {
DeinitHelper.onDeinit(object: self)
}
}
}
struct View2: View {
@StateObject var viewModel: ViewModel
var body: some View {
ZStack {
Button(action: {
viewModel.goNext = true
}, label: {
Text("Go Next")
})
NavigationLink(isActive: $viewModel.goNext,
destination: {
View3(viewModel: .init())
},
label: {
EmptyView()
})
}
}
}
extension View2 {
class ViewModel: ObservableObject {
@Published var goNext = false
init() {
DeinitHelper.onInit(object: self)
}
deinit {
DeinitHelper.onDeinit(object: self)
}
}
}
struct View3: View {
@StateObject var viewModel: ViewModel
var body: some View {
ZStack {
Button(action: {
viewModel.goNext = true
}, label: {
Text("Go Next")
})
NavigationLink(isActive: $viewModel.goNext,
destination: {
View4(viewModel: .init())
},
label: {
EmptyView()
})
}
}
}
extension View3 {
class ViewModel: ObservableObject {
@Published var goNext = false
init() {
DeinitHelper.onInit(object: self)
}
deinit {
DeinitHelper.onDeinit(object: self)
}
}
}
struct View4: View {
@StateObject var viewModel: ViewModel
var body: some View {
Button(action: {
NotificationCenter.default.post(name: Notification.Name("ChangeView"), object: nil)
}) {
Text("Change Main View")
}
}
}
extension View4 {
class ViewModel: ObservableObject {
init() {
DeinitHelper.onInit(object: self)
}
deinit {
DeinitHelper.onDeinit(object: self)
}
}
}
import os
struct DeinitHelper {
static func onDeinit(object: AnyObject) {
os_log("deInit %s", log: Log.debug, type: .debug, String(describing: object))
}
static func onInit(object: AnyObject) {
os_log("!!! Init %s", log: Log.debug, type: .debug, String(describing: object))
}
}
struct Log {
static let debug = OSLog(subsystem: "Test", category: "debug")
}
Log from iOS 15.
2021-09-18 10:21:43.066023+0300 ios15test[43190:444462] [debug] !!! Init ios15test.ContentView.ViewModel
2021-09-18 10:21:44.220878+0300 ios15test[43190:444462] [debug] !!! Init ios15test.View1.ViewModel
2021-09-18 10:21:45.562711+0300 ios15test[43190:444462] [debug] !!! Init ios15test.View2.ViewModel
2021-09-18 10:21:46.238179+0300 ios15test[43190:444462] [debug] !!! Init ios15test.View3.ViewModel
2021-09-18 10:21:47.635900+0300 ios15test[43190:444462] [debug] !!! Init ios15test.View4.ViewModel
2021-09-18 10:21:48.873941+0300 ios15test[43190:444462] [debug] deInit ios15test.View4.ViewModel
2021-09-18 10:21:48.875682+0300 ios15test[43190:444462] [debug] deInit ios15test.View2.ViewModel
2021-09-18 10:21:48.875730+0300 ios15test[43190:444462] [debug] deInit ios15test.View1.ViewModel
2021-09-18 10:21:48.875874+0300 ios15test[43190:444462] [debug] deInit ios15test.View3.ViewModel
2021-09-18 10:21:48.876261+0300 ios15test[43190:444462] [debug] !!! Init ios15test.View4.ViewModel
2021-09-18 10:21:50.473198+0300 ios15test[43190:444462] [debug] deInit ios15test.View4.ViewModel
Log from iOS 14
2021-09-18 11:24:18.957072+0300 ios15test[44741:493113] [debug] !!! Init ios15test.ContentView.ViewModel
2021-09-18 11:24:20.372983+0300 ios15test[44741:493113] [debug] !!! Init ios15test.View1.ViewModel
2021-09-18 11:24:21.018618+0300 ios15test[44741:493113] [debug] !!! Init ios15test.View2.ViewModel
2021-09-18 11:24:22.048887+0300 ios15test[44741:493113] [debug] !!! Init ios15test.View3.ViewModel
2021-09-18 11:24:23.003798+0300 ios15test[44741:493113] [debug] !!! Init ios15test.View4.ViewModel
2021-09-18 11:24:23.619264+0300 ios15test[44741:493113] [debug] deInit ios15test.View1.ViewModel
2021-09-18 11:24:23.619511+0300 ios15test[44741:493113] [debug] deInit ios15test.View2.ViewModel
2021-09-18 11:24:23.619724+0300 ios15test[44741:493113] [debug] deInit ios15test.View3.ViewModel
2021-09-18 11:24:24.518013+0300 ios15test[44741:493113] [debug] deInit ios15test.View4.ViewModel
I found solution
var body: some View {
GeometryReader { _ in
//your view
}
.ignoresSafeArea(.keyboard, edges: isKeyboardVisible ? .top : .bottom)
}
For detecting if keyboard is visible or not you can use any solution that you like. as example https://stackoverflow.com/questions/65784294/how-to-detect-if-keyboard-is-present-in-swiftui