简体   繁体   中英

UITableview Section?

I am trying to have two sections in my tableView. I would like items to add to section 0 and then be able to select a row to move it from section 0 to section 1. So far, I have the items added to section 0, but the data doesn't load when it dismisses the second viewController. I have to change views (hit the add button the back button) and it finally shows up (still haven't figured that out). I know moving the row across sections must be done through the arrays and the didSelectRow method, but it's throwing me for a loop (especially with the coreData). Do I create a second array for the section 1 items? The TableView data is inputted from a second ViewController and managed by the NSFetchedResultsController for the Entity "SList". I have created an attribute for the "slcross" under "SList" (also included the input "slitem", "sldesc", "slqty", and "slprice" but have no idea how to go about getting it from section 0 to section 1. Or, do I need to create a second entity for the crossed off items? Sorry, I am in slightly over my head...

class ShoppingList: UIViewController, NSFetchedResultsControllerDelegate, UITableViewDataSource, UITableViewDelegate {

    let moc = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext

    var frc : NSFetchedResultsController = NSFetchedResultsController()

    func itemFetchRequest() -> NSFetchRequest{

        let fetchRequest = NSFetchRequest(entityName: "SList")
        let primarySortDescription = NSSortDescriptor(key: "slcross", ascending: true)
        let secondarySortDescription = NSSortDescriptor(key: "slitem", ascending: true)
        fetchRequest.sortDescriptors = [primarySortDescription, secondarySortDescription]
        return fetchRequest
    }

    func getFetchRequetController() ->NSFetchedResultsController{

        frc = NSFetchedResultsController(fetchRequest: itemFetchRequest(), managedObjectContext: moc, sectionNameKeyPath: "slcross", cacheName: nil)
        return frc
    }

    @IBOutlet weak var tableView: UITableView!

    @IBAction func AddNew(sender: AnyObject) {

        frc = getFetchRequetController()
        frc.delegate = self

        do {
            try frc.performFetch()
        } catch _ {
            print("Failed to perform inital fetch.")
            return
        }
        self.tableView.reloadData()
    }

    override func viewDidLoad() {

        super.viewDidLoad()


        frc = getFetchRequetController()
        frc.delegate = self

        do {
            try frc.performFetch()
        } catch _ {
            print("Failed to perform inital fetch.")
            return
        }

        self.tableView.reloadData()

        //TableView Background Color
        self.tableView.backgroundColor = UIColor.clearColor()
        self.tableView.separatorColor = UIColor.blackColor()
        tableView.reloadData()

    override func viewDidDisappear(animated: Bool) {

        frc = getFetchRequetController()
        frc.delegate = self

        do {
            try frc.performFetch()
        } catch _ {
            print("Failed to perform inital fetch.")
            return
        }
        self.tableView.reloadData()
    }

    //tableView Data
    func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        let managedObject:NSManagedObject = frc.objectAtIndexPath(indexPath) as! NSManagedObject
        moc.deleteObject(managedObject)
        do {
            try moc.save()
        } catch _ {
            print("Failed to save.")
            return
        }
    }

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {

        let numberOfSections = frc.sections?.count
        return numberOfSections!
    }

    func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String?{
        let sectionHeader = "Items - #\(frc.sections![section].numberOfObjects)"
        let sectionHeader1 = "Crossed Off Items - #\(frc.sections![section].numberOfObjects)"
        if (section == 0) {
            return sectionHeader
        }
        if (section == 1){
            return sectionHeader1
        }else{
            return nil
        }
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        let numberOfRowsInSection = frc.sections?[section].numberOfObjects
        return numberOfRowsInSection!
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
        let items = frc.objectAtIndexPath(indexPath) as! SList
        cell.backgroundColor = UIColor.clearColor()
        cell.textLabel?.text = "\(items.slitem!) - Qty: \(items.slqty!)"
        cell.textLabel?.font = UIFont.systemFontOfSize(23)


        return cell
    }
    //end tablevViewData*/


    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }


    func controllerDidChangeContent(controller: NSFetchedResultsController) {
        tableView.reloadData()
    }

    //segue to add/edit
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {

        if segue.identifier == "edit" {

            let cell = sender as! UITableViewCell
            let indexPath = tableView.indexPathForCell(cell)
            let SListController:SLEdit = segue.destinationViewController as! SLEdit
            let items:SList = frc.objectAtIndexPath(indexPath!) as! SList
            SListController.item = items
        }
    }
}

