UICollectionViewCell内部的领域对象级别通知 [英] Realm Object-Level Notifications inside UICollectionViewCell's

查看:137
本文介绍了UICollectionViewCell内部的领域对象级别通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含Album对象的集合视图.通过单击单元格内部的按钮,可以收藏Album或收藏Album.按钮图像的变化取决于Album是否被收藏.这部分很容易并且有效.

I have a collection view with Album objects. An Albumcould be favorited or unfavorited by tapping a button inside of the cell. The buttons image changes depending on if the Album is favorited or not. This part is easy and works.

我遇到的问题是:

  • 如果选择一个单元格,则会出现一个新的视图控制器,该单元格中的Album对象.在此视图控制器中,您可以收藏或取消收藏Album对象. 现在,当我关闭该视图控制器时,将根据AlbumisFavorite属性不"更新单元格中的按钮.
  • If you select a cell, a new view controller appears with the Album object in the cell. Within this view controller, you can favorite or unfavorite the Album object. Now when I dismiss this view controller, the button in the cell is "not" updated based on Album's isFavorite property.

我认为解决方案是使用领域的对象级通知在UICollectionViewCell的内部.这样,当您在不同的视图控制器中喜欢/不喜欢Album时,返回到集合视图时,该按钮是最新的.但是我不知道如何添加和删除通知-像在哪里添加/删除以及在哪里根据通知进行更新?

I think the solution is to use Realm's Object-Level Notifications inside the UICollectionViewCell's. So that when you favorite/unfavorite an Album in different view controllers, when you come back to the collection view, the button is up to date. But I have no idea how to add and remove the notifications - like where to add/remove and where to update based on the notification?

注意:请不要说使用collectionView.reloadData().

这是我到目前为止的内容(请注意评论:var notificationToken: NotificationToken? // Is this where I add the notification for Realm?):

This is what I have so far (notice the comment: var notificationToken: NotificationToken? // Is this where I add the notification for Realm?):

class Album: Object {
    dynamic var title = ""
    dynamic var isFavorite = false

    convenience init(json: [String: Any]) throws {
        self.init()

        guard let title = json["title"] as? String else {
            throw SerializationError.invalidJSON("Album")
        }

        self.title = title
    }
}

protocol AlbumCollectionViewCellDelegate: class {
    func didTapFavoriteButton(_ favoriteButton: UIButton, album: Album)
}

class AlbumCollectionViewCell: UICollectionViewCell {
    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var favoriteButton: UIButton!

    weak var delegate: AlbumCollectionViewCellDelegate?
    var album: Album!

    // HELP
    var notificationToken: NotificationToken? // Is this where I add the notification for Realm?

    @IBAction func didTapFavoriteButton(_ sender: UIButton) {
        delegate?.didTapFavoriteButton(sender, album: album)
    }

    func configure(with album: Album) {
        titleLabel.text = album.title
        favoriteButton.isSelected = album.isFavorite
        self.album = album
    }
}

class FavoritesListViewController: UIViewController, AlbumCollectionViewCellDelegate {

    // MARK: - AlbumCollectionViewCellDelegate
    func didTapFavoriteButton(_ favoriteButton: UIButton, album: Album) {
        favoriteButton.isSelected = album.isFavorite
    }
}

有什么想法吗?

推荐答案

我知道您说过不提reloadData(),但是如果确保视图控制器不在屏幕上并且会被调回到屏幕上,我会相反,只需将reloadData()(甚至只是reload​Items(at:​ [Index​Path])传递可见项的索引路径)调用到视图控制器的viewWillAppear(animated:)方法中即可.

I know you said not to mention reloadData(), but if the view controller was guaranteed to be off screen and would be called back onto the screen, I would instead just call reloadData() (or even just reload​Items(at:​ [Index​Path]) passing in the index paths of the visible items) into the viewWillAppear(animated:) method of the view controller.

这比管理通知令牌集要容易得多,尤其是如果在视图控制器开始显示时甚至不使用通知令牌的情况下. :)

It would be much easier than managing sets of notification tokens, especially if you're not even using notification tokens when the view controller is on screen to begin with. :)

话虽如此,如果您想避免手动更新视图,无论是在屏幕上还是在屏幕外,并且始终依赖于通知,那么,是的,Realm的对象级通知将是最适合使用的功能,是的,将逻辑添加到集合视图单元格子类将是最合适的. :)

That being said, if you want to avoid manually updating the view, when it's onscreen and offscreen and rely on notifications all the time, then yes, Realm's object-level notifications would be the most appropriate feature to use, and yes, adding the logic to the collection view cell subclass would be the most appropriate. :)

class AlbumCollectionViewCell: UICollectionViewCell {
    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var favoriteButton: UIButton!

    weak var delegate: AlbumCollectionViewCellDelegate?
    var album: Album!

    var notificationToken: NotificationToken? 

    @IBAction func didTapFavoriteButton(_ sender: UIButton) {
        delegate?.didTapFavoriteButton(sender, album: album)
    }

    override func prepareForReuse() {
        notificationToken.stop()
        notificationToken = nil
    }

    func configure(with album: Album) {
        titleLabel.text = album.title
        favoriteButton.isSelected = album.isFavorite
        self.album = album

        notificationToken = self.album.addNotificationBlock { change in
            switch change {
            case .change(let properties):
                for property in properties {
                    if property.name == "isFavorite" {
                        self.favoriteButton.isSelected = self.album.isFavorite
                    }
                }
            }
        }
    }
}

这篇关于UICollectionViewCell内部的领域对象级别通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