BackButton without text SwiftUI - swift

Actually, this is the question.
I have a screen like this, I would like to change the BackButton.
My View screen:
enter image description here
I want instead of blue backbutton with standart array + text BACK, just to be black array WITHOUT text.
In other words, essentially remove the text from the backbutton and change the color to black. How not to achieve this?

You can use the appropriate modifiers inside the View you wish to be black and without text. You need to specify no button and supply your own image as well as the return functionality.
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink(destination: SecondView()) {
Text("Hello, World!")
}
}
}
}
struct SecondView: View {
#Environment(\.presentationMode) var presentation
var body: some View {
VStack {
Text("Hello")
Text("Second view")
}
.navigationBarBackButtonHidden(true)
.navigationBarItems(leading: Button(action: {
self.presentation.wrappedValue.dismiss()
}) {
Image(systemName: "chevron.left")
}
.foregroundColor(.black))
}
}
Edited: Inserted the appropriate image.

Related

How can I replace the navigation title in my macOS SwiftUI app with my own code?

How can I replace the navigationTitle with my own element?
To replace the navigationTitle with your own (presumably) non-text code:
Hide the navigationTitle by setting it to an empty string.
Add your own toolbar elements there with the navigation placement.
For example, this code...
struct ContentView: View {
var body: some View {
Text("ABC")
.navigationTitle("")
.toolbar {
ToolbarItem(placement: .navigation) {
Text("This is my own text!")
}
}
}
}
...achieves this result:

How can I change my SwiftUI background without losing the navigation bar UI?

I'm trying to change my View background colour to a specific color, however, whenever I add it using the basic Zstack way, it loses the navigation bar UI. (See pictures)
EDITED CODE
This method is not working for me:
var body: some View {
ZStack{
Color("Background")
.edgesIgnoringSafeArea(.vertical)
VStack {
ScrollView {
ZStack {
VStack {
HStack{
VStack (alignment: .leading) {
Text("")
}
}
}
}
}
Text("")
}
}
}
Current UI with simple ZStack:
Desired UI:
How do I change my background color in SwiftUI without losing the navigation bar UI?
At this period of SwiftUI evolution it is possible only as workaround via UIKit
Here is a demo of possible approach (tested with Xcode 12.1 / iOS 14.1):
var body: some View {
NavigationView {
VStack {
ScrollView {
VStack {
ForEach(0..<50) {
Text("Item \($0)")
}
}
}
Text("Test").navigationTitle("Test")
.background(UINavigationConfiguration { nc in
nc.topViewController?.view.backgroundColor = .yellow
})
}
}
}
Note: the UINavigationConfiguration is taken from next my answer https://stackoverflow.com/a/65404368/12299030

Why NavigationView is shown inline when using emojis in navigationTitle in SwiftUI?

I'm new in SwiftUI and I have come to a weird behavior that is driving me nuts. I'm using the following code as an example:
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
ScrollView {
NavigationLink(
destination: NonEmojiView(),
label: { Text("NON-emoji view.") }
)
Spacer()
NavigationLink(
destination: EmojiView(),
label: { Text("Emoji view.") }
)
}
.navigationTitle("I love emojis")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct EmojiView: View {
var body: some View {
Text("Testing emojis in navigation titles.")
.navigationTitle("♥️")
}
}
struct NonEmojiView: View {
var body: some View {
Text("Testing emojis in navigation titles.")
.navigationTitle("Boring title")
}
}
When I run this app (iOS 14, XCode 12.2) and tap on the Emoji view (second navigation link), and then the "< Back" button in the navigation bar, the inline title style is shown in the navigation bar (image1) instead of the expected one (image 2). Any clue why? Anything am I doing wrong? Is that a SwiftUI bug? The only difference is the emoji in the title.
EDIT: As pointed out by Luffy, if the navigationTitle in ContentView contains an emoji too, it works well. May be related to the height of the title? More points for this to be a SwiftUI bug.
Thanks!!
If you add emoji in a ContentView's navBarTitle, it will work. If you remove it, then it won't. I think it's a SwiftUI bug.
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
ScrollView {
NavigationLink(
destination: NonEmojiView(),
label: { Text("NON-emoji view.") }
)
Spacer()
NavigationLink(
destination: EmojiView(),
label: { Text("Emoji view.") }
)
}
.navigationBarTitle(Text("I ❤️ emojis"), displayMode: .large) // <~ HERE
}
}
}
struct EmojiView: View {
let emoji = Image(systemName: "heart.fill")
var body: some View {
Text("Testing emojis in navigation titles.")
.navigationBarTitle(Text("❤️"), displayMode: .large)
}
}
struct NonEmojiView: View {
var body: some View {
Text("Testing emojis in navigation titles.")
.navigationBarTitle(Text("Boring title"), displayMode: .large)
}
}

