我是新来的,也是swift的新手。现在我正在创建一个invoice应用,所以我需要在nextViewController中显示invoiceViewController,但是invoice中的账单单元格不能正确地进入下一页,就像是一个rangeProblem。我试过几种方法,但越来越失望。谁能听见救命啊!..
这是我的InvoiceViewController
enum selecteddScope:Int {
case Name = 0
case Code = 1
case Price = 2
case Quantity = 3
case Total = 4
}
import UIKit
import CoreData
class InvoiceViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate {
@IBOutlet var searchBar: UISearchBar!
@IBOutlet var invoiceNo: UITextField?
@IBOutlet var customerName: UITextField?
@IBOutlet var invoiceDate: UIDatePicker?
@IBOutlet var tableView: UITableView!
@IBOutlet var totalAmountLabel: UILabel!
@IBOutlet var discountLabel: UILabel!
@IBOutlet var netAmountLabel: UILabel!
var selectedCellValues: [String] = []
var invoices: [NSManagedObject] = []
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
var currentInvoice: Invoice?
let appDelegate = UIApplication.shared.delegate as! AppDelegate
var filteringInvoices: [NSManagedObject] = []
var isSearching = false
var managedObjectContext: NSManagedObjectContext!
var totalSum = 0.0
override func viewDidLoad() {
super.viewDidLoad()
loadDataFromDatabases()
tableView.reloadData()
searchBar.delegate = self
saveToOurCoreData()
searchBarSetuP()
fetchInvoices()
tableView.reloadData()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "celll")
self.navigationItem.rightBarButtonItem = self.editButtonItem
}
func searchBarSetuP() {
let searchBar = UISearchBar(frame: CGRect(x:0,y:0,width:(UIScreen.main.bounds.width),height:70))
searchBar.showsScopeBar = true
searchBar.scopeButtonTitles = ["Name","Code","Price","Quantity","Total"]
searchBar.selectedScopeButtonIndex = 0
searchBar.delegate = self
self.tableView.tableHeaderView = searchBar
}
func fetchInvoices() {
do {
invoices = try context.fetch(Invoice.fetchRequest())
} catch {
print("Error fetching invoice: \(error.localizedDescription)")
}
tableView.reloadData()
}
func filteringInvoices(with searchText: String) {
let predicate = NSPredicate(format: "productName CONTAINS[c] %@ OR productCode CONTAINS[c] %@ OR unitPrice == %@ OR quantity == %@ OR totalAmount == %@", searchText, searchText, searchText, searchText, searchText)
filteringInvoices = invoices.filter { predicate.evaluate(with: $0) }
tableView.reloadData()
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchText.isEmpty {
isSearching = true
filteringInvoices = invoices
} else {
isSearching = false
filteringInvoices(with: searchText)
// filterContentForSearchText(searchText, scope: searchBar.selectedScopeButtonIndex)
}
tableView.reloadData()
}
override func viewWillAppear(_ animated: Bool) {
loadDataFromDatabases()
tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func loadDataFromDatabases() {
//Set up Core Data Context
let context = appDelegate.persistentContainer.viewContext
//Set up Request
let request = NSFetchRequest<NSManagedObject>(entityName: "Invoice")
//Execute request
do {
invoices = try context.fetch(request)
} catch _ as NSError {
// print("Could not fetch. \(error), \(error.userInfo)")
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return isSearching ? filteringInvoices.count : invoices.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "celll", for: indexPath)
let invoice: Invoice
if isSearching {
invoice = filteringInvoices[indexPath.row] as! Invoice
} else {
invoice = invoices[indexPath.row] as! Invoice
}
// Create labels for each column
let productNameLabel = UILabel()
let productCodeLabel = UILabel()
let unitPriceLabel = UILabel()
let quantityLabel = UILabel()
let totalLabel = UILabel()
// Configure label properties
productNameLabel.text = invoice.productName
productNameLabel.textAlignment = .left
productNameLabel.frame = CGRect(x: 15, y: 10, width: 100, height: 30)
productCodeLabel.text = invoice.productCode
productCodeLabel.textAlignment = .left
productCodeLabel.frame = CGRect(x: 100, y: 10, width: 100, height: 30)
unitPriceLabel.text = String(invoice.unitPrice)
unitPriceLabel.textAlignment = .left
unitPriceLabel.frame = CGRect(x: 180, y: 10, width: 100, height: 30)
quantityLabel.text = String(invoice.quantity)
quantityLabel.textAlignment = .left
quantityLabel.frame = CGRect(x: 250, y: 10, width: 100, height: 30)
totalLabel.text = String(invoice.totalAmount)
totalLabel.textAlignment = .right
totalLabel.frame = CGRect(x: 270, y: 10, width: 100, height: 30)
// Remove existing labels from cell's contentView
cell.contentView.subviews.forEach { $0.removeFromSuperview()
}
// Add labels to the cell's contentView
cell.contentView.addSubview(productNameLabel)
cell.contentView.addSubview(productCodeLabel)
cell.contentView.addSubview(unitPriceLabel)
cell.contentView.addSubview(quantityLabel)
cell.contentView.addSubview(totalLabel)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// Get the selected item
if let selecteddInvoice = invoices[indexPath.row] as? Invoice {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
if let controller = storyboard.instantiateViewController(withIdentifier: "ProductDetailViewController") as? ProductDetailViewController {
controller.selecteddItem = selecteddInvoice
self.navigationController?.pushViewController(controller, animated: true)
} else {
print("Failed to instantiate DetailViewController")
}
}
}
@IBAction func onClickSaveInvoice(_ sender: UIButton) {
//saveToOurCoreData()
guard UIApplication.shared.delegate is AppDelegate else {
return
}
// Save the calculated values
let totalSum = calculateTotalAmount()
let netAmount = totalSum - 100
do {
// Pass the calculated values to InvoiceDetailViewController
if let selectedInvoice = invoices.first as? Invoice {
let section = 0
let rowIndexes = 0...5
var selectedCellValues: [String] = []
for row in rowIndexes {
let indexPath = IndexPath(row: row, section: section)
let cell = tableView.dequeueReusableCell(withIdentifier: "celll", for: indexPath)
}
if let selectedIndexPath = tableView.indexPathForSelectedRow {
if let selectedCell = tableView.cellForRow(at: selectedIndexPath) {
for subview in selectedCell.contentView.subviews {
if let label = subview as? UILabel {
if let labelText = label.text {
selectedCellValues.append(labelText)
print("label.text")
}
}
else if let otherLabel1 = subview as? UILabel {
if let otherLabel1Text = otherLabel1.text {
selectedCellValues.append(otherLabel1Text)
print("otherLabel1.text")
}
}
else if let otherLabel2 = subview as? UILabel {
if let otherLabel2Text = otherLabel2.text {
selectedCellValues.append(otherLabel2Text)
}
}
else if let otherLabel3 = subview as? UILabel {
if let otherLabel3Text = otherLabel3.text {
selectedCellValues.append(otherLabel3Text)
}
print(selectedCellValues)
}
}
}
}
let storyboard = UIStoryboard(name: "Main", bundle: nil)
if let controller = storyboard.instantiateViewController(withIdentifier: "InvoiceDetailViewController") as? InvoiceDetailViewController {
controller.selectedddItem = selectedInvoice
controller.cellValues = selectedCellValues
controller.invoice = selectedInvoice
controller.invoice?.customer = customerName?.text
controller.invoice?.number = invoiceNo?.text
controller.invoice?.amountTotal = String(totalSum)
controller.invoice?.netTotal = String(netAmount)
controller.invoice?.date = invoiceDate?.date
self.navigationController?.pushViewController(controller, animated: true)
} else {
print("Failed to instantiate InvoiceDetailViewController")
}
}
} catch _ as NSError {
// print("Could not save. \(error), \(error.userInfo)")
}
}
func saveToOurCoreData() {
guard UIApplication.shared.delegate is AppDelegate else {
return
}
let context = appDelegate.persistentContainer.viewContext
let request = NSFetchRequest<NSManagedObject>(entityName: "Invoice")
do {
invoices = try context.fetch(request)
// Calculate total amount
var totalSum = 0.0
for invoice in invoices {
if let amount = invoice.value(forKey: "totalAmount") as? Double {
totalSum += amount
}
}
totalAmountLabel.text = String(totalSum)
// Calculate net amount
let netAmount = totalSum - 100
netAmountLabel.text = String(netAmount)
} catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
}
}
func calculateTotalAmount() -> Double {
var totalSum = 0.0
for invoice in invoices {
if let amount = invoice.value(forKey: "totalAmount") as? Double {
totalSum += amount
}
}
return totalSum
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
let invoice = invoices[indexPath.row] as? Invoice
let name = invoice!.productName
let alertController = UIAlertController(title: "Selected row: \(indexPath.row) (\(name))", message: "Are you sure you want to delete this Product?", preferredStyle: .alert)
let cancelAction = UIAlertAction(title: "No", style: .cancel, handler: nil)
alertController.addAction(cancelAction)
let deleteAction = UIAlertAction(title: "Yes", style: .destructive) { [self] _ in
let context = appDelegate.persistentContainer.viewContext
context.delete(invoice!)
do {
try context.save()
loadDataFromDatabases()
tableView.deleteRows(at: [indexPath], with: .fade)
}
catch {
fatalError("Error saving context: \(error)")
}
}
// loadDataFromDatabase()
alertController.addAction(deleteAction)
present(alertController, animated: true, completion: nil)
// tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "invoiceDetailViewController" {
let destinationVC1 = segue.destination as! InvoiceDetailViewController
}
}
}
extension InvoiceViewController: NSFetchedResultsControllerDelegate {
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
tableView.reloadData()
}
func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
filterContentForSearchText(searchBar.text ?? "", scope: selectedScope)
}
func filterContentForSearchText(_ searchText: String, scope: Int) {
var predicate: NSPredicate?
switch scope {
case 0: // Name
predicate = NSPredicate(format: "productName CONTAINS[c] %@", searchText)
case 1: // Code
predicate = NSPredicate(format: "productCode CONTAINS[c] %@", searchText)
case 2: // Price
predicate = NSPredicate(format: "unitPrice == %@", searchText)
case 3: // Quantity
predicate = NSPredicate(format: "quantity == %@", searchText)
case 4: // Amount
predicate = NSPredicate(format: "totalAmount == %@", searchText)
default:
predicate = nil
}
if let predicate = predicate {
filteringInvoices = invoices.filter { predicate.evaluate(with: $0) }
} else {
filteringInvoices = invoices
}
tableView.reloadData()
}
}
andthis is my detailInvoiceViewController
class InvoiceDetailViewController: UIViewController, UITableViewDataSource {
@IBOutlet var labelOfDate: UILabel!
@IBOutlet var labelOfCustomer: UILabel!
@IBOutlet var labelOfNumber: UILabel!
@IBOutlet var labelOfTotalAmount: UILabel!
@IBOutlet var labelOfNetAmount: UILabel!
@IBOutlet var tableViewww: UITableView!
var cellValues: [String] = []
var selectedddItem: Invoice?
var invoice: Invoice?
var invoices: [Invoice] = []
override func viewDidLoad() {
super.viewDidLoad()
// tableViewww.reloadData()
if let invoice = selectedddItem {
labelOfCustomer.text = invoice.customer
labelOfNumber.text = invoice.number
labelOfTotalAmount.text = invoice.amountTotal
labelOfNetAmount.text = invoice.netTotal
// Convert Date to String using a DateFormatter
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/dd/yyyy"
if let date = invoice.date {
labelOfDate.text = dateFormatter.string(from: date)
} else {
labelOfDate.text = ""
}
// Update cell values
cellValues = [
invoice.productName ?? "",
invoice.productCode ?? "",
String(invoice.unitPrice),
String(invoice.quantity),
String(invoice.totalAmount),
]
tableViewww.reloadData()
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of rows based on your data
return cellValues.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cells", for: indexPath)
let productNameLabel1 = UILabel()
let productCodeLabel2 = UILabel()
let unitPriceLabel3 = UILabel()
let quantityLabel4 = UILabel()
let totalLabel5 = UILabel()
productNameLabel1.text = cellValues[indexPath.row]
productNameLabel1.textAlignment = .left
productNameLabel1.frame = CGRect(x: 15, y: 10, width: 100, height: 30)
productCodeLabel2.text = cellValues[1]
productCodeLabel2.textAlignment = .left
productCodeLabel2.frame = CGRect(x: 100, y: 10, width: 100, height: 30)
unitPriceLabel3.text = cellValues[2]
unitPriceLabel3.textAlignment = .left
unitPriceLabel3.frame = CGRect(x: 180, y: 10, width: 100, height: 30)
quantityLabel4.text = cellValues[3]
quantityLabel4.textAlignment = .left
quantityLabel4.frame = CGRect(x: 250, y: 10, width: 100, height: 30)
totalLabel5.text = cellValues[4]
totalLabel5.textAlignment = .right
totalLabel5.frame = CGRect(x: 270, y: 10, width: 100, height: 30)
cell.contentView.subviews.forEach { $0.removeFromSuperview() }
cell.contentView.addSubview(productNameLabel1)
cell.contentView.addSubview(productCodeLabel2)
cell.contentView.addSubview(unitPriceLabel3)
cell.contentView.addSubview(quantityLabel4)
cell.contentView.addSubview(totalLabel5)
//tableViewww.reloadData()
return cell
}
}
我已经尝试在下一个ViewController单元格中显示此单元格,但它显示在不正确的范围不正确的方式。
我会分享我的模拟器截图,这样你们就可以指出我说的话和我的问题。
1条答案
按热度按时间h9a6wy2h1#
这是细节控制器。
按钮动作