SwiftUI View и Swift Package Manager

Я пытаюсь создать пакет Swift, который в основном представляет собой одно представление SwiftUI. Я создал здесь образец, чтобы показать, что происходит. Что делает пакет, не имеет значения, я только что включил некоторые переменные @State и @Binding в представление, чтобы получить ту же ошибку, что и в моем реальном пакете. Структура представления - это.

import SwiftUI

public struct SampleView: View {
    @Binding var myNum:Int
    @State var fixedText:String = ""
    var myText = ""
    var optional: String?


   public  var body: some View {
        VStack {
            if optional != nil {
                Text(optional!)
            }
            Text(myText)
            Text("Parent number: \(myNum)")
            Text("\(fixedText)")
            Button("Increment num") {
                self.myNum += 1
            }.foregroundColor(.blue)
            Button("Change Parent Text") {
                self.fixedText = "Only Changes Child"
            }.foregroundColor(.blue)
        }.background(Color.red)
            .foregroundColor(.white)
    }
}

Когда я добавляю пакет и импортирую его в одно из представлений в моем проекте, я должен иметь возможность использовать что-то вроде этого, как я могу сделать, если представление не является частью пакета Swift:

 SampleView(myNum: $myNum,
             fixedText: parentText,
             myText: "Display Text Passed from parent")

Однако я не получаю завершения кода и получаю сообщение об ошибке:

'SampleView' initializer is inaccessible due to 'internal' protection level

Я пробовал всевозможные инициализации структуры SampeView, но продолжаю получать всевозможные ошибки. Я просто не понимаю, как здесь поправить уровни доступа. Кто-нибудь может помочь? Скриншот тоже есть здесь. введите здесь описание изображения


person Stewart Lynch    schedule 08.01.2020    source источник


Ответы (1)


Вот ожидаемое объявление в пакете (протестировано с Xcode 11.2.1 / iOS 13.2.2). Обратите внимание, что @State нельзя использовать вне View, поэтому все, что вам нужно сделать для синхронизации, следует передать через Binding:

public struct SampleView: View {
    @Binding var myNum:Int
    @Binding var fixedText:String
    var myText: String
    var optional: String?

    public init(myNum: Binding<Int>, fixedText: Binding<String>, 
                myText: String = "", optional: String? = nil) {
        self._myNum = myNum
        self._fixedText = fixedText
        self.myText = myText
        self.optional = optional
    }

    public var body: some View {
        VStack {
            if optional != nil {
                Text(optional!)
            }
            Text(myText)
            Text("Parent number: \(myNum)")
            Text("\(fixedText)")
            Button("Increment num") {
                self.myNum += 1
            }.foregroundColor(.blue)
            Button("Change Parent Text") {
                self.fixedText = "Only Changes Child"
            }.foregroundColor(.blue)
        }.background(Color.red)
            .foregroundColor(.white)
    }
}

и использование:

@State private var myNum: Int = 1
@State private var parentText = "Test"
var body: some View {
    SampleView(myNum: $myNum,
               fixedText: $parentText,
               myText: "Display Text Passed from parent")
}
person Asperi    schedule 08.01.2020
comment
Спасибо, помогло. Но как заставить работать превью компонентов пользовательского интерфейса, если они находятся в отдельном пакете? - person Vegi Woo; 18.03.2021