swiftswiftuicombineswiftui-view

Why does SwiftUI throw an "Extra argument in call" error when I add more than 10 views?


I seem to be getting a random "Extra argument in call." error while coding a tip calculator. Here is my SwiftUI File:

import SwiftUI

internal enum ReceiptRowType {
    case subtotal
    case tax
    case total
    case tip
    case grandTotal
}

struct TipView: View {
    @ObservedObject internal var adBannerView: BannerAdView = BannerAdView()
    @ObservedObject internal var receiptViewModel: ReceiptViewModel
    
    private let percentageFormatter: NumberFormatter = {
        let f = NumberFormatter()
        f.numberStyle = .percent
        return f
    }()
    
    var body: some View {
        ZStack {
            Color.white
                .scaledToFit()
            
            VStack {
                if adBannerView.adHasLoaded {
                    adBannerView
                        .frame(maxHeight: adBannerView.adHeight)
                        .animation(.easeInOut(duration: 2.0))
                }

                BorderView()
                
                Text(ARCHLocalizedStrings.receipt)
                    .foregroundColor(Color.gray)
                
                BorderView()
                
                HStack {
                    Spacer()
                    
                    Button(action: {
                        self.receiptViewModel.addNewReceiptItem()
                    }) {
                        Text(ARCHLocalizedStrings.buttonTitleAddItem)
                    }
                }
                
                BorderView()
        
                ScrollView {
                    ForEach(receiptViewModel.receiptItems) { receiptItem in
                        ItemView(receiptItem: receiptItem)
                        
                        if receiptItem != self.receiptViewModel.receiptItems.last {
                            Divider()
                        }
                    }
                }
                
                BorderView()
                
                BottomOfReceiptRow(receiptViewModel: receiptViewModel,
                                   type: ReceiptRowType.subtotal,
                                   title: ARCHLocalizedStrings.subtotal)
                
                BottomOfReceiptRow(receiptViewModel: receiptViewModel,
                                   type: ReceiptRowType.tax,
                                   title: ARCHLocalizedStrings.tax)
            }
            .padding(.horizontal, ARCHSwiftUILayoutConstants.defaultPaddingAndSpacing)
        }
    }
}

struct BorderView: View {
    var body: some View {
        Text("================================")
            .lineLimit(1)
            .foregroundColor(Color.gray)
            .minimumScaleFactor(0.5)
    }
}

struct ItemView: View {
    @ObservedObject var receiptItem: ReceiptItemViewModel
        
    var body: some View {
        HStack {
            TextField(receiptItem.name, text: $receiptItem.name)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .foregroundColor(Color.gray)
                .multilineTextAlignment(TextAlignment.leading)

            TextField("Price", value: $receiptItem.price, formatter: ARCHUtilities.currencyFormatter)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .foregroundColor(Color.gray)
                .multilineTextAlignment(TextAlignment.trailing)
                .minimumScaleFactor(0.5)
                .frame(width: ARCHSwiftUILayoutConstants.widthForCurrency)
        }
    }
}

struct BottomOfReceiptRow: View {
    @ObservedObject internal var receiptViewModel: ReceiptViewModel
    
    internal var type: ReceiptRowType
    internal var title: String
    
    var body: some View {
        HStack {
            Spacer()
            
            Text(title)
                .foregroundColor(Color.gray)
            
            if type == ReceiptRowType.subtotal {
                Text("\(receiptViewModel.subtotal)")
                    .foregroundColor(Color.gray)
                    .frame(width: ARCHSwiftUILayoutConstants.widthForCurrency)
            } else if type == ReceiptRowType.tax {
                Text("\(receiptViewModel.taxRate)")
                    .foregroundColor(Color.gray)
                    .frame(width: ARCHSwiftUILayoutConstants.widthForCurrency)
            } else if type == ReceiptRowType.total {
                Text("\(receiptViewModel.total)")
                    .foregroundColor(Color.gray)
                    .frame(width: ARCHSwiftUILayoutConstants.widthForCurrency)
            } else if type == ReceiptRowType.tip {
                
            } else if type == ReceiptRowType.grandTotal {
                Text("\(receiptViewModel.grandTotal)")
                    .foregroundColor(Color.gray)
                    .frame(width: ARCHSwiftUILayoutConstants.widthForCurrency)
            }
        }
    }
}

struct TipView_Previews: PreviewProvider {
    static var previews: some View {
        TipView(receiptViewModel: ReceiptViewModel())
    }
}

However, if I add another view on the TipView body (any view), I seem to get a "Extra argument in call" error:

Picture of error here

Does anyone know what's going on?


Solution

  • Try making a Group { } around your views. Just 10 views are allowed in Swift UI, but with groups you can add more. Or use subviews (which would be cleaner code, too).