Как отображать объекты в порядке возрастания на табличном представлении? - PullRequest
0 голосов
/ 05 апреля 2020

У меня есть проект Bookstore с отдельными классами для Book и Bookstore, а затем контроллер основного вида и соответствующий контроллер подробного представления. В данный момент он отображает список книг из массива книг с именем bookList, но я хочу изменить его, чтобы список книг отображался в порядке возрастания.

Я думаю, что код для изменения массива bookList должно быть bookList.sorted() { $0.title < $1.title }, но я не знаю, где его разместить, чтобы он отображался в представлении в порядке возрастания в соответствии с заголовком.

Я попытался поместить этот код в viewDidLoad из DetailViewController, добавив var myBookStore = BookStore () в начало класса, а затем вызвав bookList.sorted() { $0.title < $1.title } в методе viewDidLoad, но это говорит Result of call to 'sorted(by:)' is unused

Класс книги

class Book {
    var title: String
    var author: String
    var description: String
    var price: Double


    init(title: String, author: String, description: String, price: Double) {
        self.title = title
        self.author = author
        self.description = description
        self.price = price
    }
}

Класс модели BookStore:

class BookStore {
    var bookList: [Book] = [] //bookList is an array which allows us to add a series of objects - Book objects :)

    var book1 = Book(title: "Z to A in weird words", author: "Arthur Doyle", description: "standout strange words", price: 30.95)
    var book2 = Book(title: "Cave Life", author: "Samuel Stone", description: "Outliving coronavirus", price: 10.00)
    var book3 = Book(title: "Andy Warhol: the biography", author: "Bal Smith", description: "the artist's life", price: 5.00)


    init() {
        bookList += [book1, book2, book3]
        }

Контроллер детального вида:

class DetailViewController: UIViewController {

    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var authorLabel: UILabel! 
    @IBOutlet weak var descriptionTextView: UITextView!
    @IBOutlet weak var priceLabel: UILabel!

    var myBookStore = BookStore()


    //convenience method
    func configureView() {
        // Update the user interface for the detail item.

        if let myBook = detailItem { 
            titleLabel.text = myBook.title
            authorLabel.text = myBook.author
            descriptionTextView.text = myBook.description
            priceLabel.text = String(format: "%.2f", myBook.price)

        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        configureView()

        myBookStore.bookList.sorted() { $0.title < $1.title }

    }

    var detailItem: Book? {
        didSet {
            // Update the view.

        }
    }


}

Контроллер основного вида:

class MasterViewController: UITableViewController {

    var detailViewController: DetailViewController? = nil
    var objects = [Any]()

    var myBookStore = BookStore()


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        navigationItem.leftBarButtonItem = editButtonItem

        let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(insertNewObject(_:)))
        navigationItem.rightBarButtonItem = addButton
        if let split = splitViewController {
            let controllers = split.viewControllers
            detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController
        }
    }

    override func viewWillAppear(_ animated: Bool) {
        clearsSelectionOnViewWillAppear = splitViewController!.isCollapsed
        super.viewWillAppear(animated)
    }

    @objc
    func insertNewObject(_ sender: Any) {
        objects.insert(NSDate(), at: 0)
        let indexPath = IndexPath(row: 0, section: 0)
        tableView.insertRows(at: [indexPath], with: .automatic)
    }

    // MARK: - Segues


    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "showDetail" {
            if let indexPath = tableView.indexPathForSelectedRow {
                let selectedBook: Book = myBookStore.bookList[indexPath.row]
                let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController
                controller.detailItem = selectedBook
                controller.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
                controller.navigationItem.leftItemsSupplementBackButton = true
                detailViewController = controller
            }
        }
    }

    // MARK: - Table View

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

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

    //tip: look for default provided object to replace this with your object
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        cell.textLabel!.text = myBookStore.bookList[indexPath.row].title
        cell.detailTextLabel!.text = "Default text"
        return cell
    }

    override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        // Return false if you do not want the specified item to be editable.
        return true
    }

    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            objects.remove(at: indexPath.row)
            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.
        }
    }


}

1 Ответ

3 голосов
/ 05 апреля 2020

Итак, во-первых, .sorted() возвращает отсортированную копию того, что вы ей даете. Вот почему Xcode предупреждает вас о том, что результат не используется - он возвращает новый массив, и вы не назначаете его переменной или нигде не используете. Для сортировки на месте вы можете использовать .sort(). Если вы просто измените сортировку на сортировку в своем текущем коде, она будет работать, пока вы не добавите новую книгу в bookList, но я скажу, что это не очень хорошая идея.

(Если ваш bookList будет будьте статичны c, тогда все будет в порядке, и я просто переместу вызов .sort() в конец вашего BookStore инициализатора, чтобы обеспечить надлежащее разделение проблем.)

Вы можете использовать вычисляемая переменная в вашей модели, которая возвращает отсортированную копию bookList и использует ее вместо:

var bookListSorted: [Book] {
    bookList.sorted() { $0.title < $1.title }
}

, которая будет работать, если у вас есть маленькая bookList, но она также не очень хороша, потому что каждый раз Вы просите счет или индекс в нем, он будет пересчитан, что может очень быстро стать дорогим.

Вместо этого я бы порекомендовал вам не допустить, чтобы ваш bookList был изменен извне вашего класса модели. (private(set) var bookList: [Book]) и вместо этого предоставьте функции в классе модели для добавления, редактирования или удаления записей в bookList. Вы можете выполнить сортировку на месте после внесения каких-либо изменений или, если вам нужна максимальная эффективность, вам нужно подумать о реализации бинарного поиска , чтобы найти правильный индекс для новой записи, а затем вставить его при этом. индекс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...