UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SOLVED: Project 7: iExpense, Error

Forums > 100 Days of SwiftUI

Is anyone else getting an error for the TextField .keyboardType(.decimalPad)? I keep getting 2 errors: Cannot infer contextual base in reference to member 'numberPad' Value of type 'TextField<Text>' has no member 'keyboardType'

which I think is weird because I'm pretty sure that Text field does have keyboardTypes as an imput type.

`import SwiftUI

struct AddView: View { @State private var name = "" @State private var type = "Personal" @State private var amount = 0.0

let types = ["Buisness", "Personal"]
var body: some View {
    NavigationView{
        Form {
            TextField("Name", text: $name)

            Picker("Type", selection: $type){
            ForEach(types, id:\.self){
                Text($0)
            }
        }
        TextField("Amount", value: $amount, format: .currency(code: "USD"))
            .keyboardType(.decimalPad)
    }
    .navigationTitle("Add New Expense")
}

} } struct AddView_Previews: PreviewProvider { static var previews: some View { AddView() } }`

2      

I copied and paste your code and it compiled and ran correctly with no errors.

import SwiftUI

struct AddView: View {
    @State private var name = ""
    @State private var type = "Personal"
    @State private var amount = 0.0

    let types = ["Buisness", "Personal"]

    var body: some View {
        NavigationView{
            Form {
                TextField("Name", text: $name)

                Picker("Type", selection: $type){
                    ForEach(types, id:\.self){
                        Text($0)
                    }
                }
                TextField("Amount", value: $amount, format: .currency(code: "USD"))
                    .keyboardType(.decimalPad)
            }
            .navigationTitle("Add New Expense")
        }
    }
}

struct AddView_Previews: PreviewProvider {
    static var previews: some View {
        AddView()
    }
}

2      

Other errors: I am also getting an error in the Picker aftert Text($0): Cannot infer contextual base in reference to member 'numberPad' and after @ObservedObject var expense = Expenses: Type 'Expenses.Type' cannot conform to 'ObservableObject'

import SwiftUI

@available(macOS 12.0, *)
struct AddView: View {
    @ObservedObject var expense = Expenses
    @Environment(\.dismiss) var dismiss

    @State private var name = ""
    @State private var type = "Personal"
    @State private var amount = 0.0

    let types = ["Buisness", "Personal"]
    var body: some View {
        NavigationView{
            Form {
                TextField("Name", text: $name)

                Picker("Type", selection: $type){
                ForEach(types, id:\.self){
                    Text($0)
                }
            }
            TextField("Amount", value: $amount, format: .currency(code: "USD"))
                .keyboardType(.decimalPad)
        }
        .navigationTitle("Add New Expense")
        .toolbar {
            Button("Save") {
                let item = ExpenseItem(name: name, type: type, amount: amount)
                expenses.items.append(item)
                dismiss()
            }
        }
    }
}
}
struct AddView_Previews: PreviewProvider {
    static var previews: some View {
        AddView(expenses: Expenses())
    }
}

2      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

try

@ObservedObject var expenses: Expenses

instead of

@ObservedObject var expense = Expenses

You're not creating a new instance, you're refering to the one you already created in ContentView and if you were creating a new instance of Expenses you would need Expenses()

plus, these two don't match:

@ObservedObject var expense = Expenses

AddView(expenses: Expenses())

you have expense up at top and expenses in the previews

Using:

@ObservedObject var expenses: Expenses

should fix that.

2      

I don't understand why it would compile for you but not for me. I am running Xcode Version 13.3 (13E113). Are you running an older version? and my code is not compatible with the newer version?

Also, I changed "@ObservedObject var expense: Expenses" to "@ObservedObject var expenses: Expenses", but I'm still getting the same error.

2      

Here's my old one I pulled from backup with your modified AddView added. Xcode 13.3 13E113, complies and runs. You should be able to create a new test app, copy and paste all the code below over the ContentView content and be able to build and run it. If you've verified that works then you can compare your original one with this version.

