xcode 如何在Swift invoice应用中正确显示invoice单元格到下一个视图控制器tableViewCell?

cgh8pdjw  于 2023-06-07  发布在  Swift
关注(0)|答案(1)|浏览(80)

我是新来的,也是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单元格中显示此单元格,但它显示在不正确的范围不正确的方式。
我会分享我的模拟器截图,这样你们就可以指出我说的话和我的问题。

sqyvllje

sqyvllje1#

这是细节控制器。

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] = [] {
        didSet {tableView.reloadData()}
     }
    
    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
                      
        }
    }
    
    func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 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
   }
 }

按钮动作

@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.invoices = invoices as? [Invoice] ?? []
                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)")
    }
}

相关问题