バックエンドに Realm を使用するアプリの UI を開発しました。テキストは、画面を効率的に使用するために「フローティング」ラベルを使用するカスタマイズされた TextField にユーザーが入力します。ラベル アニメーション (非常に単純なロジックに基づく) は、Realm オブジェクトのプロパティとカスタム ビューの間の Binding の状態をチェックすることによってトリガーされます。
ビューのプロトタイプを作成していたときに、構造体に基づく @State または @Binding プロパティを使用したところ、ビューは期待どおりに動作しました。ただし、メイン アプリでこれを使用する場合、@State または @Binding はクラス (レルム オブジェクト) をラップし、遷移はトリガーされません。これは、ビューが内部状態の変更を登録しないため、再生成されないためです。 -色とオフセットを変更してレンダリング。
クラスを操作するときに @ObservableObject を使用する必要があることに気付いたとき、解決策があると思いましたが、これも機能しません。よく考えてみると、これは理にかなっているように思えますが、さまざまなプロパティ ラッパーがどのように機能しているかについて少し混乱しています。
これには回避策があり、最初の呼び出しポートは willChange にフックして必要な状態を変更する可能性が高いと思われます。しかし、それまでの間、私は少しぼんやりしているので、誰かがここで何が起こっているのか説明できますか. たまたま解決策が手元にある場合、これは私が狂った接線に行くのを止めるかもしれませんか?
カスタム ビュー:
struct FloatingLabelTextField: View {
let title: String
let text: Binding<String>
let keyboardType: UIKeyboardType?
let contentType: UITextContentType?
var body: some View {
ZStack(alignment: .leading) {
Text(title)
.foregroundColor(text.wrappedValue.isEmpty ? Color(.placeholderText) : .accentColor)
.offset(y:text.wrappedValue.isEmpty ? 0 : -25)
.scaleEffect(text.wrappedValue.isEmpty ? 1 : 0.8, anchor: .leading)
TextField("", text: text, onEditingChanged: { _ in print("Edit change") }, onCommit: { print("Commit") })
.keyboardType(keyboardType ?? .default)
.textContentType(contentType ?? .none)
}
.padding(15)
.border(Color(.placeholderText), width: 1)
.animation(.easeIn(duration: 0.3))
}
}
機能の実装:
struct MyView: View {
@State private var test = ""
var body: some View {
VStack {
FloatingLabelTextField(title: "Test", text: $test, keyboardType: nil, contentType: nil)
}
}
}
また...
struct TestData {
var name: String = ""
}
struct ContentView: View {
@State private var test = TestData()
var body: some View {
VStack {
FloatingLabelTextField(title: "Test", text: $test.name, keyboardType: nil, contentType: nil)
}
}
オブジェクトで @State/@Binding を使用する:
class TestData: ObservableObject {
var name: String = ""
}
struct ContentView: View {
@ObservedObject private var test = TestData()
var body: some View {
VStack {
FloatingLabelTextField(title: "Test", text: $test.name, keyboardType: nil, contentType: nil)
}
}