import SwiftUI

struct ContentView: View {
    @StateObject var expenses = Expenses()
    @State private var showingAddExpense = false
    var body: some View {
        NavigationView {
            List {
                ForEach(expenses.items) { item in
                    HStack {
                        VStack(alignment: .leading) {
                            Text(item.name)
                                .font(.headline)
                            Text(item.type)
                        }
                        Spacer()
                        Text(item.amount, format: .currency(code: "USD"))
                    }
                }
                .onDelete(perform: removeItems)
            }
            .navigationTitle("iExpense")
            .toolbar {
                Button {
                    showingAddExpense = true
                } label: {
                    Image(systemName: "plus")
                }
            }
            .sheet(isPresented: $showingAddExpense) {
                AddView(expenses: expenses)
            }

        }

    }
    func removeItems(at offsets: IndexSet) {
        expenses.items.remove(atOffsets: offsets)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
import SwiftUI

@available(macOS 12.0, *)
struct AddView: View {
    @ObservedObject var expenses: Expenses
    @Environment(\.dismiss) var dismiss

    @State private var name = ""
    @State private var type = "Personal"
    @State private var amount = 0.0

    let types = ["Buisness", "Personal"]
    var body: some View {
        NavigationView{
            Form {
                TextField("Name", text: $name)

                Picker("Type", selection: $type){
                ForEach(types, id:\.self){
                    Text($0)
                }
            }
            TextField("Amount", value: $amount, format: .currency(code: "USD"))
                .keyboardType(.decimalPad)
        }
        .navigationTitle("Add New Expense")
        .toolbar {
            Button("Save") {
                let item = ExpenseItem(name: name, type: type, amount: amount)
                expenses.items.append(item)
                dismiss()
            }
        }
    }
}
}
struct AddView_Previews: PreviewProvider {
    static var previews: some View {
        AddView(expenses: Expenses())
    }
}
import Foundation

struct ExpenseItem: Identifiable, Codable {
    var id = UUID()
    let name: String
    let type: String
    let amount: Double
}
import Foundation

class Expenses: ObservableObject {
    @Published var items = [ExpenseItem]() {
        didSet {
            if let encoded = try? JSONEncoder().encode(items) {
                UserDefaults.standard.set(encoded, forKey: "Items")
            }
        }
    }
    init() {
        if let savedItems = UserDefaults.standard.data(forKey: "Items") {
            if let decodedItems = try? JSONDecoder().decode([ExpenseItem].self, from: savedItems) {
                items = decodedItems
                return
            }
        }
        items = []
    }
}

2      

=..( So frustrating. I copied all of the code that you gave into my Xcode, (after getting 3 errors to add "if #available(macOS 12.0, ) { AddView(expenses: Expenses()) } else {" and adding those) but it's still giving me the error "Cannot infer contextual base in reference to member 'numberPad' " and "Value of type 'TextField<Text>' has no member 'keyboardType' " in the Amount TextField. I don't know what to do when it works for others but not in mine.

2      

The only other thing I can think to suggest is to start a new app from scratch and slowly rebuild the code a little bit at a time. Do a CMD+B frequently to make sure it's building as you go. If it fails to build at some point then undo whatever changes you made and build again to see if you can figure out what's causing the problem.

2      

I agree with Vince. Start from scratch. Also, I went throught the 100 Days tutorials always with iOS in mind. There may be some shennanigans going on with your code and certain Targets? Not sure I know how this magic works.

This next part may be nonsense.

But if you're adding code like @available(macOS 12.0, *) to your logic, and compilling a MacOS app but trying to run in an iOS simulator, not sure if this would result in some of the errors you're seeing.

2      

I just realized that there is an option when creating a new project to change what platform you are coding for. And there is a way to change from macOS to iOS at the top of the window. Looks like that fixed it. Thanks!!

2      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.