TextField In Tab View will show space upon keyboard - ios

I'm using text field in Tab view, but when keyboard shows out. There has a space upon keyboard.
enter image description here
var body: some View {
TabView {
TestView()
}
}
var body: some View {
VStack {
ScrollView(.vertical, showsIndicators: false) {
ForEach(0..<100) { data in
Text("\(data)")
}
}
Spacer()
HStack {
Image(systemName: "paperplane")
TextField("test field", text: $test)
.textFieldStyle(RoundedBorderTextFieldStyle())
}
}
.padding()
.ignoresSafeArea(.keyboard, edges: .bottom)
}
If I'm using without Tab view, the keyboard works totally fine.
enter image description here
I took some search and put .ignoresSafeArea(.keyboard, edges: .bottom), I don't know why it still doesn't work.

Modifier should be applied in correct place:
HStack {
Image(systemName: "paperplane")
TextField("test field", text: $test)
.textFieldStyle(RoundedBorderTextFieldStyle())
}
.ignoresSafeArea(.keyboard, edges: .bottom) // << here !!
Tested with Xcode 13.4 / iOS 15.5

Related

Extraneous alignment of a SwiftUI.Menu when animated by the keyboard appearing

I'm facing a weird alignment issue with a floating menu when the keyboard appears and I've no idea if there's a workaround. To reproduce the issue, simply copy and paste this code:
struct ContentView: View {
#State var searchQuery = ""
var customToolbarButton: some View {
VStack {
Text("Example").font(.footnote)
Image(systemName: "arrowtriangle.down.fill").imageScale(.small)
}.foregroundColor(.accentColor)
}
var body: some View {
NavigationView {
Rectangle().fill(.red)
.safeAreaInset(edge: .bottom) {
HStack(alignment: .center) {
customToolbarButton
Spacer()
Menu { } label: {
customToolbarButton
}
}
.frame(height: 52)
.padding(.horizontal)
.background(Color.white)
.clipShape(Capsule(style: .continuous))
}
}.searchable(text: $searchQuery)
}
}
When the keyboard appears and moves the HStack up, the views that are a Menu are wrongly placed, all other views seem fine. Any idea if there's a fix?
Video to illustrate the issue: https://twitter.com/xmollv/status/1616851571832229889

SwiftUI ScrollView extra padding when go to another screen with showed keyboard

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

SwiftUI - How to prevent keyboard in a sheet to push up my main UI

I'm using sheets (SwiftUI) during an onboarding to let people enter text, however whenever the sheet is dismissed, the elements in the background move, as if the keyboard was pushing them up and down. If the keyboard is not on screen, the elements in the background don't move when the sheet is dismissed. I've tried to use .ignoresSafeArea(.keyboard, edges: .bottom) but it doesn't seem to work.
Any idea regarding how to "fix" the background elements while a sheet with a keyboard is dismissed?
private var welcomeSection5: some View {
ZStack {
VStack {
// This is the part that moves up and down
TellSlideView(text: "And what's your age \(userName) if I may?")
Spacer()
Button(action: {
displaySheet.toggle()
}, label: {
Text("Enter age")
.padding()
.foregroundColor(Color.white)
.frame(maxWidth: .infinity)
.background(Color.MyTheme.Purple)
.cornerRadius(15)
.padding(.horizontal)
.padding(.bottom, 40)
})
}.sheet(isPresented: $displaySheet) {
AddUserAgeView(onboardingState: $onboardingState)
}.ignoresSafeArea(.keyboard, edges: .bottom)
}
}
I had a similar problem once. I can't reproduce your code, but you might try using GeometryRadar like this:
GeometryReader { geometry in
ZStack {
VStack {
// This is the part that moves up and down
}
}
}
.ignoresSafeArea(.keyboard, edges: .bottom)

SwiftUI Dismiss keyboard on List NavigationLink item tap

I have a list of items and a text field for search keywords. When I do search on the list and tap on items, navigationlink works faster than keyboard dismiss, and this causes a disabled area in the next scroll view.
// search TextField
HStack {
Spacer(minLength: 10)
Image(systemName: "magnifyingglass")
.foregroundColor(.gray)
TextField("Search",
text: self.$textbox){
UIApplication.shared.endEditing()
}
.onChange(of: textbox) {
print($0)
dictionaryListVM.getResult(language: self.currentLanguage, text: self.textbox)
self.theId += 1
}
.accessibility(identifier: "loginUserName")
.background(Color.white)
.frame(height: 10, alignment: .leading)
.padding()
}.overlay(
RoundedRectangle(cornerRadius: 4)
.stroke(Color.gray, lineWidth: 2)
)
// Subview for displaying items:
GeometryReader { reader in
ScrollView {
VStack {
if model.dataLoaded {
List {
ForEach(self.model.englishDictionaries, id: \.id) { item in
ZStack {
VStack(alignment: .leading, spacing: 4) {
Text("\(item.value)").font(.title2)
Text("\(item.pairWord)").foregroundColor(.gray).font(.caption)
}
NavigationLink(destination: WordDetailView(englishWordId: item.id, englishWord: item.value, lang: "en")) {
}
.isDetailLink(false)
.buttonStyle(PlainButtonStyle()).frame(width:0).opacity(0)
}
}
}.frame(height: reader.size.height)
.animation(.linear)
}else{
Text("Words sync inprogress, please comeback later.")
}
}
}.padding(.leading, 10)
}
So, I want to make sure that my keyboard is dismayed before navigation to the next view.
check out demo for the issue in action
If you are using iOS 15
I believe you can make use of the #FocusState Property wrapper to dismiss the keyboard.
First you will have to define a variable to hold the focus value.
#FocusState private var isFocused: Bool
Adding the .focused(_:) View Modifier to the TextField:
TextField("Hello There", text: $someText)
.focused($isFocused)
Toggling $isFocused on button press or navigation link press. You can set it as shown below:
isFocused = false

SwiftUI change view from first screen to tabview screen

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 {
// ...
}
}
}
}

Resources