diff --git a/Signal/src/ViewControllers/Wallpapers/ChatColorViewController.swift b/Signal/src/ViewControllers/Wallpapers/ChatColorViewController.swift index b900421a1d..2ca4627634 100644 --- a/Signal/src/ViewControllers/Wallpapers/ChatColorViewController.swift +++ b/Signal/src/ViewControllers/Wallpapers/ChatColorViewController.swift @@ -134,6 +134,7 @@ class ChatColorViewController: OWSTableViewController2 { hasWallpaper: hasWallpaper, customChatColor: currentValue ) + mockConversationView.delegate = self let previewSection = OWSTableSection() previewSection.hasBackground = false previewSection.add(OWSTableItem { [weak self] in @@ -214,7 +215,7 @@ class ChatColorViewController: OWSTableViewController2 { private func showCustomColorView(valueMode: CustomColorViewController.ValueMode) { let customColorVC = CustomColorViewController(thread: thread, - valueMode: valueMode) { [weak self] (value) in + valueMode: valueMode) { [weak self] (value: ChatColor) in guard let self = self else { return } Self.databaseStorage.write { transaction in Self.chatColors.upsertCustomValue(value, transaction: transaction) @@ -496,3 +497,11 @@ class ChatColorViewController: OWSTableViewController2 { saveAndDismiss() } } + +// MARK: - + +extension ChatColorViewController: MockConversationDelegate { + var mockConversationViewWidth: CGFloat { + self.view.width - cellOuterInsets.totalWidth + } +} diff --git a/Signal/src/ViewControllers/Wallpapers/CustomColorViewController.swift b/Signal/src/ViewControllers/Wallpapers/CustomColorViewController.swift index 5f9a5f09eb..ed9974e3b3 100644 --- a/Signal/src/ViewControllers/Wallpapers/CustomColorViewController.swift +++ b/Signal/src/ViewControllers/Wallpapers/CustomColorViewController.swift @@ -927,6 +927,7 @@ private class CustomColorPreviewView: UIView { self.addSubview(wallpaperPreviewView) wallpaperPreviewView.autoPinEdgesToSuperviewEdges() + mockConversationView.delegate = self mockConversationView.setContentHuggingVerticalHigh() mockConversationView.setCompressionResistanceVerticalHigh() self.addSubview(mockConversationView) @@ -1364,3 +1365,9 @@ class CustomColorGestureRecognizer: UIGestureRecognizer { self.isActive = false } } + +// MARK: - + +extension CustomColorPreviewView: MockConversationDelegate { + var mockConversationViewWidth: CGFloat { self.width } +} diff --git a/Signal/src/ViewControllers/Wallpapers/PreviewWallpaperViewController.swift b/Signal/src/ViewControllers/Wallpapers/PreviewWallpaperViewController.swift index 3359b995ff..cb567c3c3e 100644 --- a/Signal/src/ViewControllers/Wallpapers/PreviewWallpaperViewController.swift +++ b/Signal/src/ViewControllers/Wallpapers/PreviewWallpaperViewController.swift @@ -37,6 +37,8 @@ class PreviewWallpaperViewController: UIViewController { self.delegate = delegate super.init(nibName: nil, bundle: nil) + + mockConversationView.delegate = self } required init?(coder: NSCoder) { @@ -536,3 +538,9 @@ class BlurButton: UIButton { action(isSelected) } } + +// MARK: - + +extension PreviewWallpaperViewController: MockConversationDelegate { + var mockConversationViewWidth: CGFloat { self.view.width } +} diff --git a/Signal/src/views/MockConversationView.swift b/Signal/src/views/MockConversationView.swift index 9d389d6c2f..3494513559 100644 --- a/Signal/src/views/MockConversationView.swift +++ b/Signal/src/views/MockConversationView.swift @@ -4,8 +4,16 @@ import Foundation +protocol MockConversationDelegate: class { + var mockConversationViewWidth: CGFloat { get } +} + +// MARK: - + class MockConversationView: UIView { + weak var delegate: MockConversationDelegate? + let hasWallpaper: Bool enum MockItem { @@ -43,6 +51,13 @@ class MockConversationView: UIView { fatalError("init(coder:) has not been implemented") } + @objc + public override func didMoveToSuperview() { + super.didMoveToSuperview() + + update() + } + private func setup() { if !hasWallpaper { backgroundColor = Theme.backgroundColor } @@ -86,10 +101,19 @@ class MockConversationView: UIView { reset() - let mockViewWidth = UIScreen.main.bounds.size.smallerAxis - let viewWidth = (bounds.size.width > 0 - ? bounds.size.width - : mockViewWidth) + guard let delegate = self.delegate else { + return + } + // We create our contents using the size of this view. + // The wrinkle is that this view is often embedded within + // a UITableView that will measure the contents of this + // view (it's cell) before this view & its cell have been + // displayed, when they still have zero width. Therefore + // we need to consult our delegate for the expected width. + let viewWidth = delegate.mockConversationViewWidth + guard viewWidth > 0 else { + return + } var renderItems = [CVRenderItem]() databaseStorage.uiRead { transaction in diff --git a/SignalMessaging/ViewControllers/OWSTableViewController.m b/SignalMessaging/ViewControllers/OWSTableViewController.m index 3af30091b6..6b509e70a2 100644 --- a/SignalMessaging/ViewControllers/OWSTableViewController.m +++ b/SignalMessaging/ViewControllers/OWSTableViewController.m @@ -659,6 +659,19 @@ NSString *const kOWSTableCellIdentifier = @"kOWSTableCellIdentifier"; [self configureTableLayoutMargins]; [self applyContents]; [self applyTheme]; + + // Reload when dynamic type settings change. + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(uiContentSizeCategoryDidChange:) + name:UIContentSizeCategoryDidChangeNotification + object:nil]; +} + +- (void)uiContentSizeCategoryDidChange:(NSNotification *)notification +{ + OWSAssertIsOnMainThread(); + + [self applyContents]; } - (void)viewWillAppear:(BOOL)animated diff --git a/SignalMessaging/ViewControllers/OWSTableViewController2.swift b/SignalMessaging/ViewControllers/OWSTableViewController2.swift index 30cd05e2a5..7e1e5d2086 100644 --- a/SignalMessaging/ViewControllers/OWSTableViewController2.swift +++ b/SignalMessaging/ViewControllers/OWSTableViewController2.swift @@ -34,7 +34,7 @@ open class OWSTableViewController2: OWSViewController { } @objc - public let tableView = UITableView(frame: .zero, style: .grouped) + public let tableView = OWSTableView(frame: .zero, style: .grouped) // This is an alternative to/replacement for UITableView.tableHeaderView. // @@ -102,6 +102,8 @@ open class OWSTableViewController2: OWSViewController { // We also do this in applyTheme(), but we also need to do it here // for the case where we push multiple table views at the same time. navigationItem.backBarButtonItem = .init(title: " ", style: .plain, target: nil, action: nil) + + tableView.tableViewDelegate = self } open override func viewDidLoad() { @@ -172,6 +174,19 @@ open class OWSTableViewController2: OWSViewController { applyContents() applyTheme() + + // Reload when dynamic type settings change. + NotificationCenter.default.addObserver(self, + selector: #selector(contentSizeCategoryDidChange), + name: UIContentSizeCategory.didChangeNotification, + object: nil) + } + + @objc + private func contentSizeCategoryDidChange(_ notification: Notification) { + Logger.debug("") + + applyContents() } open override func viewWillAppear(_ animated: Bool) { @@ -219,6 +234,10 @@ open class OWSTableViewController2: OWSViewController { self.title = title } + let shouldReload = (shouldReload && + self.isViewLoaded && + tableView.width > 0) + if shouldReload { tableView.reloadData() } } @@ -789,7 +808,7 @@ extension OWSTableViewController2: UITableViewDataSource, UITableViewDelegate { super.themeDidChange() - tableView.reloadData() + applyContents() } @objc @@ -1002,18 +1021,18 @@ extension OWSTableViewController2: UITableViewDataSource, UITableViewDelegate { // transition occurs. For iPhone, this moment is _during_ the // transition. We reload in the right places accordingly. if UIDevice.current.isIPad { - tableView.reloadData() + applyContents() } coordinator.animate { [weak self] _ in - self?.tableView.reloadData() + self?.applyContents() } completion: { [weak self] _ in - self?.tableView.reloadData() + self?.applyContents() } } public override func viewSafeAreaInsetsDidChange() { - tableView.reloadData() + applyContents() } } @@ -1028,3 +1047,42 @@ public extension UITableViewCell { backgroundView.autoPinEdgesToSuperviewEdges() } } + +// MARK: - + +extension OWSTableViewController2: OWSTableViewDelegate { + func tableViewDidChangeWidth() { + applyContents() + } +} + +// MARK: - + +private protocol OWSTableViewDelegate: class { + func tableViewDidChangeWidth() +} + +// MARK: - + +@objc +public class OWSTableView: UITableView { + fileprivate weak var tableViewDelegate: OWSTableViewDelegate? + + public override var frame: CGRect { + didSet { + let didChangeWidth = frame.width != oldValue.width + if didChangeWidth { + tableViewDelegate?.tableViewDidChangeWidth() + } + } + } + + public override var bounds: CGRect { + didSet { + let didChangeWidth = bounds.width != oldValue.width + if didChangeWidth { + tableViewDelegate?.tableViewDidChangeWidth() + } + } + } +}