From a2fe0dfb789a77309ca57b101d982419d3e72045 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Mon, 25 Sep 2023 21:44:43 -0400 Subject: [PATCH] Avoid unnecessarily recreating avatar views in notifications cells --- ...nNotificationGroupCollectionViewCell.swift | 30 +++++++++++-------- ...wNotificationGroupCollectionViewCell.swift | 28 ++++++++++------- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/Tusker/Screens/Notifications/ActionNotificationGroupCollectionViewCell.swift b/Tusker/Screens/Notifications/ActionNotificationGroupCollectionViewCell.swift index 5dd71732..5efea38e 100644 --- a/Tusker/Screens/Notifications/ActionNotificationGroupCollectionViewCell.swift +++ b/Tusker/Screens/Notifications/ActionNotificationGroupCollectionViewCell.swift @@ -139,20 +139,26 @@ class ActionNotificationGroupCollectionViewCell: UICollectionViewListCell { mastodonController.persistentContainer.account(for: $0.account.id) } - avatarStack.arrangedSubviews.forEach { $0.removeFromSuperview() } - for avatarURL in people.lazy.compactMap(\.avatar).prefix(10) { - let imageView = CachedImageView(cache: .avatars) - imageView.contentMode = .scaleAspectFill - imageView.layer.masksToBounds = true - imageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadiusFraction * 30 - imageView.layer.cornerCurve = .continuous - avatarStack.addArrangedSubview(imageView) + let visibleAvatars = Array(people.lazy.compactMap(\.avatar).prefix(10)) + for (index, avatarURL) in visibleAvatars.enumerated() { + let imageView: CachedImageView + if index < avatarStack.arrangedSubviews.count { + imageView = avatarStack.arrangedSubviews[index] as! CachedImageView + } else { + imageView = CachedImageView(cache: .avatars) + imageView.contentMode = .scaleAspectFill + imageView.layer.masksToBounds = true + imageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadiusFraction * 30 + imageView.layer.cornerCurve = .continuous + avatarStack.addArrangedSubview(imageView) + imageView.widthAnchor.constraint(equalTo: imageView.heightAnchor).isActive = true + } imageView.update(for: avatarURL) } - NSLayoutConstraint.activate(avatarStack.arrangedSubviews.map { - $0.widthAnchor.constraint(equalTo: $0.heightAnchor) - }) - + for imageView in avatarStack.arrangedSubviews.dropFirst(visibleAvatars.count) { + avatarStack.removeArrangedSubview(imageView) + } + actionLabel.setEmojis(pairs: people.map { ($0.displayOrUserName, $0.emojis) }, identifier: group.id) // todo: use htmlconverter diff --git a/Tusker/Screens/Notifications/FollowNotificationGroupCollectionViewCell.swift b/Tusker/Screens/Notifications/FollowNotificationGroupCollectionViewCell.swift index 513849c7..849357c3 100644 --- a/Tusker/Screens/Notifications/FollowNotificationGroupCollectionViewCell.swift +++ b/Tusker/Screens/Notifications/FollowNotificationGroupCollectionViewCell.swift @@ -116,19 +116,25 @@ class FollowNotificationGroupCollectionViewCell: UICollectionViewListCell { }, identifier: group.id) updateTimestamp() - avatarStack.arrangedSubviews.forEach { $0.removeFromSuperview() } - for avatarURL in people.lazy.compactMap(\.avatar).prefix(10) { - let imageView = CachedImageView(cache: .avatars) - imageView.contentMode = .scaleAspectFill - imageView.layer.masksToBounds = true - imageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadiusFraction * 30 - imageView.layer.cornerCurve = .continuous + let visibleAvatars = Array(people.lazy.compactMap(\.avatar).prefix(10)) + for (index, avatarURL) in visibleAvatars.enumerated() { + let imageView: CachedImageView + if index < avatarStack.arrangedSubviews.count { + imageView = avatarStack.arrangedSubviews[index] as! CachedImageView + } else { + imageView = CachedImageView(cache: .avatars) + imageView.contentMode = .scaleAspectFill + imageView.layer.masksToBounds = true + imageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadiusFraction * 30 + imageView.layer.cornerCurve = .continuous + avatarStack.addArrangedSubview(imageView) + imageView.widthAnchor.constraint(equalTo: imageView.heightAnchor).isActive = true + } imageView.update(for: avatarURL) - avatarStack.addArrangedSubview(imageView) } - NSLayoutConstraint.activate(avatarStack.arrangedSubviews.map { - $0.widthAnchor.constraint(equalTo: $0.heightAnchor) - }) + for imageView in avatarStack.arrangedSubviews.dropFirst(visibleAvatars.count) { + avatarStack.removeArrangedSubview(imageView) + } } private func updateActionLabel(names: [NSAttributedString]) -> NSAttributedString {