Используйте протокол для определения свойства представления swiftui - PullRequest
0 голосов
/ 03 февраля 2020

У меня есть несколько классов, которые я хочу использовать с представлением выбора бюджета. У всех них определен этот бюджетный протокол.

import SwiftUI

struct BudgetPickerView: View {
    @EnvironmentObject var userData: UserData
    @State var budgetable: Budgetable
    ...
}
import Foundation

protocol Budgetable
{
    var budgetId: String { get set }
}

Например, этот класс распределения

import Foundation
import Combine

class Allocation: ObservableObject, Identifiable, Budgetable {
    let objectWillChange = ObservableObjectPublisher()

    let id: String?
    var amount: String { willSet { self.objectWillChange.send() } }
    var budgetId: String { willSet { self.objectWillChange.send() } }

    init(id: String? = nil, amount: String, budgetId: String) {
        self.id = id
        self.amount = amount.removePrefix("-")
        self.budgetId = budgetId
    }
}

Однако, когда я пытаюсь передать распределение в представление выбора бюджета, я получаю ошибка

NavigationLink(destination: BudgetPickerView(budgetable: allocation))...

Невозможно преобразовать возвращаемое выражение типа 'NavigationLink>, BudgetPickerView>' в возвращаемый тип 'some View'

Тип выражения 'BudgetPickerView' является неоднозначным без дополнительного контекста

Ответы [ 2 ]

0 голосов
/ 03 февраля 2020

Согласно концепции SwiftUI, вам не разрешено работать с @State за пределами View, но следующее работает хорошо (без изменений других ваших частей)

struct BudgetPickerView: View {
    @State private var budgetable: Budgetable

    init(budgetable: Budgetable) {
        _budgetable = State<Budgetable>(initialValue: budgetable)
    }

    var body: some View {
        Text("Hello, World!")
    }
}
struct TestBudgetPickerView: View {
    var body: some View {
        NavigationView {
            NavigationLink(destination: 
               BudgetPickerView(budgetable: Allocation(amount: "10", budgetId: "1"))) 
               { Text("Item") }
        }
    }
}

Кстати, просто добавьте, опять же, дизайн @ Состояние предназначено для хранения данных только для временного просмотра , а не модели. Для модели предпочтительнее использовать ObservableObject. В вашем случае Budgetable выглядит как модель.

0 голосов
/ 03 февраля 2020

Изменить, как показано ниже:

struct BudgetPickerView: View {
   @EnvironmentObject var userData: UserData
   var budgetable: Budgetable
   var body: some View {
   ...
   }
}

и

NavigationLink(destination: BudgetPickerView(budgetable: allocation).EnvironmentObject(UserData()))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...