gpt4 book ai didi

swift - 如何正确更新修改器?

转载 作者:行者123 更新时间:2023-12-01 17:11:55 24 4
gpt4 key购买 nike

我试图在存在文本字段时使 View 中的每个对象向上移动,并且为了减少代码量,我尝试将修饰符制作为修饰符类,但问题是当 y 值获取时更改了键盘处理程序,它不会移动。如果您不使用单独的函数,这个确切的代码就可以工作,所以我不知道出了什么问题。

我尝试将 y 的值设置为修饰符中的状态,但它仍然不会更新 - 正如我所说,如果它不在自定义修饰符中,它就可以工作。

ContentView.swift

struct ContentView: View {
@State private var name = Array<String>.init(repeating: "", count: 3)
@ObservedObject private var kGuardian = KeyboardGuardian(textFieldCount: 1)


var body: some View {
Background {
VStack {
Group {
Text("Some filler text").font(.largeTitle)
Text("Some filler text").font(.largeTitle)
}

TextField("enter text #1", text: self.$name[0])
.textFieldStyle(RoundedBorderTextFieldStyle())

TextField("enter text #2", text: self.$name[1])
.textFieldStyle(RoundedBorderTextFieldStyle())

TextField("enter text #3", text: self.$name[2])
.textFieldStyle(RoundedBorderTextFieldStyle())
.background(GeometryGetter(rect: self.$kGuardian.rects[0]))

}
}.modifier(BetterTextField(kGuardian: kGuardian, slide: kGuardian.slide))
}

}

KeyboardModifications.swift

struct GeometryGetter: View {
@Binding var rect: CGRect

var body: some View {
GeometryReader { geometry in
Group { () -> AnyView in
DispatchQueue.main.async {
self.rect = geometry.frame(in: .global)
}

return AnyView(Color.clear)
}
}
}
}

final class KeyboardGuardian: ObservableObject {
public var rects: Array<CGRect>
public var keyboardRect: CGRect = CGRect()

// keyboardWillShow notification may be posted repeatedly,
// this flag makes sure we only act once per keyboard appearance
public var keyboardIsHidden = true

@Published var slide: CGFloat = 0
var appearenceDuration : Double = 0

var showField: Int = 0 {
didSet {
updateSlide()
}
}

init(textFieldCount: Int) {
self.rects = Array<CGRect>(repeating: CGRect(), count: textFieldCount)

NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillHide(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)

}

deinit {
NotificationCenter.default.removeObserver(self)
}

@objc func keyBoardWillShow(notification: Notification) {

guard let duration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double else {return}
appearenceDuration = duration

if keyboardIsHidden {
keyboardIsHidden = false
if let rect = notification.userInfo?["UIKeyboardFrameEndUserInfoKey"] as? CGRect {
keyboardRect = rect
updateSlide()
}
}
}

@objc func keyBoardWillHide(notification: Notification) {
keyboardIsHidden = true
updateSlide()
}

func updateSlide() {
if keyboardIsHidden {
slide = 0
} else {
let tfRect = self.rects[self.showField]
let diff = keyboardRect.minY - tfRect.maxY

if diff > 0 {
slide += diff
} else {
slide += min(diff, 0)
}

}
}
}

struct Background<Content: View>: View {
private var content: Content

init(@ViewBuilder content: @escaping () -> Content) {
self.content = content()
}

var body: some View {
Color.white
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
.overlay(content)
}
}

自定义修饰符类:

struct BetterTextField: ViewModifier {
public var kGuardian : KeyboardGuardian
@State public var slide : CGFloat
func body(content: Content) -> some View {
content
.offset(y: slide).animation(.easeIn(duration: kGuardian.appearenceDuration))
.onTapGesture {
let keyWindow = UIApplication.shared.connectedScenes
.filter({$0.activationState == .foregroundActive})
.map({$0 as? UIWindowScene})
.compactMap({$0})
.first?.windows
.filter({$0.isKeyWindow}).first
keyWindow!.endEditing(true)
}
}
}

应该发生的是整个屏幕应该随着键盘向上移动,但它保持原样。我已经尝试了大约 2 个小时,但没有成功。

最佳答案

我猜你的幻灯片变量没有更新。尝试在 BetterTextField 修饰符中使用以下更改代码:

struct BetterTextField: ViewModifier {
@ObservedObject var kGuardian : KeyboardGuardian
func body(content: Content) -> some View {
content
.offset(y: kGuardian.slide).animation(.easeIn(duration: kGuardian.appearenceDuration))
.onTapGesture {
let keyWindow = UIApplication.shared.connectedScenes
.filter({$0.activationState == .foregroundActive})
.map({$0 as? UIWindowScene})
.compactMap({$0})
.first?.windows
.filter({$0.isKeyWindow}).first
keyWindow!.endEditing(true)
}
}
}

关于swift - 如何正确更新修改器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58036545/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com