键盘显示时 SwiftUI 背景图像移动

SwiftUI background image moves when keyboard shows

我有一个图像背景,它应该在键盘显示时留在原处,但它却与屏幕上的所有内容一起向上移动。我看到有人推荐使用 ignoresSafeArea(.keyboard),而这个问题 ,但都不适合我。这是我超级简化的代码示例。请记住,尽管背景应保持不变,但内容本身仍应像往常一样避开键盘。

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)
        )
    }
}

这是一个可能的救赎:



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()
            
        }
  
    }
    
}

你可以使用 GeometryReader

获取父视图大小

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 = [=10=]
                }
        }
    }
}

extension Publishers {
    static var keyboardHeight: AnyPublisher<CGFloat, Never> {
        let willShow = NotificationCenter.default.publisher(for: UIApplication.keyboardWillShowNotification)
            .map { [=10=].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()
    }
}