首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >错误不能在属性初始化器中使用实例成员'xxx‘

错误不能在属性初始化器中使用实例成员'xxx‘
EN

Stack Overflow用户
提问于 2019-07-24 19:10:28
回答 1查看 4.1K关注 0票数 2

26-07-19

我将在观看WWDC视频时更新我的代码。我的数据模型是:

代码语言:javascript
复制
struct Egg: Identifiable {
    var id = UUID()
    var thumbnailImage: String
    var day: String
    var date: String
    var text: String
    var imageDetail: String
    var weight: Double
}

#if DEBUG
let testData = [

    Egg(thumbnailImage: "Dag-1", day: "1.circle", date: "7 augustus 2019", text: "Kippen leggen iedere dag een ei.", imageDetail: "Day-1", weight: 35.48),

    Egg(thumbnailImage: "Dag-2", day: "2.circle", date: "8 augustus 2019", text: "Kippen leggen iedere dag een ei.", imageDetail: "Day-2", weight: 35.23),

    Egg(thumbnailImage: "Dag-3", day: "3.circle", date: "9 augustus 2019", text: "Kippen leggen iedere dag een ei.", imageDetail: "Day-3", weight: 34.92)

Etc, etc
]

我有一个TabbedView、一个ContentView、一个ContentDetail和一些其他视图(用于设置等)。ContentView的代码是:

代码语言:javascript
复制
struct ContentView : View {
    var eggs : [Egg] = []

    var body: some View {
        NavigationView {
            List(eggs) { egg in
                EggCell(egg: egg)
            }
            .padding(.top, 10.0)
            .navigationBarTitle(Text("Egg management"), displayMode: .inline)
        }
    }
}

#if DEBUG
struct ContentView_Previews : PreviewProvider {
    static var previews: some View {
        ContentView(eggs: testData)
    }
}
#endif

struct EggCell : View {
    let egg: Egg

    var body: some View {

        return NavigationLink(destination: ContentDetail(egg: egg)) {

            ZStack {

                HStack(spacing: 8.0) {

                    Image(egg.thumbnailImage)
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .padding(.leading, -25)
                        .padding(.top, -15)
                        .padding(.bottom, -15)
                        .padding(.trailing, -25)
                        .frame(width: 85, height: 61)

                    VStack {
                        Image(systemName: egg.day)
                            .resizable()
                            .frame(width: 30, height: 22)
                            .padding(.leading, -82)

                        Spacer()
                    }
                    .padding(.leading)

                    VStack {
                        Text(egg.date)
                            .font(.headline)
                            .foregroundColor(Color.gray)
                        Text(egg.weight.clean)
                            .font(.title)

                    }

                }
            }
        }
    }
}

extension Double {
    var clean: String {
        return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(format: "%.2f", self)
    }
}

ContentDetail的代码是:

代码语言:javascript
复制
struct ContentDetail : View {
    let egg: Egg

    @State private var photo = true
    @State private var calculated = false
    @Binding var weight: Double

