I had tried this code, I have also tried with stacks but not able to align with top .
I just want the view to appear on top with auto layout as like UIKit .
import SwiftUI
struct ItemDetail: View {
let item : MenuItem
var body: some View {
HStack(alignment: .top){
VStack{
Image(item.mainImage)
Text(item.description)
}
.padding(10)
.background(.red)
.navigationTitle(item.name)
}
}
}
struct ItemDetail_Previews: PreviewProvider {
static var previews: some View {
ItemDetail(item: MenuItem.example)
}
}
Swap the HStack for a VStack and add a Spacer() at the end. e.g.:
struct ItemDetail: View {
let item : MenuItem
var body: some View {
VStack{
VStack{
Image(item.mainImage)
Text(item.description)
}
.padding(10)
.background(.red)
.navigationTitle(item.name)
Spacer()
}
}
}
This should do it:
VStack()
{
VStack
{
Image(item.mainImage)
Text(item.description)
}
.padding(10)
.background(.red)
.navigationTitle(item.name)
Spacer()
}
The default "Keyboard Avoidance" SwiftUI is used.
First GIF
If you put the code in VStack and add another View to it, then the container rises
Second GIF
I don't want to delete Keyboard Avoidance. I need to remove extra spacing
scrollDismissesKeyboard for ScrollView is not an option
minimal iOS version is iOS 16
struct ContentView: View {
#State var text: String = "Bu bu?"
var body: some View {
NavigationStack {
ScrollViewReader { proxy in
VStack {
ScrollView(showsIndicators: false) {
VStack(spacing: 0) {
Spacer()
.frame(height: 500)
TextField("", text: $text)
.padding(.bottom, 70)
.frame(height: 40)
.frame(maxWidth: .infinity)
.background(Color.red)
NavigationLink("Screen 2", destination: {
Text("SwiftUI - Nice to meet you, let's never meet again")
})
}
}
Text("I'm in VSTack after scroll view")
}
}
}
}
}
I looked it up with a hierarchy view, and noticed that a UIInputSetHostView is created with a height of 216
View hierarchy 1
View hierarchy 2
disableAutocorrection not working
I read tons of questions about how to make the app ignore the safe area, but when I create a new app then the status bar space is ignored anyway without
.ignoresSafeArea()
Why is that? I don't want it to be ignored!
This is all I have:
import SwiftUI
struct ContentView: View {
var body: some View {
VStack{
Text("Hello, world!")
.padding()
Spacer()
}
.frame(width: 300)
.background(Color.teal)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
the result screenshot
You can do it like so:
VStack {
Color.teal
.overlay {
Text("Hello World!")
}
}
Ok I got it, inside a ZStack:
GeometryReader { reader in
Color.white
.frame(height: reader.safeAreaInsets.top, alignment: .top)
.ignoresSafeArea()
}
Use this modifier:
.edgesIgnoringSafeArea(.all)
if you don't want everything you can choose : .top, .bottom, .vertical, .horizontal,...
I want to change views once the user taps 'get started' but due to having navigation view in my first view, it is showing back button on my next screen which I don't want. Please see the images attached below.
Code for the first view is below:
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
VStack {
Spacer()
Text("LifePath")
.font(.system(size: 48, weight: .semibold))
.padding(.bottom)
Spacer()
NavigationLink(destination: ViewChanger()) {
Text("Get Started")
.font(.headline)
.navigationBarBackButtonHidden(true)
}
}
.padding()
}
}
}
back button showing on screen 2
First view
Change the location of your navigationBackButtonHidden modifier so that it actually modifies the view that you're going to (and not the NavigationLink label):
struct ContentView: View {
var body: some View {
NavigationView {
VStack {
Spacer()
Text("LifePath")
.font(.system(size: 48, weight: .semibold))
.padding(.bottom)
Spacer()
NavigationLink(destination: ViewChanger()
.navigationBarBackButtonHidden(true) // <-- Here
) {
Text("Get Started")
.font(.headline)
}
}
.padding()
}
}
}
If you want not only the back button to be gone, but the entire header bar, you can use the .navigationBarHidden(true) modifier.
Also, if you run this on iPad at all, you probably want .navigationViewStyle(StackNavigationViewStyle()) added to the outside of your NavigationView
If you use a NavigationLink (in a NavigationView), the view will be pushed. If you want to replace the view, you can do this with an if statement.
For example, this could be implemented like this:
struct ContentView: View {
#State var showSecondView: Bool = false
var body: some View {
if !showSecondView {
NavigationView {
VStack {
Spacer()
Text("LifePath")
.font(.system(size: 48, weight: .semibold))
.padding(.bottom)
Spacer()
Button(action: { showSecondView = true }) {
Text("Get Started")
.font(.headline)
}
}
.padding()
} else {
TabView {
// ...
}
}
}
}
I am trying to use a logo image instead of a NavigationView title at the top section of the app. Couldn't find any documentation of using images inside a NavigationView.
iOS 14+
Starting from iOS 14 you can create a ToolbarItem with the principal placement:
struct ContentView: View {
var body: some View {
NavigationView {
Text("Test")
.toolbar {
ToolbarItem(placement: .principal) {
Image(systemName: "ellipsis.circle")
}
}
}
}
}
See the ToolbarItemPlacement documentation for more placements.
NavigationView.navigationBarTitle() can only take a Text() argument right now. You could instead use .navigationBarItems() to set an Image as either the trailing or leading argument, but this is the SwiftUI equivalent of UINavigationItem.leftBarButtonItem[s] and UINavigationItem.rightBarButtonItem[s], which means that you're restricted to navigation bar button dimensions. But if you're ok with that, you may want to set a blank title so that you can specify a standard-height navigation bar.
Hard-Coded Positioning
If you can stand to live with yourself, you can fake a centered nav bar item by hard-coding padding around the image, like
.padding(.trailing, 125),
(Note that I deliberately positioned it off-center so that you can see that it's hard-coded.)
Slightly Less Hard-Coded Positioning
Even better would be to wrap the whole thing in a GeometryReader { geometry in ... } block to use the screen dimensions to calculate precise positioning, if you know the exact width of the image you're using:
GeometryReader { geometry in
NavigationView {
...
}
.navigationBarTitle(Text(""), displayMode: .inline)
.navigationBarItems(trailing:
PresentationButton(
Image(systemName: "person.crop.circle")
.imageScale(.large)
.padding(.trailing, (geometry.size.width / 2.0) + -30), // image width = 60
destination: ProfileHost()
)
)
If you don't want to hack it, here's what you can do:
Standard nav bar height, left button item
.navigationBarTitle(Text(""), displayMode: .inline)
.navigationBarItems(leading:
PresentationButton(
Image(systemName: "person.crop.circle")
.imageScale(.large)
.padding(),
destination: ProfileHost()
)
)
Standard nav bar height, right button item
.navigationBarTitle(Text(""), displayMode: .inline)
.navigationBarItems(trailing:
PresentationButton(
Image(systemName: "person.crop.circle")
.imageScale(.large)
.padding(),
destination: ProfileHost()
)
)
Expanded nav bar height, no title, left button item
.navigationBarItems(leading:
PresentationButton(
Image(systemName: "person.crop.circle")
.imageScale(.large)
.padding(),
destination: ProfileHost()
)
)
Use this:
NavigationView {
Text("Hello, SwiftUI!")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .principal) {
HStack {
Image(systemName: "sun.min.fill")
Text("Title").font(.headline)
}
}
}
}
Credit: https://sarunw.com/posts/custom-navigation-bar-title-view-in-swiftui/
With SwiftUIX, you can use navigationBarTitleView(View):
NavigationView() {
NavigationLink(destination:YourView().navigationBarTitleView(Image(systemName: "message.fill")))
}
I don't want to claim 100% accuracy whether title image positioned at center but visually it looks center to me. Do your judgment and adjust padding :)
Here is code:
.navigationBarTitle(
Text("")
, displayMode: .inline)
.navigationBarItems(leading:
HStack {
Button(action: {
}) {
Image(systemName: "arrow.left")
}.foregroundColor(Color.oceanWhite)
Image("oceanview-logo")
.resizable()
.foregroundColor(.white)
.aspectRatio(contentMode: .fit)
.frame(width: 60, height: 40, alignment: .center)
.padding(UIScreen.main.bounds.size.width/4+30)
}
,trailing:
HStack {
Button(action: {
}) {
Image(systemName: "magnifyingglass")
}.foregroundColor(Color.oceanWhite)
}
)
To extend on NRitH's answer, putting your logo in a different component (to borrow a React way of putting it) may help anyone looking to understand the concepts.
The actual Image can be wrapped in any container view such as a VStack, etc. An example of setting up a struct as a component to be used in our navigation items could be something like the following:
struct NavLogo: View {
var body: some View {
VStack {
Image("app-logo")
.resizable()
.aspectRatio(2, contentMode: .fit)
.imageScale(.large)
}
.frame(width: 200)
.background(Color.clear)
}
}
When the aspect ratio is set, only the width needs to be set on the frame on the container view. We could also set a property in the NavLogo to set width and/or height from property dependency injection. Regardless, our navigationBarItems becomes very straight forward and more readable 🙂
NavigationView {
Text("Home View")
.navigationBarItems(
leading: NavLogo()
trailing: ProfileButton()
)
}
On iOS 13, a little hacky way to achieve this:
private var logo: some View {
Image("logo-image")
}
var body: some View {
GeometryReader { g in
content()
.navigationBarTitle("")
.navigationBarItems(leading:
ZStack(alignment: .leading) {
logo.frame(width: g.size.width).padding(.trailing, 8)
HStack {
leadingItems().padding(.leading, 10)
Spacer()
trailingItems().padding(.trailing, 10)
}
.frame(width: g.size.width)
}
)
}
}
Try the following.
struct ContainerView: View {
var body: some View {
VStack {
Image(systemName: "person.crop.square")
ContentView()
}
}
}
It worked for me.
Make sure you change ContentView to ContainerView inside SceneDelegate.swift before running on simulator or device.