Инициирование SwiftUI View с необязательным свойством @Binding кажется неоднозначным - PullRequest
0 голосов
/ 03 октября 2019

Учитывая мои предположения, из кода ниже, что:

  • $a возвращает Binding<Bool>
  • Binding.constant(a: self.a) также возвращает Binding<Bool>

тогда почему B(a: Binding<Bool?>) отклоняет (правильно) первое с "Cannot convert value of type 'Binding<Bool>' to expected argument type 'Binding<Bool?>'", но принимает второе?

import SwiftUI

struct ContentView: View {
    @State var a: Bool = false

    var body: some View {
        A(a: $a)
    }
}

struct A : View {
    @Binding var a: Bool

    var body: some View {
            //B(a: $a)
            // ^~~~ 
            // Fails with "Cannot convert value of type 'Binding<Bool>' to expected argument type 'Binding<Bool?>'"       
            B(a: Binding.constant(self.a))
    }
}

struct B : View {
    @Binding var a: Bool?

    var body: some View {

        if a == nil {
            return Text("a is nil")
        } else {
            return Text("a is \(a! ? "true" : "false")")
        }
    }
}

1 Ответ

1 голос
/ 03 октября 2019

Что вы ожидаете от содержимого необязательного Bool, хранящегося в A.a, если кто-то установит производное необязательное связывание Bool в B.b в nil? Ваш способ обернуть Bool в .constant работает, потому что он предотвращает эту возможность (поскольку постоянная привязка не может быть изменена).

В качестве альтернативы вы можете создать производную привязку, которая просто игнорирует установку значений nil, например, так (обратите внимание на недокументированный префикс "_" для назначения значения оболочки основного свойства):

extension B {
    init(reqA: Binding<Bool>) {
        self._a = Binding<Bool?>(get: { reqA.wrappedValue },
          set: { if let newValue = $0 { reqA.wrappedValue = newValue } })
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...