    var body: some View {

        VStack (alignment: .center, spacing: 10) {

            Text(egg.date)
                .font(.title)
                .fontWeight(.medium)
                .navigationBarTitle(Text(egg.date), displayMode: .inline)

            ZStack (alignment: .topLeading) {

                Image(photo ? egg.imageDetail : egg.thumbnailImage)
                    .resizable()
                    .aspectRatio(contentMode: .fill)
                    .background(Color.black)
                    .padding(.trailing, 0)
                    .tapAction { self.photo.toggle() }

                VStack {

                    HStack {
                        Image(systemName: egg.day)
                            .resizable()
                            .padding(.leading, 10)
                            .padding(.top, 10)
                            .frame(width: 50, height: 36)
                            .foregroundColor(.white)

                        Spacer()

                        Image(systemName: photo ?  "photo" : "wand.and.stars")
                            .resizable()
                            .padding(.trailing, 10)
                            .padding(.top, 10)
                            .frame(width: 50, height: 36)
                            .foregroundColor(.white)

                    }

                    Spacer()

                    HStack {
                        Image(systemName: "arrow.left.circle")
                            .resizable()
                            .padding(.leading, 10)
                            .padding(.bottom, 10)
                            .frame(width: 50, height: 50)
                            .foregroundColor(.white)

                        Spacer()

                        Image(systemName: "arrow.right.circle")
                            .resizable()
                            .padding(.trailing, 10)
                            .padding(.bottom, 10)
                            .frame(width: 50, height: 50)
                            .foregroundColor(.white)

                    }
                }
            }

            Text("the weight is: \(egg.weight) gram")
                .font(.headline)
                .fontWeight(.bold)

            ZStack {

                RoundedRectangle(cornerRadius: 10)
                    .padding(.top, 45)
                    .padding(.bottom, 45)
                    .border(Color.gray, width: 5)
                    .opacity(0.1)

                HStack {

                    Spacer()

                    DigitPicker(digitName: "tens", digit: $weight.tens)
                    DigitPicker(digitName: "ones", digit: $weight.ones)

                    Text(".")
                        .font(.largeTitle)
                        .fontWeight(.black)
                        .padding(.bottom, 10)

                    DigitPicker(digitName: "tenths", digit: $weight.tenths)
                    DigitPicker(digitName: "hundredths", digit: $weight.hundredths)

                    Spacer()

                    }
                }

            Toggle(isOn: $calculated) {
                Text(calculated ? "This weight is calculated." : "This weight is measured.")
            }

            Text(egg.text)
                .lineLimit(2)
                .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
                .padding(.leading, 6)

            Spacer()

        }
        .padding(6)

    }
}

#if DEBUG
struct ContentDetail_Previews : PreviewProvider {
    static var previews: some View {
        NavigationView { ContentDetail(egg: testData[0]) }
    }
}
#endif


struct DigitPicker: View {
    var digitName: String
    @Binding var digit: Int

    var body: some View {
        VStack {
            Picker(selection: $digit, label: Text(digitName)) {
                ForEach(0 ... 9) {
                    Text("\($0)").tag($0)
                }
            }.frame(width: 60, height: 110).clipped()
        }
    }
}

fileprivate extension Double {
    var tens: Int {
        get { sigFigs / 1000 }
        set { replace(tens: newValue)  }
    }

    var ones: Int {
        get { (sigFigs / 100) % 10 }
        set { replace(ones: newValue) }
    }

    var tenths: Int {
        get { (sigFigs / 10) % 10 }
        set { replace(tenths: newValue) }
    }

    var hundredths: Int {
        get { sigFigs % 10 }
        set { replace(hundredths: newValue) }
    }

    private mutating func replace(tens: Int? = nil, ones: Int? = nil, tenths: Int? = nil, hundredths: Int? = nil) {
        self = Double(0
            + 1000 * (tens ?? self.tens)
            + 100 * (ones ?? self.ones)
            + 10 * (tenths ?? self.tenths)
            + (hundredths ?? self.hundredths)) / 100.0
    }

    private var sigFigs: Int {
        return Int((self * 100).rounded(.toNearestOrEven))
    }
}

我仍然收到的编译器错误是:

  1. 在ContentView中,NavigationLink下面:在调用中缺少参数‘权重’的参数参数
  2. 在ContentDetail中,at NavigationView:在调用中缺少参数‘权重’的参数参数
  3. 在ContentDetail中,在#endif之后:在调用中缺少参数‘权重’的参数参数

25-07-19

下面的代码是列表详细视图的一部分。变量‘权重’是通过'NavigationLink‘语句从列表中得到的。在这段代码中,我声明它为'35.48',但是NavigationLink填充了它的实际值。

我想用compactMap语句创建一个数组3、5、4、8。在游乐场还行。这些值分配给4个不同的选择器(在一个HStack中)。

