问题描述
我有一个包含Album
对象的集合视图.通过单击单元格内部的按钮,可以收藏Album
或收藏Album
.按钮图像的变化取决于Album
是否被收藏.这部分很容易并且有效.
I have a collection view with Album
objects. An Album
could 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
对象. 现在,当我关闭该视图控制器时,将根据Album
的isFavorite
属性不"更新单元格中的按钮.
- 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 theAlbum
object. Now when I dismiss this view controller, the button in the cell is "not" updated based onAlbum
'sisFavorite
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()
(甚至只是reloadItems(at: [IndexPath])
传递可见项的索引路径)调用到视图控制器的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 reloadItems(at: [IndexPath])
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内部的领域对象级别通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!