5

我一直在尝试使用 Swift UI 为 iOS 13 制作应用程序,但我不断收到这个奇怪的错误:“对成员 'buildBlock()' 的模糊引用”。

无论我做什么,错误都不会消失。

我尝试一次注释代码部分,以查看可能导致问题的部分,但唯一有效的是注释掉整个视图。

我已经尝试清理我的构建文件夹并删除派生数据。我还尝试多次重新启动计算机和 Xcode,但没有任何修复。

我很确定这只是一个 Xcode 错误,但一定有它周围的地方,如果有人能告诉我那是什么,我将不胜感激。

var body: some View {
    GeometryReader { geometry in {
        VStack {
            Button (action: self.editProfilePicture) {
                    Image(ImageNames.AccountIconImageName, bundle: Bundle.main)
                        .resizable()
                        .frame(width: geometry.size.width / SizeConstants.AccountIconSizeDiviser, height: geometry.size.width / SizeConstants.AccountIconSizeDiviser)
                        .padding()
                        .background(ColorConstants.VeryLightGrayColor)
                        .clipShape(Circle())
                }
                .accentColor(.white)
                .padding(.bottom, LargePadding)

                ScrollView (showsVerticalIndicator: false) {

                    let const: Length? = geometry.size.width - SizeConstants.FullNameTextFieldWidthReduction

                    TextBox(textBinding: self.$fullName, placeHolder: Text(Strings.FullNameString), editChanged: self.fullNameChanged)/*.padding(.bottom, SmallPadding)*/.frame(width: const)
                    TextBox(textBinding: self.$username, placeHolder: Text(Strings.UsernameString), editChanged: self.usernameChanged)//.padding(.bottom)

                    Text(verbatim: Strings.ChooseIdType).font(.footnote).color(.gray)

                    TextBox(textBinding: self.$phoneNumber, placeHolder: Text(Strings.PhoneNumberString), editChanged: self.phoneNumberChanged)//.padding(.bottom, SmallPadding)
                    TextBox(textBinding: self.$emailAddress, placeHolder: Text(Strings.EmailAddressString), editChanged: self.emailAddressChanged)//.padding(.bottom)

                    Spacer(minLength: PaddingConstants.FirstSignupSpacerMinSize)

                    TextBox(textBinding: self.$password, placeHolder: Text(Strings.PasswordFieldPlaceHolder), editChanged: self.signupPasswordChanged)//.padding(.bottom, SmallPadding)
                    TextBox(textBinding: self.$confirmPassword, placeHolder: Text(Strings.ConfirmPasswordString), editChanged: self.confirmPasswordChanged)//.padding(.bottom)

                    Spacer(minLength: PaddingConstants.SecondSignupSpacerMinSize)

                    Button (action: self.signup) {
                        Text(Strings.CreateAccountString).color(.white).font(Font.system(size: SizeConstants.LoginButtonFontSize))
                    }
                    .padding(EdgeInsets(top: PaddingConstants.CreatAccountButtonVerticalPadding,
                                        leading: PaddingConstants.CreateAccountButtonSidePadding,
                                        bottom: PaddingConstants.CreatAccountButtonVerticalPadding,
                                        trailing: PaddingConstants.CreateAccountButtonSidePadding))
                    .background(LeznoBlue)
                    .clipShape(RoundedRectangle(cornerRadius: SmallCornerRadius))

                    Spacer(minLength: PaddingConstants.ThirdSignupSpacerMinSize)

                    Text(Strings.AgreementString)

                    HStack {
                        Button (action: {}) {
                            Text(Strings.TermsString)
                        }
                        Text(Strings.AndString)
                        Button (action: {}) {
                            Text(Strings.PrivacyString)
                        }
                    }

                }
        }
        .padding()
    }
}

错误截图

编辑:

事实证明,我忘记了在视图构建器闭包中最多只能有 10 个视图,而我拥有的不止这些。只需将它们分组以减少查看次数即可解决该错误。

事实证明,Xcode 显示的错误非常具有误导性。

感谢 Hamish 指出

4

1 回答 1

8

As @Hamish originally mentioned in comments, ViewBuilder's can not exceeding over 10 subview limit! So you should group items in smaller pieces and try to add them group by group.

So instead of something like this: (This is a working example based on your original code, not exactly the same)

struct ContentView : View {

    @State var firstName: String = ""
    @State var lastName: String = ""

    @State var phoneNumber: String = ""
    @State var emailAddress: String = ""

    @State var password: String = ""
    @State var confirmPassword: String = ""

    var body: some View {

        ScrollView (showsVerticalIndicator: false) {

            TextField($firstName, placeholder: Text("First Name"))
            TextField($lastName, placeholder: Text("Last Name"))

            Spacer()

            TextField($phoneNumber, placeholder: Text("Phone Number"))
            TextField($emailAddress, placeholder: Text("Email Address"))

            Spacer()

            TextField($password, placeholder: Text("Password"))
            TextField($confirmPassword, placeholder: Text("Confirm Password"))

            // ...

        }
        .padding()
    }

}

Consider breaking it into meaningful smaller groups like this:

struct NameSectionView : View {

    @State var firstName: String
    @State var lastName: String

    var body: some View {
        Group {
            TextField($firstName, placeholder: Text("First Name"))
            TextField($lastName, placeholder: Text("Last Name"))
        }
    }

}

struct ContactSectionView : View {

    @State var phoneNumber: String
    @State var emailAddress: String

    var body: some View {
        Group {
            TextField($phoneNumber, placeholder: Text("Phone Number"))
            TextField($emailAddress, placeholder: Text("Email Address"))
        }
    }

}

struct PasswordSectionView : View {

    @State var password: String
    @State var confirmPassword: String

    var body: some View {
        Group {
            TextField($password, placeholder: Text("Password"))
            TextField($confirmPassword, placeholder: Text("Confirm Password"))
        }
    }

}

and use them like this:

struct ContentView : View {

    @State var firstName: String = ""
    @State var lastName: String = ""

    @State var phoneNumber: String = ""
    @State var emailAddress: String = ""

    @State var password: String = ""
    @State var confirmPassword: String = ""

    var body: some View {

        ScrollView (showsVerticalIndicator: false) {

            NameSectionView(firstName: firstName, lastName: lastName)

            Spacer()

            ContactSectionView(phoneNumber: phoneNumber, emailAddress: emailAddress)

            Spacer()

            PasswordSectionView(password: password, confirmPassword: confirmPassword)

            // ...

        }
        .padding()
    }

}

Also this is more reusable if you ever want to use any of these somewhere else.

于 2019-06-19T11:30:28.887 回答