second ViewController

class SLEdit: UIViewController {

    let moc = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext


    @IBOutlet weak var slitem: UITextField!
    @IBOutlet weak var sldesc: UITextField!
    @IBOutlet weak var slqty: UITextField!
    @IBOutlet weak var slprice: UITextField!

    var item: SList? = nil


    override func viewDidLoad() {
        super.viewDidLoad()

        if item != nil{
            slitem.text = item?.slitem
            sldesc.text = item?.sldesc
            slqty.text = item?.slqty
            slprice.text = item?.slprice
        }

        // "x" Delete Feature
        self.slitem.clearButtonMode = UITextFieldViewMode.WhileEditing
        self.sldesc.clearButtonMode = UITextFieldViewMode.WhileEditing
        self.slqty.clearButtonMode = UITextFieldViewMode.WhileEditing
        self.slprice.clearButtonMode = UITextFieldViewMode.WhileEditing
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    func dismissVC() {
        navigationController?.popViewControllerAnimated(true)
    }


    // Dispose of any resources that can be recreated.


    @IBAction func saveButton(sender: AnyObject) {

        if item != nil {
            edititems()
        } else {
            createitems()
        }

        dismissVC()
    }

    func createitems() {

        let entityDescription = NSEntityDescription.entityForName("SList", inManagedObjectContext: moc)

        let item = SList(entity: entityDescription!, insertIntoManagedObjectContext: moc)

        item.slitem = slitem.text
        item.sldesc = sldesc.text
        item.slqty = slqty.text
        item.slprice = slprice.text

        if slitem.text == nil{
            createitems()

        }else{
            edititems()
        }

        do {
            try moc.save()
        } catch _ {
            return
        }
    }

    func edititems() {
        item?.slitem = slitem.text!
        item?.sldesc = sldesc.text!
        item?.slqty = slqty.text!
        item?.slprice = slprice.text!

        do {
            try moc.save()
        } catch {
            return
        }
    }
}

I am just learning and teaching myself so if you could show me and explain it so I could understand I would appreciate it!

... the data doesn't load when it dismisses the second viewController ...

I can't immediately see why that's the case. I suggest using breakpoints and/or print() to try to debug it. I would expect the table view to be automatically updated by the FRC in the controllerDidChangeContent delegate method, so start by putting

print("Controller didChangeContent reloaded the tableView")

in that method and see whether it appears in the log after you create/edit an item. Likewise for the AddNew IBAction method and viewDidDisappear .

... Do I create a second array for the section 1 items...

No need. The FRC should manage the sections and items for you: assuming slcross is a Boolean attribute, the FRC will analyse the SLItem objects and allocate them correctly to section 0 if slcross is false, and section 1 if it is true. (The indexPath used to "lookup" objects in the FRC, eg

let items = frc.objectAtIndexPath(indexPath) as! SList

comprises both the section and the row).

...how to go about getting it from section 0 to section 1...

To ensure that the items are correctly allocated when first created, add:

item.slcross = false

to the createItems() method. To move an item from section 0 to section 1, change this value to true - as you say, didSelectRowAtIndexPath is probably a good place to do this:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let items = frc.objectAtIndexPath(indexPath) as! SList
    items.slcross = true
}

...do I need to create a second entity for the crossed off items?

No need, the FRC should do the necessary.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM