0

I have 3 user input fields which each create a different array. These arrays are being used to fill a UITableViewCell. My intention is to sort the added cells by date.

One of the input fields contains a date which shall be used to sort this table. To also display the date, the array is of type String, hence the dates are formatted to String.

Let's say I would not directly format it to String and sort it before I do. Is there a way to sort the other arrays according to the Date array?

import UIKit

class NotificationViewController: UIViewController {

    let defaults = UserDefaults.standard

    @IBOutlet weak var toolbar: UIToolbar!
    @IBOutlet weak var notificationView: UITableView!

    var isVisible = false

    var descArray: [String] = []
    var titleArray: [String] = []
    var dateArray: [String] = []
    var typeArray: [Int] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        declareArrays()
        print(dateArray)
        self.toolbar.setBackgroundImage(UIImage(),
                                        forToolbarPosition: .any,
                                        barMetrics: .default)
        self.toolbar.setShadowImage(UIImage(), forToolbarPosition: .any)
        notificationView.delegate = self
        notificationView.dataSource = self
    }

    func declareArrays() {
        descArray = getDesc()
        titleArray = getTitle()
        dateArray = getDate()
        typeArray = getType()
    }

    func getDesc() -> [String] {
        return descNotificationArray
    }

    func getTitle() -> [String] {
        return titleNotificationArray
    }

    func getDate() -> [String] {
        return dateNotificationArray
    }

    func getType() -> [Int] {
        return notificationTypeArray
    }

    @IBAction func goBack(_ sender: Any) {
        performSegue(withIdentifier: "goBackToMain", sender: self)
    }

    @IBAction func addNotification(_ sender: Any) {
       performSegue(withIdentifier: "goToType", sender: self)
    }

}

extension NotificationViewController: UITableViewDataSource, UITableViewDelegate {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dateArray.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let date = dateArray[indexPath.row]
        let title = titleArray[indexPath.row]
        let desc = descArray[indexPath.row]
        let notType = typeArray[indexPath.row]

        if notType == 1 {
            let cell = tableView.dequeueReusableCell(withIdentifier: "TuvTableViewCell") as! TuvTableViewCell
            cell.setTitle(title: title)
            cell.setDesc(desc: desc)
            cell.setDate(date: date)
            return cell
        } else if notType == 2 {
            let cell = tableView.dequeueReusableCell(withIdentifier: "ServiceNotTableViewCell") as! ServiceNotTableViewCell
            cell.setTitle(title: title)
            cell.setDesc(desc: desc)
            cell.setDate(date: date)
            return cell
        } else {
            let cell = tableView.dequeueReusableCell(withIdentifier: "NotificationViewCell") as! NotificationViewCell
            cell.setTitle(title: title)
            cell.setDesc(desc: desc)
            cell.setDate(date: date)
            return cell
        }
    }

    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if (editingStyle == .delete) {
            dateArray.remove(at: indexPath.item)
            titleArray.remove(at: indexPath.item)
            descArray.remove(at: indexPath.item)

            descNotificationArray.remove(at: indexPath.item)
            dateNotificationArray.remove(at: indexPath.item)
            titleNotificationArray.remove(at: indexPath.item)

            defaults.set(descNotificationArray, forKey: "descNotificationArray")
            defaults.set(dateNotificationArray, forKey: "dateNotificationArray")
            defaults.set(titleNotificationArray, forKey: "titleNotificationArray")

            tableView.deleteRows(at: [indexPath], with: .automatic)
        }
    }

}

Edit:

Ok, I've added an struct and a func which appends the input to the array and sorts it:

struct not {
    var title: String
    var desc: String
    var Date: Date
}

func appendToStructArray() {
        let notificationData: not = not(title: notifTitle.text!, desc: notifDescribtion.text!, Date: datePicker.date)
        notStructArray.append(notificationData)
        notStructArray.sort(by: { $0.Date < $1.Date })
    }

Now in the TableViewController: How do I manage to get the data from one struct inside of the array and add it to a cell just like I did it previously with my arrays?

3
  • Your code makes no sense. What is dateNotificationArray? If dateArray is an array of dates, why is it an array of String? Commented Apr 28, 2019 at 17:05
  • This video by Rob Napier talks about exactly your problem at 7:14. youtu.be/_S6UOrwS-Tg?t=434 Commented Apr 28, 2019 at 17:08
  • @matt I haven't thought of sorting the array before, that's why I immediately transformed the Date into a String after user input to display it. Commented Apr 28, 2019 at 17:42

2 Answers 2

3

The proper solution is to have one array, not four. Create a struct with 4 properties. Then have one array of that struct. Then it becomes trivial to add, remove, sort, and filter the array as needed to populate your table view.

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you. I've added my progress to my initial question. How do I manage to get the data from one struct inside of the array and add it to a cell just like I did it previously with my arrays?
It's no different. let rowData = notStructArray[indexPath.row]. Then access the properties of rowData to setup the cell much like you were doing. cell.setTitle(title: rowData.title)
Following error appears: Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to insert non-property list object ( "Fuel_Check.not(title: \"T\U00dcV\", desc: \"N\U00e4chster T\U00dcV Termin\", date: 2019-05-01 18:50:00 +0000, type: 1)" ) for key notStructArray'
That's a whole new issue. Do some research on that error. If you need further help with your new issue, please post a new question with all relevant details.
2

Instead using all those arrays, you might consider using another type that comprises all of those, something like:

struct Foo {
  let date: Date
  let desc: String
  let type: String
  let title: String
}

Then you would have an array of foos that you could sort by date. That way everything would be sorted without the need of handling different arrays.

2 Comments

Thank's a lot for your help. I've added my progress to my initial question. How do I manage to get the data from one struct inside of the array and add it to a cell just like I did it previously with my arrays?
Just do this in the cell for row: let not = notStructArray[indexPath.row] and use not to populate the views: cell.setTitle(not.title).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.