Hello,
I took a little bit of a break from looking at this and then decided to come back to it today.
I tried to proceed with a solution using NavigationStack but encountered two issues. I'll detail them below.
My NavigationStack follows this hierarchy. Welcome -> Enter Name -> Enter Job
I use NavigationLink as follows to go from one view to another:
NavigationLink(destination: OnboardingNameView(vc: vc)) {
OnboardingButtonView(buttonString: "next".localized())
}
Issue 01:
If I press Next on WelcomeView, it takes me to EnterNameView as expected. If I hit back to return to WelcomeView, the Next Button no longer works until I force quit and re-open the app.
Issue 02:
On EnterNameView the Next Button is greyed out and can not be pressed. Normally it will appear blue and can be used as normal.
I tested both of these issues in iOS 17 vs iOS 18 using the exact same code. No issues in iOS 17 and everything works as expected.
It seems to fix this I may need to completely re-build every facet of my navigation. This is a lot of work so I opted to look for an alternate solution.
Alternate Solution
Previously I detailed that NavigationView would present a blank screen with a sidebar button. This is still the case. I could never pressed the sidebar button as it would appear outside of the safe area and thus taps would not work. When I added padding I could press the button and it printed this in the console:
unknown display mode: Automatic
With this in mind I found that you can still use NavigationView in iOS 18 with:
.navigationViewStyle(.stack)
It seems that the .automatic navigationViewStyle has been removed in iOS 18 which is why it doesn't work by default.
However I still had an issue. Same code, in iOS 17 it automatically adds safe area insets to NavigationView or NavigationStack, in iOS 18 this is not the case.
I found that if I add 0.5 Vertical Padding as per the below the NavigationView and/or NavigationStack would show as intended:
.padding(.vertical, 0.5)
The only other issue that I am facing is that the slide animation when you navigate forward and back in a NavigationView or NavigationStack does not work in iOS 18 which my existing code. It does work with a clean project using NavigationStack and Rectangles with different colors. I'm not sure what it is in my existing code that causes the animation to break, however the animation works fine in iOS 17. I have seen that a few other developers have had the 'no animation' issue in iOS 18.
As this overarching issue essentially breaks my onboarding process which means new users can not access the app if running iOS 18, I opted for a manual version check workaround. For reference, Apple will not let you use a normal version check for an unreleased iOS Version as per the below:
if #available(iOS 16.0, *)
Please see below for a complete code snippet with all workarounds. I may not have animation on iOS 18 but at least users can use my app as intended on iOS 17 and still access it if they opt to try the iOS 18 Beta.
import SwiftUI
struct FirstLoadOnboardingView: View {
@StateObject var vc: FirstLoadOnboardingViewController
@State private var verticalPadding: Double = 0
var body: some View {
NavigationView {
OnboardingWelcomeView(vc: vc)
}
.navigationViewStyle(.stack)
.padding(.vertical, verticalPadding)
.onAppear {
let systemVersion = UIDevice.current.systemVersion
if systemVersion.contains("18.") {
// Update Vertical Padding for iOS 18
verticalPadding = 0.5
}
}
}
}
Post
Replies
Boosts
Views
Activity
Yes, that is what I thought until I tried to use the UIContainerView in my actual project, rather than the new, bare bones test project. Using UIContainerView in my actual project still has the same issues as described above.
Also, I noticed that UIContainerView isn't actually a subclass of UIView, it is just a UIView inserted as a child. So it's unclear exactly why using UIContainerView via Interface Builder fixes the problem in the Test Project and why UIView is functioning different than it did in iOS 17.
I just did a test with a UIContainerView instead of a UIView as the 'containerView' in which the SwiftUI View is drawn.
Everything works as expected in UIContainerView. It seems that there are changes to UIView in iOS 18 that impact how it handles safe area insets.
Thanks for getting back so quickly.
I am using Xcode 16.0 beta 3 on macOS 15.0 beta 3 (24A5289h) running in a VM with a 14.5 Host.
At a glance, one difference I can see if that I am using a UIView as my 'containerView' where it looks you are using a 'UIContainerView'.
I understand that I can switch to using Safe Area and tweak all of the subsequent views, but in iOS 17 it is setup as Superview and all safe area insets are handled on the Swift UI Side.
It seems I can not upload my project here as a Zip File, this is a link to download my project so we are 100% on the same page:
https://drive.google.com/file/d/1cCaY4trWLJqDSxtxTwUGqwQIfQ305_j2/view?usp=drivesdk
Thanks Sydney!
I created a sample project and the issue persists, please see the below code snippet:
import UIKit
import SwiftUI
class ViewController: UIViewController {
@IBOutlet weak var containerView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
let onboardingView = UIHostingController(rootView: FirstLoadOnboardingView())
SwiftUIBrain().assign(hostingController: onboardingView, to: containerView)
}
}
struct SwiftUIBrain {
func assign(hostingController: UIHostingController<some View>, to uiKitView: UIView) {
uiKitView.addSubview(hostingController.view)
hostingController.view.translatesAutoresizingMaskIntoConstraints = false
hostingController.view.topAnchor.constraint(equalTo: uiKitView.topAnchor).isActive = true
hostingController.view.bottomAnchor.constraint(equalTo: uiKitView.bottomAnchor).isActive = true
hostingController.view.leftAnchor.constraint(equalTo: uiKitView.leftAnchor).isActive = true
hostingController.view.rightAnchor.constraint(equalTo: uiKitView.rightAnchor).isActive = true
}
}
struct FirstLoadOnboardingView: View {
var body: some View {
NavigationView {
Rectangle().foregroundColor(.red)
}
}
}
The 'containerView' is setup as per the below images with constraints to the edge of the display:
NavigationView in the sample project still just displays the Sidebar Button in the top left and does not show the Red Rectangle. I'm not sure why it is doing this.
If you comment out NavigationView and just have the Red Rectangle View it shows as it should, that is a SwiftUI View that respects the safe areas.
It seems that if I use NavigationStack and modify the constraints of the 'containerView' it will work as expected, however those constraints work in iOS 17 with NavigationView and display correctly as is, so it'd mean I'd need to programatically change the constraint values if it's running on iOS 18.
My understanding of this is that I am giving the SwiftUI View the full screen to work with within the UIViewController, as I am using NavigationStack it should apply it's own Safe Area Insets considering the NavBar based on the iPhone. But it seems that NavigationStack does not create it's own safe area insets in iOS 18. I just tested NavigationStack in iOS 17 and the Safe Area Insets are created and respected.
So I think there are two issues here:
NavigationView does not display content and shows a Sidebar Button
NavigationStack does not create it's own Safe Area Insets
Thank you!
I was in contact with 'Apple Developer Support - Development and Technical' about this issue, they say they can not help and to wait for an Apple Engineer to engage on this forum?
Unfortunately, we are unable to provide support for the issue you are facing. Apple Developer Program Support Team provides administrative-level support to members of the Apple Developer Programs.
As mentioned previously, please refer to the Developer Forums to engage with Apple engineers and other developers.
I have posted the file that shows as a Keylogger to VirusTotal:
https://www.virustotal.com/gui/file/13a83bec5ada72c38d4da13657f95acc9682bab8ca14671d00b0941779236468
Only ClamAV and Google seem to detect it as a Keylogger. Not sure if this is a false flag or it is indeed a problem. Again, I can confirm that these files only exist in /Users/username/Library/Developer/Xcode/iOS DeviceSupport/. If you delete the contents of this directory they are gone and not appear again until you test with Xcode using a physical iOS Device. This implies that files are present on iOS/iPadOS and are transferred across for debug. So again, I'm not sure if the iOS Devices are compromised or if this is a false flag.
Any help from Apple would be appreciated!
I finally got to the bottom of my issue thanks to some help on reddit. The problem was an image that I was using in the widget was too large in resolution, thus large in file size and it capped out the 30MB Memory Limit of Widgets.
The reddit user that helped me had this to say:
'Black or redacted widget means that during loading you hit the 30 mb memory limit.
Also if you're reloading more than one widget at a time, it seems that there's a higher chance you'll hit the memory budget.'
'Forgot to mention that black/redacted widget can also happen if the widget crashes (not necessary due to memory budget). So maybe you have some threading problems or are force unwrapping something that is nil.'