0
votes

I have an image background, which should stay in place when the keyboard shows, but instead it moves up together with everything on the screen. I saw someone recommend using ignoresSafeArea(.keyboard), and this question Simple SwiftUI Background Image keeps moving when keyboard appears, but neither works for me. Here is my super simplified code sample. Please keep in mind that while the background should remain unchanged, the content itself should still avoid the keyboard as usual.

struct ProfileAbout: View {

    @State var text: String = ""

    var body: some View {
        VStack {
            TextField("write something", text: $text)
            Spacer()
            Button("SomeButton") {}
        }
        .background(
            Image("BackgroundName")
                .resizable()
                .aspectRatio(contentMode: .fill)
                .ignoresSafeArea(.keyboard)
        )
    }
}
2

2 Answers

1
votes

u can use GeometryReader

get parent View size

import SwiftUI
import Combine

struct KeyboardAdaptive: ViewModifier {
    @State private var keyboardHeight: CGFloat = 0
    
    func body(content: Content) -> some View {
        GeometryReader { geometry in
            content
                .padding(.bottom, keyboardHeight)
                .onReceive(Publishers.keyboardHeight) {
                    self.keyboardHeight = $0
                }
        }
    }
}

extension Publishers {
    static var keyboardHeight: AnyPublisher<CGFloat, Never> {
        let willShow = NotificationCenter.default.publisher(for: UIApplication.keyboardWillShowNotification)
            .map { $0.keyboardHeight }
        let willHide = NotificationCenter.default.publisher(for: UIApplication.keyboardWillHideNotification)
            .map { _ in CGFloat(0) }
        
        return MergeMany(willShow, willHide)
            .eraseToAnyPublisher()
    }
}
extension View {
    func keyboardAdaptive() -> some View {
        ModifiedContent(content: self, modifier: KeyboardAdaptive())
    }
}
struct ProfileAbout: View {

    @State var text: String = ""

    var body: some View {
        VStack {
            TextField("write something", text: $text)
            Spacer()
            Button("SomeButton") {}
        }
        .background(
            Image("BackgroundName")
                .resizable()
                .aspectRatio(contentMode: .fill)
                .ignoresSafeArea(.keyboard)
        )
        .keyboardAdaptive()
    }
}
1
votes

Here a possible salvation:


enter image description here


import SwiftUI

struct ContentView: View {
    
    @Environment(\.verticalSizeClass) var verticalSizeClass
    
    @State var valueOfTextField: String = String()
    
    var body: some View {
        
        GeometryReader { proxy in
            
            Image("Your Image name here").resizable().scaledToFill().ignoresSafeArea()
            
            ZStack {
                
                if verticalSizeClass == UserInterfaceSizeClass.regular { TextFieldSomeView.ignoresSafeArea(.keyboard) }
                else { TextFieldSomeView }
                
                VStack {
                    
                    Spacer()
                    
                    Button(action: { print("OK!") }, label: { Text("OK").padding(.horizontal, 80.0).padding(.vertical, 5.0).background(Color.yellow).cornerRadius(5.0) }).padding()
                    
                }

            }
            .position(x: proxy.size.width/2, y: proxy.size.height/2)
            
            
        }
        
    }
    
    var TextFieldSomeView: some View {
        
        return VStack {
            
            Spacer()
            
            TextField("write something", text: $valueOfTextField).padding(5.0).background(Color.yellow).cornerRadius(5.0).padding()
            
            Spacer()
            
        }
  
    }
    
}