Неизменные некоторые переменные тела представления / непрозрачный возврат в View - PullRequest
0 голосов
/ 06 июня 2019

В Swift 5.1 есть непрозрачные типы. Я вижу это, например body является обязательной переменной протокола. Это контракт определяется следующим образом:

var body: Self.Body { get }

Это означает, что мы должны пометить тело как неизменное (нет set). Как это должно быть сделано? Возможно ли, чтобы непрозрачные типы переменных были неизменными? Я попробовал:

import SwiftUI

struct ContentView : View {

    init() {
        body = AnotherView(body: Text(""))
    }

    let body: some View
}

struct AnotherView: View {
    var body: Text
}

Но я получаю ошибку, что AnotherView должно быть приведено к some View. После этого я получаю сообщение об ошибке:

некоторые типы реализованы только для объявленного типа свойств. и индексы и возвращаемый тип функций

Могу ли я соответствовать View с неизменяемыми body переменными типа some View (не помечая его как AnotherView)? AnotherView - это some View, я не понимаю, почему я не могу просто присвоить экземпляр AnotherView body. Я хочу оставаться гибким и не раскрывать фактический тип реализации тела вне структуры, но я хочу инициализировать его непосредственно внутри инициализатора (потому что я передаю значения внутри инициализатора, создаю дополнительные свойства и использую их в свойстве тела. многословный).

1 Ответ

0 голосов
/ 06 июня 2019

Поскольку нет установщика, любая реализация body, являющаяся типом значения, будет неизменной.var просто означает, что body оценивается лениво, а не изменчиво.Вы могли бы объявить let body, но, как вы указали, это раскрывает базовую реализацию View:

public struct StaticTextView : View {
    public let body: Text

    public init(string: String) {
        self.body = Text(string)
    }
}

Один из способов исправить это - это иметьbody просто возвращает внутреннее приватное значение, например так:

public struct StaticTextView : View {
    private let textView: Text
    public var body: some View { textView }

    public init(string: String) {
        self.textView = Text(string)
    }
}

Однако вы должны иметь в виду, что body предназначен для динамического запуска всякий раз, когда изменяется любое из связанных состояний, и если выЕсли вы хотите присвоить ваше представление константе, ничто в иерархии этого представления не может быть привязано к какому-либо динамическому состоянию.Например, это было бы невозможно:

struct DynamicStepperView : View {
    @State var stepperValue = 1

    var body: some View {
        Stepper(value: $stepperValue, in: 1...11, label: { Text("Current Value: \(stepperValue)") })
    }
}

Если ваша главная задача - предотвратить утечку деталей реализации вашей иерархии представлений, обратите внимание, что непрозрачный тип возврата some View действительно непрозрачен для любых клиентов.кода, и они не смогут увидеть какие-либо подробности базовой реализации, кроме того, что это некоторая вещь, которая соответствует протоколу View.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...