Ich entwickle eine App in Swift und ich habe ein Problem mit benutzerdefinierten Zellen. Ich habe eine benutzerdefinierte Zelle und wenn Sie auf Hinzufügen klicken, wird eine weitere benutzerdefinierte Zelle erstellt. Zelle hat 3 Textfelder und 2 Knöpfe. Diese Textfelder sind Name, Preis und Menge des Inhaltsstoffes der Mahlzeit, die ich erstelle. Wenn ich nur eine benutzerdefinierte Zelle verwende oder eine weitere Zelle hinzufüge, werden die Daten ordnungsgemäß gespeichert. Aber wenn ich 2 benutzerdefinierte Zelle (3 benutzerdefinierte Zellen insgesamt) hinzufügen, habe ich das Problem des falschen Preises, nur die letzten beiden Zutaten werden im Preis berechnet. Wenn ich 3 benutzerdefinierte Zellen (insgesamt 4 benutzerdefinierte Zellen) hinzufüge, erstellt es nur die erste Zelle mit aufgefüllten Daten wie in der ersten Zelle. Am Ende Knopf tippen, bekomme ich einen fatalen Fehler: Fand Null beim Entpacken Optionaler Wert.iOS Entwicklung Schnelle benutzerdefinierte Zellen
View Controller
import UIKit
import CoreData
class AddMealViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {
@IBOutlet weak var mealNameTF: UITextField!
@IBOutlet weak var addMealsCell: UITableViewCell!
@IBOutlet weak var finishButton: UIButton!
@IBOutlet weak var resetButton: UIButton!
@IBOutlet weak var addButton: UIButton!
@IBOutlet weak var addMealTableView: UITableView!
@IBOutlet weak var productPrice: UILabel!
let currency = "$" // this should be determined from settings
var priceTotal = "0"
override func viewDidLoad() {
super.viewDidLoad()
addMealTableView.delegate = self
addMealTableView.dataSource = self
borderToTextfield(textField: mealNameTF)
mealNameTF.delegate = self
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
self.view.endEditing(true)
return true;
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return counter
}
var counter = 1
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return counter
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier:
"addMealsCell", for: indexPath) as! AddMealsTableViewCell
borderToTextfield(textField: (cell.amountTF)!)
borderToTextfield(textField: (cell.ingredientNameTF)!)
//borderToTextfield(textField: cell.normativeTF)
borderToTextfield(textField: (cell.priceTF)!)
return cell
}
@IBAction func addButton(_ sender: UIButton) {
counter += 1
addMealTableView.register(AddMealsTableViewCell.self, forCellReuseIdentifier: "addMealsCell")
addMealTableView.reloadData()
}
@IBAction func resetButton(_ sender: UIButton) {
mealNameTF.text = ""
for c in 0..<counter{
let indexPath = IndexPath(row: c, section:0)
let cell = addMealTableView.cellForRow(at: indexPath) as! AddMealsTableViewCell
cell.amountTF.text = ""
cell.ingredientNameTF.text = ""
// cell.normativeTF.text = ""
cell.priceTF.text = ""
}
productPrice.text = "\(currency)0.00"
priceTotal = "0"
counter = 1
}
@IBAction func finishButton(_ sender: UIButton) {
for c in (0..<counter){
if let cell = addMealTableView.cellForRow(at: IndexPath(row: c, section: 0)) as? AddMealsTableViewCell {
cell.amountTF.delegate = self
cell.ingredientNameTF.delegate = self
// cell.normativeTF.delegate = self
cell.priceTF.delegate = self
guard cell.priceTF.text?.isEmpty == false && cell.amountTF.text?.isEmpty == false && mealNameTF.text?.isEmpty == false && cell.ingredientNameTF.text?.isEmpty == false
else {
return
}
if cell.priceTF.text?.isEmpty == false{
// if (true) {
let tfp = Double((cell.priceTF.text!))!*Double((cell.amountTF.text!))!
var ttp = Double(priceTotal)
ttp! += tfp
priceTotal = String(ttp!)
// }
}}
}
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let newMeal = NSEntityDescription.insertNewObject(forEntityName: "Meal", into: context)
let mealName = mealNameTF.text
newMeal.setValue(mealName, forKey: "name")
newMeal.setValue(priceTotal, forKey: "price")
do {
try context.save()
print("Spremljeno")
} catch {
print("Neki error")
}
productPrice.text = currency + priceTotal
}
@IBAction func addNewIngredientButton(_ sender: UIButton) {
}
func borderToTextfield(textField: UITextField){
let border = CALayer()
let width = CGFloat(2.0)
border.borderColor = UIColor.white.cgColor
border.frame = CGRect(x: 0, y: textField.frame.size.height - width, width: textField.frame.size.width, height: textField.frame.size.height)
border.borderWidth = width
textField.layer.addSublayer(border)
textField.layer.masksToBounds = true
textField.tintColor = UIColor.white
textField.textColor = UIColor.white
textField.textAlignment = .center
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
self.view.endEditing(true)
return true;
}
}
Handy
class AddMealsTableViewCell: UITableViewCell, UITextFieldDelegate{
@IBOutlet weak var DropMenuButton: DropMenuButton!
@IBOutlet weak var addNewIngredient: UIButton!
@IBOutlet weak var ingredientNameTF: UITextField!
// @IBOutlet weak var normativeTF: UITextField!
@IBOutlet weak var amountTF: UITextField!
@IBOutlet weak var priceTF: UITextField!
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
self.endEditing(true)
return true;
}
override func prepareForReuse() {
self.amountTF.text = ""
self.priceTF.text = ""
self.ingredientNameTF.text = ""
}
@IBAction func DropMenuButton(_ sender: DropMenuButton) {
DropMenuButton.initMenu(["kg", "litre", "1/pcs"], actions: [({() -> (Void) in
print("kg")
sender.titleLabel?.text = "kg"
}), ({() -> (Void) in
print("litre")
sender.titleLabel?.text = "litre"
}), ({() -> (Void) in
print("1/pcs")
sender.titleLabel?.text = "1/pcs"
})])
}
@IBAction func addNewIngredient(_ sender: UIButton) {
let name = ingredientNameTF.text
let amount = amountTF.text
let price = priceTF.text
// let normative = normativeTF.text
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let newIngredient = NSEntityDescription.insertNewObject(forEntityName: "Ingredient", into: context)
newIngredient.setValue(name, forKey: "name")
// newIngredient.setValue(normative, forKey: "normative")
newIngredient.setValue(amount, forKey: "amount")
newIngredient.setValue(price, forKey: "price")
do {
try context.save()
print("Spremljeno")
} catch {
print("Neki error")
}
}
}
Ok, danke. Aber wenn ich das tue, erscheint ein anderes Problem. Wenn ich die Tabellenansicht dort lade, wo diese benutzerdefinierte Zelle ist, schlägt sie fehl und es heißt: Index außerhalb des Bereichs. Was kann ich tun, um das Problem zu beheben? – Alen
@Alen Welche Zeile schlägt speziell mit diesem Fehler fehl? – ColdLogic
@CodeLogic Bei dieser Zeile: lassen Sie Zutat = Zutaten [indexPath.Zeile] in meiner Konsole Ausgabe bekomme ich: fataler Fehler: Index außerhalb des Bereichs – Alen