SwiftUI TextField takes max width

I have a navigation list with each list item being in this format:
HStack {
TextField("Insert something here.",text: self.$userData.pages[i].title)
.border(Color.blue)
Spacer()
}
This results in the following view:
The touchable area is highlighted by the blue border and it takes the whole width of the row
The problem with this is that despite the list item being a navigation link, the user clicking anywhere along the item will result in them editing the text content. What I would prefer is a TextField that has the same width as a Text:
The blue border wraps the text instead of taking the max width
So if the user clicks outside the TextField, the navigation works, but if they click on the text, it will let them edit the text. (The above view is with Text field).
Apologies if I've asked an unclear or bad question. I'm new to Stack Overflow and SwiftUI.
Edit:
I've tried using the fixedSize modifier, and the TextField correctly wraps my Text, but now the Navigation Link doesn't work (i.e. clicking on it just doesn't navigate). This is my full code:
NavigationLink(destination: PageView(page: self.userData.pages[i])) {
HStack {
Button(action: {}){
TextField(" ", text: self.$userData.pages[i].title)
.fixedSize()
}
.buttonStyle(MyButtonStyle())
.border(Color.blue)
Spacer()
}
}
No need to apologize, your question is clear.
You can do this by using fixedSize()
so your code should be like this
HStack {
TextField("Insert something here.",text: self.$userData.pages[i].title)
.border(Color.blue)
.fixedSize()
Spacer()
}
You can further specify how would you like the stretch to be, either vertical or horizontal or even both by passing parameters like so
.fixedSize(horizontal: true, vertical: false)
UPDATED ANSWER TO MATCH YOUR NEW REQUIREMENTS
import SwiftUI
struct StackOverflow5: View {
#State var text: String = ""
#State var selection: Int? = nil
var body: some View {
NavigationView {
ZStack {
NavigationLink(destination: Page2(), tag: 1, selection:self.$selection) {
Color.clear
.onTapGesture {
self.selection = 1
}
}
TextField("Text", text: self.$text)
.fixedSize()
}
}
}
}
struct StackOverflow5_Previews: PreviewProvider {
static var previews: some View {
StackOverflow5()
}
}
struct Page2: View {
var body: some View {
Text("Page2")
}
}
We used a ZStack here to separate between our TextField and our NavigationLink so they can be interacted with separately.
Note the use of Color.clear before our TextField and this is on purpose so that our TextField has interaction priority. Also we used Color.clear because it will stretch as a background and it's clear so it's not visible.
Obviously I hard coded 1 here but this can be from List or a ForEach
Additionally, if you don't want to use selection and tag you can do something like this
...
#State var isActive: Bool = false
...
NavigationLink(destination: Page2(), isActive: self.$isActive) {
Color.clear
.onTapGesture {
self.isActive.toggle()
}
}
....

SwiftUI Text disappearing behind Navigation Bar

I have an Issue where my text disappears behind the navigation bar. The navigation bar is made visible once the user clicks on Settings (or any other menu button). It shows up and the content is visible but then when done loading the new view the text disappears behind the bar. Any solutions?
I change the status of the navigation bar being visible with .onAppear and .onDisappear of views that are root level.
Code something like this:
struct ContentView: View {
#State public var navBarHidden = true
var body: some View {
NavigationView{
VStack{
ZStack(alignment: .center){
WhiteImage().onAppear{self.navBarHidden = true} //Here only seen as white background
BottomButtons().onDisappear{self.navBarHidden = false}
ProfileInvoke().navigationBarTitle("").navigationBarHidden(self.navBarHidden)
}
}
}
}
}
//The buttons are done with such a construct
struct MenuButton: View {
var buttonText: String
var buttonCallView: AnyView
var body: some View {
NavigationLink(destination: self.buttonCallView) {
Text(self.buttonText)
}.padding()
}
}
//Population of a button
MenuButton(buttonText: "My Favourites", buttonCallView: AnyView(MyFavouritesView().navigationBarTitle(Text("My Favourites"), displayMode: .inline)))
// The settings view where the title disappears
struct SettingsView: View {
var body: some View {
HStack(alignment: .top){
VStack(alignment: .leading){
Text("General").bold()
Divider()
Spacer()
}.padding()
Spacer()
}
}
}
I have the feeling that it has something to do with the .onAppear and .onDisappear where I set the status of the navigation bar being hidden or not. Ain't sure tho.