代码语言:javascript
复制
import SwiftUI
import Foundation

    struct ContentDetail : View {

        var weight : Double = 35.48
        var weightArray = "\(weight)".compactMap { Int("\($0)") }

        @State var digit1 = weightArray[0] // error
        @State var digit2 = weightArray[1] // error
        @State var digit3 = weightArray[2] // error
        @State var digit4 = weightArray[3] // error

        var body: some View {

            VStack (alignment: .center, spacing: 10) {

                Text(weight)
                    .font(.title)
                    .fontWeight(.medium)

    etc etc

我得到一个错误:不能在属性初始化器中使用实例成员'weightArray‘;属性初始化器在“self”可用之前运行。

如果我使用以下代码,它可以正常工作(对于第一个list元素):

代码语言:javascript
复制
import SwiftUI
import Foundation

    struct ContentDetail : View {

        var weight : Double = 35.48
        var weightArray = [3, 5, 4, 8]

        @State var digit1 = 3
        @State var digit2 = 5
        @State var digit3 = 4
        @State var digit4 = 8

        var body: some View {

            VStack (alignment: .center, spacing: 10) {

                Text(weight)
                    .font(.title)
                    .fontWeight(.medium)

    etc etc

正确的SwiftUI方法是什么?为什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-07-24 20:09:30

实际上,属性初始化程序不能引用同一容器中的另一个属性。您必须在init中初始化属性。

代码语言:javascript
复制
struct ContentDetail: View {

    var weight: Double
    var weightArray: [Int]

    @State var digit1: Int
    @State var digit2: Int
    @State var digit3: Int
    @State var digit4: Int

    init(weight: Double) {
        self.weight = weight
        weightArray = "\(weight)".compactMap { Int("\($0)") }
        _digit1 = .init(initialValue: weightArray[0])
        _digit2 = .init(initialValue: weightArray[1])
        _digit3 = .init(initialValue: weightArray[2])
        _digit4 = .init(initialValue: weightArray[3])
    }

但是我怀疑你是因为你想让用户单独编辑数字而打破数字的,如下所示:

如果这是您想要的,那么您不应该对每个数字都有一个单独的@State属性。相反,weight应该是一个@Binding,它应该对每个数字都有一个单独的可变属性。

首先,扩展Double以允许您访问以下数字:

代码语言:javascript
复制
fileprivate extension Double {
    var tens: Int {
        get { sigFigs / 1000 }
        set { replace(tens: newValue)  }
    }

    var ones: Int {
        get { (sigFigs / 100) % 10 }
        set { replace(ones: newValue) }
    }

    var tenths: Int {
        get { (sigFigs / 10) % 10 }
        set { replace(tenths: newValue) }
    }

    var hundredths: Int {
        get { sigFigs % 10 }
        set { replace(hundredths: newValue) }
    }

    private mutating func replace(tens: Int? = nil, ones: Int? = nil, tenths: Int? = nil, hundredths: Int? = nil) {
        self = Double(0
            + 1000 * (tens ?? self.tens)
            + 100 * (ones ?? self.ones)
            + 10 * (tenths ?? self.tenths)
            + (hundredths ?? self.hundredths)) / 100.0
    }

    private var sigFigs: Int {
        return Int((self * 100).rounded(.toNearestOrEven))
    }
}

然后,将ContentDetailweight属性更改为@Binding,并去掉其他属性:

代码语言:javascript
复制
struct ContentDetail: View {
    @Binding var weight: Double

    var body: some View {
        HStack {
            DigitPicker(digitName: "tens", digit: $weight.tens)
            DigitPicker(digitName: "ones", digit: $weight.ones)
            DigitPicker(digitName: "tenths", digit: $weight.tenths)
            DigitPicker(digitName: "hundredths", digit: $weight.hundredths)
        }
    }
}

struct DigitPicker: View {
    var digitName: String
    @Binding var digit: Int

    var body: some View {
        VStack {
            Picker(selection: $digit, label: Text(digitName)) {
                ForEach(0 ... 9) {
                    Text("\($0)").tag($0)
                }
            }.frame(width: 60, height: 110).clipped()
        }
    }
}

下面是在操场上测试这一点所需的其余代码,这就是我上面生成该映像的方式:

代码语言:javascript
复制
import PlaygroundSupport

struct TestView: View {
    @State var weight: Double = 35.48

    var body: some View {
        VStack(spacing: 0) {
            Text("Weight: \(weight)")
            ContentDetail(weight: $weight)
                .padding()
        }
    }
}

let host = UIHostingController(rootView: TestView())
host.preferredContentSize = .init(width: 320, height: 240)
PlaygroundPage.current.liveView = host
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57189740

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档