Как инициализировать значения в SwiftUI перед загрузкой представления? - PullRequest
2 голосов
/ 27 мая 2020

Я хочу взять, скажем, цену акции, а затем сгенерировать значения в пределах 0,05% в 2D-массиве.

Я передаю информацию об акции, такую ​​как название акции и цена акции.

Но когда я пытаюсь запустить метод, который создает двумерный массив значений, я встречаюсь с сообщением «Невозможно использовать член экземпляра» в инициализаторе свойства; инициализаторы свойств запускаются до того, как «self» станет доступным »

Я искал как это обойти.

Скажем, акции Amazon составляют 2400. Эти данные передаются в новое представление. Я хочу создать 2D-массив значений около 2400, возможно, 2405 и 2395. Мне нужен 2D-массив этих значений, сгенерированный в новом представлении. Но я получаю сообщение об ошибке, что я не могу сгенерировать значения, пока представление не будет загружено, но они мне нужны для создания представления.

Я думаю, мне нужно использовать метод init, но я не уверен, как это сделать.

Это строка, которая вызывает ошибку выше.

var new_prices = generateValues(price: position.stock_price)

Вот метод

func generateValues(price: Double) -> [[Double]] {
    var values = [[Double]]()
     for x in 1...5 {
        values[0][x-1] = (price + price * 0.005 * Double(x))
    }
    return values
}

Это то, что передается в стандартной позиции

struct Position : Identifiable {
    var id = UUID()
    var stock_name: String
    var stock_ticker: String
    var stock_price: Double
    var price_paid: Double

}

Переданные аргументы вызывают ошибку при отсутствии аргумента init ().

struct PositionDetail_Previews: PreviewProvider {
    static var previews: some View {
        PositionDetail(position: Position(stock_name: "Amazon", 
stock_ticker: "AMZN", stock_price : 2400, price_paid : 2300))
    }
}

Ответы [ 4 ]

2 голосов
/ 27 мая 2020

Вы можете сделать

struct ContentView: View{
@State var new_prices = [[Double()]]
        init () {
            new_prices = generateValues(price: position.stock_price)
        }
    var body: some View{
           your view...
     }
}
0 голосов
/ 04 июня 2020

Использование вашей модели положения:

struct Position : Identifiable {
    var id = UUID()
    var stock_name: String
    var stock_ticker: String
    var stock_price: Double
    var price_paid: Double

}

Вы можете сгенерировать значения при создании представления, учитывая существующую позицию:

struct StockPriceViewBeforehand: View {
    // MARK: Properties
    var position: Position
    var newPrices: [[Double]]

    // MARK: Body
    var body: some View {
        Text("Use prices here")
    }
}

struct StockPriceViewBeforehand_Previews: PreviewProvider {
    static var previews: some View {
        let amznPosition = Position(stock_name: "Amazon", stock_ticker: "AMZN", stock_price : 2400, price_paid : 2300)        
       return StockPriceViewBeforehand(position: amznPosition, newPrices: StocksValueGenerator.generateValues(price: amznPosition.stock_price))
    }
}


final class StocksValueGenerator {
    static func generateValues(price: Double) -> [[Double]] {
        var values = [[Double]]()
        for x in 1...5 {
            values[0][x-1] = (price + price * 0.005 * Double(x))
        }
        return values
    }
}

Обратите внимание, что я использовал метод generateValues ​​как stati c класса StocksValueGenerator выше, но вы можете использовать ее как sh.

В качестве альтернативы вы можете вызвать метод генерации значений при появлении представления:

struct StockPriceView: View {
    // MARK: Properties
    var position: Position
    @State var values = [[Double]]()

    // MARK: Body
    var body: some View {
        Text("Your view here")
            .onAppear {
                self.values = self.generateValues(price: self.position.stock_price)
            }
    }

    // MARK: Methods
    func generateValues(price: Double) -> [[Double]] {
        var values = [[Double]]()
        for x in 1...5 {
            values[0][x-1] = (price + price * 0.005 * Double(x))
        }
        return values
    }
}

struct StockPriceView_Previews: PreviewProvider {
    static var previews: some View {
        let amznPosition = Position(stock_name: "Amazon", stock_ticker: "AMZN", stock_price : 2400, price_paid : 2300)

        return StockPriceView(position: amznPosition)
    }
}

Разница между этими двумя вариантами состоит в том, что в первом вы должны создать View с уже созданными newPrices, чтобы View могло отображать их соответствующим образом при появлении. Во втором варианте у вас сначала будет пустой массив цен, которому затем будут назначены сгенерированные.

(я знаю, что второй вариант не считается значениями инициализации до представление загружено, но я просто подумал, что дам вам несколько вариантов)

0 голосов
/ 03 июня 2020

Вот как вы вызываете динамические c функции для инициализации текущей версии данных SwiftUI View. (Примечание: не требуется .init ()):

import SwiftUI

struct Position : Identifiable {
    var id = UUID()
    var stock_name: String
    var stock_ticker: String
    var stock_price: Double
    var price_paid: Double
}

struct PositionDetail: View {
    var position: Position

    func generateValues(price: Double) -> [[Double]] {
        var values: [[Double]] = Array(repeating: Array(repeating: 0, count: 5), count: 1)

        for x in 1...5 {
            values[0][x-1] = (price + price * 0.005 * Double(x))
        }

        return values
    }

    var body: some View {
        let values   = generateValues(price: position.stock_price)

        return HStack {
            ForEach(values, id:\.self) { row in
                HStack {
                    ForEach(row, id: \.self) { value in
                        Text("\(value)")
                    }
                }
            }
        }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
    }
}


struct PositionDetail_Previews: PreviewProvider {
    static var previews: some View {
        PositionDetail(position: Position(stock_name: "Amazon", stock_ticker: "AMZN", stock_price : 2400, price_paid : 2300))
    }
}

Примечание: функция generateValues, как указано, не работает ...

0 голосов
/ 29 мая 2020

Если я правильно понял и воспроизвел ваш код изначально, вы получили это

demo

, так что вот решение (протестировано с Xcode 11.4 / iOS 13.4)

func generateValues(price: Double) -> [[Double]] {
    var values = [[Double]]()
    for x in 1...5 {
        values[0][x-1] = (price + price * 0.005 * Double(x))
    }
    return values
}

struct PositionDetail: View {
    var position: Position
    var new_prices: [[Double]]

    init(position: Position) {
        self.position = position
        self.new_prices = generateValues(price: position.stock_price)
    }

    var body: some View {
        VStack { // << just for demo
            Text("Position: \(self.position.stock_name)")
            Text("First price: \(self.new_prices[0][0])")
        }
    }
}

другой код без изменений.

...