I'm working on a SwiftUI View with a NavigationBar. The view is very simple, it's a full-page TextEditor:
struct NotesEditingScreen: View {
#State var text: String
var body: some View {
TextEditor(text: $text)
.padding(.horizontal)
.navigationBarTitle("Editing")
}
}
The issue I'm seeing, is that when landing on this screen (via a NavigationLink) the top of the TextEditor is covered up by Navigation Bar:
My desired behavior is that the TextEditor content appears beneath the Navigation Bar, like it appears after you manually scroll to the top to reveal the text.
Is there a solution/workaround to this issue? I was hoping for either some offset, a setting on NavigationBar, or some programmatic scroll behavior that could be done onAppear. Any suggestions welcome.
I think it's an unexpected behavior.
You can try this:
GeometryReader { geo in
ScrollView {
TextEditor(text: $text)
.frame(height: geo.size.height)
}
}
Related
My app has simple navigation logic using navigation view. I use the inline style navigation bar:
mainView
.navigationBarTitleDisplayMode(.inline)
I notice that the navigation bar's divider is missing for the root view. And it appears when I scroll up the content a bit.
This first screenshot shows the initial state (without nav bar divider):
This second screenshot shows the state when I scroll up the content a bit, and it shows nav bar divider:
Is it possible to always show the divider without scrolling?
I think you can work around by adding a manual Divider and ScrollView under VStack so that the divider will appear beneath the navigation bar
//
// testUI.swift
// DDStore (iOS)
//
// Created by belal medhat on 19/02/2022.
//
import SwiftUI
struct navTitleBar: View {
var body: some View {
NavigationView {
// main navigationView
VStack(){
// vstack to add the divider and under it the scrollview
Divider()
ScrollView(){
Text("Hello, World!")
}.navigationBarTitleDisplayMode(.inline).navigationTitle("Title")
}
}
}
}
struct testUI_Previews: PreviewProvider {
static var previews: some View {
navTitleBar()
}
}
I have four Views inside a TabView and each of them contains NavigationView with title. However, when the view first shows up, the navigation view does not show as designed.
Even though I have the navigation bar item, the view would always be a blank child view. It is only when I click to another page and then coming back to the navigation view that the view would show normally. What could be the problems?
Attached is the screenshot of the preview page. Thanks in advance.
struct MainContentView: View {
#State private var navSelection = 0
var body: some View {
VStack(alignment: .center){
TabView(selection:$navSelection){
NavigationView{
HomeView()
.navigationBarItems(leading: Text("Title").font(.system(size:24,weight: .heavy)), trailing: Image(systemName: "bell.fill"))
.navigationViewStyle(StackNavigationViewStyle())
}.tag(0)
NavigationView{
ExploreView()
}.tag(1)
Text("Post").tag(2)
Text("Market").tag(3)
Text("Account").tag(4)
}.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
.disabled(true)
MainTabBarView(navSelection: self.$navSelection)
}
}
}
The preview sample
Just a small mistake, apply the style to the navigation view as follows:
NavigationView{
}
.navigationViewStyle(.stack)
What went wrong is some how SwiftUI found a detail view somewhere in the hierarchy and pushed it because normally inside NavigationView there are two views defined but you only defined one. I think .tabViewStyle is what caused it.
Also to set the nav item title we use .navigationTitle("Home")
I'm making a screen when I ask the user his name and a Button to the bottom of the page.
My problem is, when I'm focusing the Textfield, the keyboard appears but push up the button. How can I stick my button to the bottom of my view and be hidden by the keyboard ?
Before the keyboard appears:
When the keyboard showed up:
Thanks a lot !
You can use .ignoresSafeArea(.keyboard) modifier:
struct ContentView: View {
#State var text = "Test"
var body: some View{
VStack {
Text("Hello, world")
Spacer()
TextField("", text: $text)
Spacer()
Button("Submit") {}
}.ignoresSafeArea(.keyboard)
}
}
This has to be applied to the surrounding parent stack -- applying it to the Button element alone in the above example has no effect.
I want to build a TabView with 4 tabs having collection views in it. Below is my code of one tab named 'Gallery'.
var body: some View {
NavigationView {
ScrollView {
GridStack(rows: 3, columns: 2) { row, column, totalColumn in
CardView(card: self.cards[(row * totalColumn) + column])
}.padding().background(Color.red)
}
.navigationBarTitle("Gallery")
}
}
When I give background color for ScrollView, scrolling is not working for NavigationView largeTitle. How can I achieve this, I want to give red color for full view's background? What if I need to achieve this same backgorund color for all tabs?
Here is possible approach (scroll view is not broken in such case)
NavigationView {
GeometryReader { gp in
ScrollView {
ZStack(alignment: .top) {
Rectangle().fill(Color.red) // << background
// ... your content here, internal alignment might be needed
}.frame(minHeight: gp.size.height)
}
.navigationBarTitle("Gallery")
}
}
I am able to add Title using .navigationBarTitle(Text((msgDetails.name))) But i wanted to add subtitle under the title in the navigationbar. Looks like title will not accept the View and it accepts only Text. I tried \n in the title but it is not working. IS there any way i can add the subtitle in navigation bar. I used leading and trailing to add left and right button in the navigation bar. I wanted to show title and subtitle along with this left and right button
Navigation Bar
If you look in SwiftUI documentation you'll see only a few overloads of navigationBarTitle function. All of them requires special parameters, like Text or StringProtocol. So you can't just put some View into navigation bar.
I can propose one strange, but working version. It's about using .navigationBarItems(leading:... - it requires some view, which you can customize (within reason). Here is simple example:
struct ContentView: View {
var body: some View {
NavigationView {
Text("Main view")
.navigationBarItems(leading:
HStack {
Button(action: {}) {
Image(systemName: "return")
}
VStack {
Text("Title")
.bold()
.font(.system(size: 30))
Text("Subtitle")
.italic()
.font(.system(size: 15))
}
.padding(.horizontal, 100) // mb it's better to use GeometryReader for centering
})
}
}
}
and you'll achieve something like this: