diff --git a/iOS/Article/ArticleViewController.swift b/iOS/Article/ArticleViewController.swift index f58a490ab..6009f6ff1 100644 --- a/iOS/Article/ArticleViewController.swift +++ b/iOS/Article/ArticleViewController.swift @@ -149,9 +149,6 @@ class ArticleViewController: UIViewController, MainControllerIdentifiable { articleExtractorButton.buttonState = controller.articleExtractorButtonState self.pageViewController.setViewControllers([controller], direction: .forward, animated: false, completion: nil) - if AppDefaults.shared.articleFullscreenEnabled { - controller.hideBars() - } // Search bar searchBar.translatesAutoresizingMaskIntoConstraints = false @@ -166,14 +163,13 @@ class ArticleViewController: UIViewController, MainControllerIdentifiable { override func viewWillAppear(_ animated: Bool) { navigationController?.isToolbarHidden = false + if AppDefaults.shared.articleFullscreenEnabled { + currentWebViewController?.hideBars() + } + super.viewWillAppear(animated) } - override func viewDidAppear(_ animated: Bool) { - super.viewDidAppear(true) - coordinator.isArticleViewControllerPending = false - } - override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) if searchBar != nil && !searchBar.isHidden { diff --git a/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeader.swift b/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeader.swift index a2aff10d4..9451a3539 100644 --- a/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeader.swift +++ b/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeader.swift @@ -62,8 +62,6 @@ class MasterFeedTableViewSectionHeader: UITableViewHeaderFooterView { return label }() - private let unreadCountView = MasterFeedUnreadCountView(frame: CGRect.zero) - private lazy var disclosureButton: UIButton = { let button = NonIntrinsicButton() button.tintColor = AppAssets.secondaryAccentColor @@ -97,7 +95,7 @@ class MasterFeedTableViewSectionHeader: UITableViewHeaderFooterView { } override func sizeThatFits(_ size: CGSize) -> CGSize { - let layout = MasterFeedTableViewSectionHeaderLayout(cellWidth: size.width, insets: safeAreaInsets, label: titleView, unreadCountView: unreadCountView) + let layout = MasterFeedTableViewSectionHeaderLayout(cellWidth: size.width, insets: safeAreaInsets, label: titleView) return CGSize(width: bounds.width, height: layout.height) } @@ -106,8 +104,7 @@ class MasterFeedTableViewSectionHeader: UITableViewHeaderFooterView { super.layoutSubviews() let layout = MasterFeedTableViewSectionHeaderLayout(cellWidth: contentView.bounds.size.width, insets: contentView.safeAreaInsets, - label: titleView, - unreadCountView: unreadCountView) + label: titleView) layoutWith(layout) } @@ -157,7 +154,6 @@ private extension MasterFeedTableViewSectionHeader { func layoutWith(_ layout: MasterFeedTableViewSectionHeaderLayout) { titleView.setFrameIfNotEqual(layout.titleRect) - unreadCountView.setFrameIfNotEqual(layout.unreadCountRect) disclosureButton.setFrameIfNotEqual(layout.disclosureButtonRect) let top = CGRect(x: safeAreaInsets.left, y: 0, width: frame.width - safeAreaInsets.right - safeAreaInsets.left, height: 0.33) diff --git a/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeaderLayout.swift b/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeaderLayout.swift index 60748bb82..73dce3f69 100644 --- a/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeaderLayout.swift +++ b/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeaderLayout.swift @@ -12,19 +12,17 @@ import RSCore struct MasterFeedTableViewSectionHeaderLayout { private static let labelMarginRight = CGFloat(integerLiteral: 8) - private static let unreadCountMarginRight = CGFloat(integerLiteral: 0) private static let disclosureButtonSize = CGSize(width: 44, height: 44) private static let verticalPadding = CGFloat(integerLiteral: 11) private static let minRowHeight = CGFloat(integerLiteral: 44) let titleRect: CGRect - let unreadCountRect: CGRect let disclosureButtonRect: CGRect let height: CGFloat - init(cellWidth: CGFloat, insets: UIEdgeInsets, label: UILabel, unreadCountView: MasterFeedUnreadCountView) { + init(cellWidth: CGFloat, insets: UIEdgeInsets, label: UILabel) { let bounds = CGRect(x: insets.left, y: 0.0, width: floor(cellWidth - insets.right), height: 0.0) @@ -33,35 +31,20 @@ struct MasterFeedTableViewSectionHeaderLayout { rDisclosure.size = MasterFeedTableViewSectionHeaderLayout.disclosureButtonSize rDisclosure.origin.x = bounds.maxX - rDisclosure.size.width - // Unread Count - let unreadCountSize = unreadCountView.contentSize - let unreadCountIsHidden = unreadCountView.unreadCount < 1 - - var rUnread = CGRect.zero - if !unreadCountIsHidden { - rUnread.size = unreadCountSize - rUnread.origin.x = bounds.maxX - (MasterFeedTableViewSectionHeaderLayout.unreadCountMarginRight + unreadCountSize.width + rDisclosure.size.width) - } - - // Max Unread Count - // We can't reload Section Headers so we don't let the title extend into the (probably) worse case Unread Count area. - let maxUnreadCountView = MasterFeedUnreadCountView(frame: CGRect.zero) - maxUnreadCountView.unreadCount = 888 - let maxUnreadCountSize = maxUnreadCountView.contentSize // Title let rLabelx = 15.0 let rLabely = UIFontMetrics.default.scaledValue(for: MasterFeedTableViewSectionHeaderLayout.verticalPadding) var labelWidth = CGFloat.zero - labelWidth = cellWidth - (rLabelx + MasterFeedTableViewSectionHeaderLayout.labelMarginRight + maxUnreadCountSize.width + MasterFeedTableViewSectionHeaderLayout.unreadCountMarginRight) + labelWidth = cellWidth - (rLabelx + MasterFeedTableViewSectionHeaderLayout.labelMarginRight) let labelSizeInfo = MultilineUILabelSizer.size(for: label.text ?? "", font: label.font, numberOfLines: 0, width: Int(floor(labelWidth))) var rLabel = CGRect(x: rLabelx, y: rLabely, width: labelWidth, height: labelSizeInfo.size.height) // Determine cell height let paddedLabelHeight = rLabel.maxY + UIFontMetrics.default.scaledValue(for: MasterFeedTableViewSectionHeaderLayout.verticalPadding) - let maxGraphicsHeight = [rUnread, rDisclosure].maxY() + let maxGraphicsHeight = [rDisclosure].maxY() var cellHeight = max(paddedLabelHeight, maxGraphicsHeight) if cellHeight < MasterFeedTableViewSectionHeaderLayout.minRowHeight { cellHeight = MasterFeedTableViewSectionHeaderLayout.minRowHeight @@ -69,9 +52,6 @@ struct MasterFeedTableViewSectionHeaderLayout { // Center in Cell let newBounds = CGRect(x: bounds.origin.x, y: bounds.origin.y, width: bounds.width, height: cellHeight) - if !unreadCountIsHidden { - rUnread = MasterFeedTableViewCellLayout.centerVertically(rUnread, newBounds) - } rDisclosure = MasterFeedTableViewCellLayout.centerVertically(rDisclosure, newBounds) // Small fonts need centered if we hit the minimum row height @@ -81,7 +61,6 @@ struct MasterFeedTableViewSectionHeaderLayout { // Assign the properties self.height = cellHeight - self.unreadCountRect = rUnread self.disclosureButtonRect = rDisclosure self.titleRect = rLabel diff --git a/iOS/MasterTimeline/MasterTimelineViewController.swift b/iOS/MasterTimeline/MasterTimelineViewController.swift index 6743e04e2..78e720341 100644 --- a/iOS/MasterTimeline/MasterTimelineViewController.swift +++ b/iOS/MasterTimeline/MasterTimelineViewController.swift @@ -17,11 +17,12 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner private var iconSize = IconSize.medium private lazy var feedTapGestureRecognizer = UITapGestureRecognizer(target: self, action:#selector(showFeedInspector(_:))) - private var refreshProgressView: RefreshProgressView? + private var filterButton: UIBarButtonItem! @IBOutlet weak var markAllAsReadButton: UIBarButtonItem! - private var filterButton: UIBarButtonItem! + private var refreshProgressView: RefreshProgressView! + private var refreshProgressItemButton: UIBarButtonItem! private var firstUnreadButton: UIBarButtonItem! private lazy var dataSource = makeDataSource() @@ -91,9 +92,15 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner refreshControl = UIRefreshControl() refreshControl!.addTarget(self, action: #selector(refreshAccounts(_:)), for: .valueChanged) + configureToolbar() configureNavbar() + + refreshProgressView = Bundle.main.loadNibNamed("RefreshProgressView", owner: self, options: nil)?[0] as? RefreshProgressView + refreshProgressItemButton = UIBarButtonItem(customView: refreshProgressView!) + + resetUI(resetScroll: true) // Load the table and then scroll to the saved position if available @@ -609,6 +616,7 @@ extension MasterTimelineViewController: UISearchBarDelegate { private extension MasterTimelineViewController { + func configureToolbar() { guard splitViewController?.isCollapsed ?? true else { return @@ -700,16 +708,9 @@ private extension MasterTimelineViewController { firstUnreadButton.isEnabled = coordinator.isTimelineUnreadAvailable if coordinator.isRootSplitCollapsed { - if let toolbarItems = toolbarItems, toolbarItems.last != firstUnreadButton { - var items = toolbarItems - items.append(firstUnreadButton) - setToolbarItems(items, animated: false) - } + setToolbarItems([markAllAsReadButton, .flexibleSpace(), refreshProgressItemButton, .flexibleSpace(), firstUnreadButton], animated: false) } else { - if let toolbarItems = toolbarItems, toolbarItems.last == firstUnreadButton { - let items = Array(toolbarItems[0..? = nil - var isArticleViewControllerPending = false - private(set) var sortDirection = AppDefaults.shared.timelineSortDirection { didSet { if sortDirection != oldValue { @@ -297,6 +295,9 @@ class SceneCoordinator: NSObject, UndoableCommandRunner { self.articleViewController = rootSplitViewController.viewController(for: .secondary) as? ArticleViewController self.articleViewController?.coordinator = self + if let navController = self.articleViewController?.navigationController { + configureNavigationController(navController) + } for sectionNode in treeController.rootNode.childNodes { markExpanded(sectionNode) @@ -1339,14 +1340,19 @@ extension SceneCoordinator: UINavigationControllerDelegate { // Don't clear it if we have pushed an ArticleViewController, but don't yet see it on the navigation stack. // This happens when we are going to the next unread and we need to grab another timeline to continue. The // ArticleViewController will be pushed, but we will briefly show the Timeline. Don't clear things out when that happens. - if viewController === masterTimelineViewController && lastMainControllerToAppear == .article && !isArticleViewControllerPending { + if viewController === masterTimelineViewController && lastMainControllerToAppear == .article { currentArticle = nil masterTimelineViewController?.updateArticleSelection(animations: [.scroll, .select, .navigation]) activityManager.invalidateReading() // Restore any bars hidden by the article controller showStatusBar() - navigationController.setNavigationBarHidden(false, animated: true) + + // We delay the showing of the navigation bars because it freaks out on iOS 15 with the new split view controller + // if it is trying to show at the same time as the show timeline animation + DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { + navigationController.setNavigationBarHidden(false, animated: true) + } navigationController.setToolbarHidden(false, animated: true) return }