diff --git a/Extensions/CollectionItem+Extensions.swift b/Extensions/CollectionItem+Extensions.swift index df6ea72..f9a7b69 100644 --- a/Extensions/CollectionItem+Extensions.swift +++ b/Extensions/CollectionItem+Extensions.swift @@ -34,8 +34,21 @@ extension CollectionItem { identification: identification, status: status, configuration: configuration) - default: - return UITableView.automaticDimension + case let .account(account): + return AccountView.estimatedHeight(width: width, account: account) + case .loadMore: + return LoadMoreView.estimatedHeight + case let .notification(notification, configuration): + return NotificationView.estimatedHeight( + width: width, + identification: identification, + notification: notification, + configuration: configuration) + case let .conversation(conversation): + return ConversationView.estimatedHeight( + width: width, + identification: identification, + conversation: conversation) } } } diff --git a/Views/AccountView.swift b/Views/AccountView.swift index d1df05b..b7e7038 100644 --- a/Views/AccountView.swift +++ b/Views/AccountView.swift @@ -1,6 +1,7 @@ // Copyright © 2020 Metabolist. All rights reserved. import Kingfisher +import Mastodon import UIKit final class AccountView: UIView { @@ -26,6 +27,16 @@ final class AccountView: UIView { } } +extension AccountView { + static func estimatedHeight(width: CGFloat, account: Account) -> CGFloat { + .defaultSpacing * 2 + + .compactSpacing * 2 + + account.displayName.height(width: width, font: .preferredFont(forTextStyle: .headline)) + + account.acct.height(width: width, font: .preferredFont(forTextStyle: .subheadline)) + + account.note.attributed.string.height(width: width, font: .preferredFont(forTextStyle: .callout)) + } +} + extension AccountView: UIContentView { var configuration: UIContentConfiguration { get { accountConfiguration } diff --git a/Views/ConversationView.swift b/Views/ConversationView.swift index d450213..ae45d95 100644 --- a/Views/ConversationView.swift +++ b/Views/ConversationView.swift @@ -1,6 +1,8 @@ // Copyright © 2020 Metabolist. All rights reserved. +import Mastodon import UIKit +import ViewModels final class ConversationView: UIView { let avatarsView = ConversationAvatarsView() @@ -24,6 +26,24 @@ final class ConversationView: UIView { } } +extension ConversationView { + static func estimatedHeight(width: CGFloat, + identification: Identification, + conversation: Conversation) -> CGFloat { + guard let status = conversation.lastStatus else { return UITableView.automaticDimension } + + let bodyWidth = width - .defaultSpacing - .avatarDimension + + return .defaultSpacing * 2 + + UIFont.preferredFont(forTextStyle: .headline).lineHeight + + StatusBodyView.estimatedHeight( + width: bodyWidth, + identification: identification, + status: status, + configuration: .default) + } +} + extension ConversationView: UIContentView { var configuration: UIContentConfiguration { get { conversationConfiguration } diff --git a/Views/LoadMoreView.swift b/Views/LoadMoreView.swift index 2836656..7574369 100644 --- a/Views/LoadMoreView.swift +++ b/Views/LoadMoreView.swift @@ -28,6 +28,10 @@ final class LoadMoreView: UIView { } extension LoadMoreView { + static var estimatedHeight: CGFloat { + .defaultSpacing * 2 + UIFont.preferredFont(forTextStyle: .title2).lineHeight + } + func directionChanged(up: Bool) { guard !loadMoreConfiguration.viewModel.loading else { return } diff --git a/Views/NotificationView.swift b/Views/NotificationView.swift index 3c37c8a..3df32c1 100644 --- a/Views/NotificationView.swift +++ b/Views/NotificationView.swift @@ -3,6 +3,7 @@ import Kingfisher import Mastodon import UIKit +import ViewModels final class NotificationView: UIView { private let iconImageView = UIImageView() @@ -29,6 +30,33 @@ final class NotificationView: UIView { } } +extension NotificationView { + static func estimatedHeight(width: CGFloat, + identification: Identification, + notification: MastodonNotification, + configuration: CollectionItem.StatusConfiguration?) -> CGFloat { + let bodyWidth = width - .defaultSpacing - .avatarDimension + + var height = CGFloat.defaultSpacing * 2 + + UIFont.preferredFont(forTextStyle: .headline).lineHeight + + .compactSpacing + + if let status = notification.status { + height += StatusBodyView.estimatedHeight( + width: bodyWidth, + identification: identification, + status: status, + configuration: configuration ?? .default) + } else { + height += UIFont.preferredFont(forTextStyle: .headline).lineHeight + + .compactSpacing + + UIFont.preferredFont(forTextStyle: .subheadline).lineHeight + } + + return height + } +} + extension NotificationView: UIContentView { var configuration: UIContentConfiguration { get { notificationConfiguration }