Прокрутите до последней вставленной строки в UITableView, используя объекты Realm - PullRequest
0 голосов
/ 20 марта 2019

У меня есть следующий код, который работает нормально, он получает список элементов из списка в Realm с именем groceryList и отображает их на UITableView в порядке убывания на основе productName.То, что я хотел бы сделать, это прокрутить до последней вставленной строки / элемента в таблице, прямо сейчас, когда вставляется новый элемент, пользователь может не видеть его, так как элементы переупорядочены по алфавиту, а последний элемент может не отображатьсяна tableView.

Как прокрутить до последней вставленной строки / элемента в UITableView?

Realm Objects:

    class Item:Object{
        @objc dynamic var productName:String = ""
        @objc dynamic var isItemActive = true
        @objc dynamic var createdAt = NSDate()
    }

    class ItemList: Object {
        @objc dynamic var listName = ""
        @objc dynamic var createdAt = NSDate()
        let items = List<Item>()
    }

UITableView:

    class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate{

        var allItems : Results<Item>!
        var groceryList : ItemList!

        override func viewDidLoad() {
            super.viewDidLoad()
            groceryList = realm.objects(ItemList.self).filter("listName = %@", "groceryList").first              
            updateResultsList()
        }

        func updateResultsList(){
            if let list = groceryList{
                allItems  = activeList.items.sorted(byKeyPath: "productName", ascending: false)
            }
        }

        func numberOfSections(in tableView: UITableView) -> Int {
            return 1
        }
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return allItems.count
        }
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {       
            let cell = tableView.dequeueReusableCell(withIdentifier: "reusableCell", for: indexPath) as! CustomCell       
            let data = allItems[indexPath.row]      
            cell.displayProductName.text = data.productName
            return cell
        }  
    }

Ответы [ 2 ]

3 голосов
/ 21 марта 2019

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

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    var allItems: Results<Item>!
    var groceryList: ItemList!

    var notificationToken: NotificationToken? = nil

    deinit {
        notificationToken?.invalidate()
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        groceryList = realm.objects(ItemList.self).filter("listName = %@", "groceryList").first
        updateResultsList()
        observeGroceryList
    }

    func updateResultsList(){
        if let list = groceryList {
            allItems  = activeList.items.sorted(byKeyPath: "productName", ascending: false)
        }
    }

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

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "reusableCell", for: indexPath) as! CustomCell
        let data = allItems[indexPath.row]
        cell.displayProductName.text = data.productName
        return cell
    }

    func observeGroceryList() {
        notificationToken = allItems.observe { [weak self] (changes: RealmCollectionChange) in
            switch changes {
            case .initial:
                self?.tableView.reloadData()
            case .update(_, let deletions, let insertions, let modifications):
                // Query results have changed, so apply them to the UITableView
                self?.tableView.beginUpdates()
                self?.tableView.insertRows(at: insertions.map({ IndexPath(row: $0, section: 0) }),
                                     with: .automatic)
                self?.tableView.deleteRows(at: deletions.map({ IndexPath(row: $0, section: 0)}),
                                     with: .automatic)
                self?.tableView.reloadRows(at: modifications.map({ IndexPath(row: $0, section: 0) }),
                                     with: .automatic)
                self?.tableView.endUpdates()
                if let lastInsertedRow = insertions.last {
                    self?.tableView.scrollToRow(at: insertions.last, at: .none, animated: true)
                }
            case .error(let error):
                // An error occurred while opening the Realm file on the background worker thread
                print("\(error)")
            }
        }
    }
}
1 голос
/ 20 марта 2019

Добавьте приведенный ниже код как расширение таблицы.

extension UITableView {
    func scrollToBottom() {
        let sections = numberOfSections-1
        if sections >= 0 {
            let rows = numberOfRows(inSection: sections)-1
            if rows >= 0 {
                let indexPath = IndexPath(row: rows, section: sections)
                DispatchQueue.main.async { [weak self] in
                    self?.scrollToRow(at: indexPath, at: .bottom, animated: true)
                }
            }
        }
    }
}

Теперь просто используйте его в своем методе:

func updateResultsList(){
       if let list = groceryList{
             allItems  = activeList.items.sorted(byKeyPath: "productName", ascending: false
             yourTableView.scrollToBottom()
      }
 }

Просто используйте этот метод там, где хотите, его следует прокрутить вниз.

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