diff --git a/Modules/Sources/WordPressUI/Extensions/UIButton+Extensions.swift b/Modules/Sources/WordPressUI/Extensions/UIButton+Extensions.swift new file mode 100644 index 000000000000..4c7b6581fb84 --- /dev/null +++ b/Modules/Sources/WordPressUI/Extensions/UIButton+Extensions.swift @@ -0,0 +1,14 @@ +import UIKit + +extension UIButton.Configuration { + public static func primary() -> UIButton.Configuration { + var configuration = UIButton.Configuration.borderedProminent() + configuration.titleTextAttributesTransformer = .init { attributes in + var attributes = attributes + attributes.font = UIFont.preferredFont(forTextStyle: .headline) + return attributes + } + configuration.buttonSize = .large + return configuration + } +} diff --git a/Modules/Sources/WordPressUI/Views/BottomToolbarView.swift b/Modules/Sources/WordPressUI/Views/BottomToolbarView.swift new file mode 100644 index 000000000000..14a7bb96c38e --- /dev/null +++ b/Modules/Sources/WordPressUI/Views/BottomToolbarView.swift @@ -0,0 +1,86 @@ +import UIKit +import Combine + +/// A custom bottom toolbar implementation that, unlike the native toolbar, +/// can accommodate larger buttons but shares a lot of its behavior including +/// edge appearance. +public class BottomToolbarView: UIView { + private let separator = SeparatorView.horizontal() + private let effectView = UIVisualEffectView() + private var isEdgeAppearanceEnabled = false + private weak var scrollView: UIScrollView? + private var cancellable: AnyCancellable? + + public let contentView = UIView() + + public override init(frame: CGRect) { + super.init(frame: frame) + + addSubview(effectView) + addSubview(separator) + + separator.pinEdges([.top, .horizontal]) + effectView.pinEdges() + + effectView.contentView.addSubview(contentView) + + contentView.pinEdges(to: effectView.contentView.safeAreaLayoutGuide, insets: UIEdgeInsets(.all, 20)) + } + + public required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + public override func layoutSubviews() { + super.layoutSubviews() + + updateScrollViewContentInsets() + } + + public override func safeAreaInsetsDidChange() { + super.safeAreaInsetsDidChange() + + updateScrollViewContentInsets() + } + + /// - warning: If you use this view, you'll typically need to take over the + /// scroll view content inset adjustment. + public func configure(in viewController: UIViewController, scrollView: UIScrollView) { + viewController.view.addSubview(self) + pinEdges([.horizontal, .bottom]) + self.scrollView = scrollView + + cancellable = scrollView.publisher(for: \.contentOffset, options: [.new]).sink { [weak self] offset in + self?.updateEdgeAppearance(animated: true) + } + updateScrollViewContentInsets() + updateEdgeAppearance(animated: false) + } + + private func updateEdgeAppearance(animated: Bool) { + guard let scrollView, let superview else { return } + + let isContentOverlapping = superview.convert(scrollView.contentLayoutGuide.layoutFrame, from: scrollView).maxY > (frame.minY + 16) + setEdgeAppearanceEnabled(!isContentOverlapping, animated: animated) + } + + private func setEdgeAppearanceEnabled(_ isEnabled: Bool, animated: Bool) { + guard isEdgeAppearanceEnabled != isEnabled else { return } + isEdgeAppearanceEnabled = isEnabled + + UIView.animate(withDuration: animated ? 0 : 0.33, delay: 0.0, options: [.allowUserInteraction, .beginFromCurrentState]) { + self.effectView.effect = isEnabled ? nil : UIBlurEffect(style: .extraLight) + self.separator.alpha = isEnabled ? 0 : 1 + } + } + + // The toolbar does no extend the safe area because it itself depends on it, + // so it resorts to changing `contentInset` instead. + private func updateScrollViewContentInsets() { + guard let scrollView else { return } + let bottomInset = bounds.height - safeAreaInsets.bottom + if scrollView.contentInset.bottom != bottomInset { + scrollView.contentInset.bottom = bottomInset + } + } +} diff --git a/Modules/Sources/WordPressUI/Views/SeparatorView.swift b/Modules/Sources/WordPressUI/Views/SeparatorView.swift new file mode 100644 index 000000000000..8d0d8b888ddb --- /dev/null +++ b/Modules/Sources/WordPressUI/Views/SeparatorView.swift @@ -0,0 +1,25 @@ +import UIKit + +public final class SeparatorView: UIView { + public static func horizontal() -> SeparatorView { + let view = SeparatorView() + view.heightAnchor.constraint(equalToConstant: 0.5).isActive = true + return view + } + + public static func vertical() -> SeparatorView { + let view = SeparatorView() + view.widthAnchor.constraint(equalToConstant: 0.5).isActive = true + return view + } + + public override init(frame: CGRect) { + super.init(frame: frame) + + backgroundColor = .separator + } + + public required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} diff --git a/Modules/Sources/WordPressUI/Views/Settings/Experimental Features/ExperimentalFeaturesList.swift b/Modules/Sources/WordPressUI/Views/Settings/ExperimentalFeatures/ExperimentalFeaturesList.swift similarity index 100% rename from Modules/Sources/WordPressUI/Views/Settings/Experimental Features/ExperimentalFeaturesList.swift rename to Modules/Sources/WordPressUI/Views/Settings/ExperimentalFeatures/ExperimentalFeaturesList.swift diff --git a/Modules/Sources/WordPressUI/Views/Settings/Experimental Features/ExperimentalFeaturesViewModel.swift b/Modules/Sources/WordPressUI/Views/Settings/ExperimentalFeatures/ExperimentalFeaturesViewModel.swift similarity index 100% rename from Modules/Sources/WordPressUI/Views/Settings/Experimental Features/ExperimentalFeaturesViewModel.swift rename to Modules/Sources/WordPressUI/Views/Settings/ExperimentalFeatures/ExperimentalFeaturesViewModel.swift diff --git a/Modules/Sources/WordPressUI/Views/Settings/Experimental Features/Feature.swift b/Modules/Sources/WordPressUI/Views/Settings/ExperimentalFeatures/Feature.swift similarity index 100% rename from Modules/Sources/WordPressUI/Views/Settings/Experimental Features/Feature.swift rename to Modules/Sources/WordPressUI/Views/Settings/ExperimentalFeatures/Feature.swift diff --git a/Modules/Sources/WordPressUI/Views/SpacerView.swift b/Modules/Sources/WordPressUI/Views/SpacerView.swift new file mode 100644 index 000000000000..2dd3e6bd46d6 --- /dev/null +++ b/Modules/Sources/WordPressUI/Views/SpacerView.swift @@ -0,0 +1,54 @@ +import UIKit + +public final class SpacerView: UIView { + public convenience init(minWidth: CGFloat) { + self.init() + + widthAnchor.constraint(greaterThanOrEqualToConstant: minWidth).isActive = true + } + + public convenience init(minHeight: CGFloat) { + self.init() + + heightAnchor.constraint(greaterThanOrEqualToConstant: minHeight).isActive = true + } + + public convenience init(width: CGFloat) { + self.init() + + widthAnchor.constraint(equalToConstant: width).isActive = true + } + + public convenience init(height: CGFloat) { + self.init() + + heightAnchor.constraint(equalToConstant: height).isActive = true + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + + // Make sure it compresses or expands before any other views if needed. + setContentCompressionResistancePriority(.init(10), for: .horizontal) + setContentCompressionResistancePriority(.init(10), for: .vertical) + setContentHuggingPriority(.init(10), for: .horizontal) + setContentHuggingPriority(.init(10), for: .vertical) + } + + public override var intrinsicContentSize: CGSize { + CGSizeMake(0, 0) // Avoid ambiguous layout + } + + public required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + override public class var layerClass: AnyClass { + CATransformLayer.self // Draws nothing + } + + override public var backgroundColor: UIColor? { + get { return nil } + set { /* Do nothing */ } + } +} diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index 14842c841edb..e66b9081a057 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -3,6 +3,7 @@ * [**] Add new lightbox screen for images with modern transitions and enhanced performance [#23922] * [*] Add prefetching to Reader streams [#23928] * [*] Fix an issue with blogging reminders prompt not being shown after publishing a new post [#23930] +* [*] Fix transitions in Blogging Reminders flow, improve accessibiliy, add close buttons [#23931] 25.6 ----- diff --git a/WordPress/Classes/Utility/Blogging Reminders/BloggingRemindersScheduler.swift b/WordPress/Classes/Utility/Blogging Reminders/BloggingRemindersScheduler.swift index d083a0e054e6..63c31026a227 100644 --- a/WordPress/Classes/Utility/Blogging Reminders/BloggingRemindersScheduler.swift +++ b/WordPress/Classes/Utility/Blogging Reminders/BloggingRemindersScheduler.swift @@ -17,7 +17,7 @@ extension InteractiveNotificationsManager: PushNotificationAuthorizer { /// Main interface for scheduling blogging reminders /// -class BloggingRemindersScheduler { +final class BloggingRemindersScheduler { // MARK: - Convenience Typealiases diff --git a/WordPress/Classes/Utility/Spotlight/SearchManager.swift b/WordPress/Classes/Utility/Spotlight/SearchManager.swift index eeb41704e412..52f20c19f3be 100644 --- a/WordPress/Classes/Utility/Spotlight/SearchManager.swift +++ b/WordPress/Classes/Utility/Spotlight/SearchManager.swift @@ -458,7 +458,7 @@ fileprivate extension SearchManager { let controller = PreviewWebKitViewController(post: apost, source: "spotlight_preview_post") controller.trackOpenEvent() - let navWrapper = LightNavigationController(rootViewController: controller) + let navWrapper = UINavigationController(rootViewController: controller) let rootViewController = RootViewCoordinator.sharedPresenter.rootViewController if rootViewController.traitCollection.userInterfaceIdiom == .pad { navWrapper.modalPresentationStyle = .fullScreen diff --git a/WordPress/Classes/ViewRelated/Blog/Blog Details/BlogDetailsViewController.m b/WordPress/Classes/ViewRelated/Blog/Blog Details/BlogDetailsViewController.m index ab41fbca01b8..33a2f1bca520 100644 --- a/WordPress/Classes/ViewRelated/Blog/Blog Details/BlogDetailsViewController.m +++ b/WordPress/Classes/ViewRelated/Blog/Blog Details/BlogDetailsViewController.m @@ -1939,7 +1939,7 @@ - (void)showViewSiteFromSource:(BlogDetailsNavigationSource)source source:@"my_site_view_site" withDeviceModes:true onClose:nil]; - LightNavigationController *navController = [[LightNavigationController alloc] initWithRootViewController:webViewController]; + UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:webViewController]; if (self.traitCollection.userInterfaceIdiom == UIUserInterfaceIdiomPad) { navController.modalPresentationStyle = UIModalPresentationFullScreen; } diff --git a/Modules/Sources/WordPressUI/Components/RestApiUpgradePrompt.swift b/WordPress/Classes/ViewRelated/Blog/Blog Details/Views/RestApiUpgradePrompt.swift similarity index 93% rename from Modules/Sources/WordPressUI/Components/RestApiUpgradePrompt.swift rename to WordPress/Classes/ViewRelated/Blog/Blog Details/Views/RestApiUpgradePrompt.swift index 7b6160afff0c..a276f9a5fd18 100644 --- a/Modules/Sources/WordPressUI/Components/RestApiUpgradePrompt.swift +++ b/WordPress/Classes/ViewRelated/Blog/Blog Details/Views/RestApiUpgradePrompt.swift @@ -1,3 +1,5 @@ +import UIKit +import WordPressUI import SwiftUI public struct RestApiUpgradePrompt: View { @@ -40,9 +42,3 @@ public struct RestApiUpgradePrompt: View { } } } - -#Preview { - RestApiUpgradePrompt(localizedFeatureName: "User Management") { - debugPrint("Tapped Get Started") - } -} diff --git a/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/BloggingRemindersAnimator.swift b/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/BloggingRemindersAnimator.swift deleted file mode 100644 index 978538eef3dc..000000000000 --- a/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/BloggingRemindersAnimator.swift +++ /dev/null @@ -1,67 +0,0 @@ -/// A transition animator that moves in the pushed view controller horizontally. -/// Does not handle the pop animation since the BloggingReminders setup flow does not allow to navigate back. -class BloggingRemindersAnimator: NSObject, UIViewControllerAnimatedTransitioning { - - var popStyle = false - - private static let animationDuration: TimeInterval = 0.2 - private static let sourceEndFrameOffset: CGFloat = -60.0 - - func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { - return Self.animationDuration - } - - func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { - - guard !popStyle else { - animatePop(using: transitionContext) - return - } - - guard let sourceViewController = - transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from), - let destinationViewController = - transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) else { - return - } - // final position of the destination view - let destinationEndFrame = transitionContext.finalFrame(for: destinationViewController) - // final position of the source view - let sourceEndFrame = transitionContext.initialFrame(for: sourceViewController).offsetBy(dx: Self.sourceEndFrameOffset, dy: .zero) - - // initial position of the destination view - let destinationStartFrame = destinationEndFrame.offsetBy(dx: destinationEndFrame.width, dy: .zero) - destinationViewController.view.frame = destinationStartFrame - - transitionContext.containerView.insertSubview(destinationViewController.view, aboveSubview: sourceViewController.view) - - UIView.animate(withDuration: transitionDuration(using: transitionContext), - animations: { - destinationViewController.view.frame = destinationEndFrame - sourceViewController.view.frame = sourceEndFrame - }, completion: {_ in - transitionContext.completeTransition(true) - }) - } - - func animatePop(using transitionContext: UIViewControllerContextTransitioning) { - guard let sourceViewController = - transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from), - let destinationViewController = - transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) else { - return - } - let destinationEndFrame = transitionContext.finalFrame(for: destinationViewController) - let destinationStartFrame = destinationEndFrame.offsetBy(dx: Self.sourceEndFrameOffset, dy: .zero) - destinationViewController.view.frame = destinationStartFrame - transitionContext.containerView.insertSubview(destinationViewController.view, belowSubview: sourceViewController.view) - - UIView.animate(withDuration: transitionDuration(using: transitionContext), - animations: { - destinationViewController.view.frame = destinationEndFrame - sourceViewController.view.transform = sourceViewController.view.transform.translatedBy(x: sourceViewController.view.frame.width, y: 0) - }, completion: {_ in - transitionContext.completeTransition(true) - }) - } -} diff --git a/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/BloggingRemindersFlow.swift b/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/BloggingRemindersFlow.swift deleted file mode 100644 index 582380d5db83..000000000000 --- a/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/BloggingRemindersFlow.swift +++ /dev/null @@ -1,87 +0,0 @@ -import Foundation -import WordPressUI - -class BloggingRemindersFlow { - - typealias DismissClosure = () -> Void - - static func present(from viewController: UIViewController, - for blog: Blog, - source: BloggingRemindersTracker.FlowStartSource, - alwaysShow: Bool = true, - delegate: BloggingRemindersFlowDelegate? = nil, - onDismiss: DismissClosure? = nil) { - - guard blog.areBloggingRemindersAllowed() else { - return - } - - guard alwaysShow || !hasShownWeeklyRemindersFlow(for: blog) else { - return - } - - let blogType: BloggingRemindersTracker.BlogType = blog.isHostedAtWPcom ? .wpcom : .selfHosted - - let tracker = BloggingRemindersTracker(blogType: blogType) - tracker.flowStarted(source: source) - - let flowStartViewController = makeStartViewController(for: blog, - tracker: tracker, - source: source, - delegate: delegate) - let navigationController = BloggingRemindersNavigationController( - rootViewController: flowStartViewController, - onDismiss: { - NoticesDispatch.unlock() - onDismiss?() - }) - - let bottomSheet = BottomSheetViewController(childViewController: navigationController, - customHeaderSpacing: 0) - - NoticesDispatch.lock() - bottomSheet.show(from: viewController) - setHasShownWeeklyRemindersFlow(for: blog) - } - - /// if the flow has never been seen, it starts with the intro. Otherwise it starts with the calendar settings - private static func makeStartViewController(for blog: Blog, - tracker: BloggingRemindersTracker, - source: BloggingRemindersTracker.FlowStartSource, - delegate: BloggingRemindersFlowDelegate? = nil) -> UIViewController { - - guard hasShownWeeklyRemindersFlow(for: blog) else { - return BloggingRemindersFlowIntroViewController(for: blog, - tracker: tracker, - source: source, - delegate: delegate) - } - - return (try? BloggingRemindersFlowSettingsViewController(for: blog, tracker: tracker, delegate: delegate)) ?? - BloggingRemindersFlowIntroViewController(for: blog, tracker: tracker, source: source, delegate: delegate) - } - - // MARK: - Weekly reminders flow presentation status - // - // stores a key for each blog in UserDefaults to determine if - // the flow was presented for the given blog. - private static func hasShownWeeklyRemindersFlow(for blog: Blog) -> Bool { - UserPersistentStoreFactory.instance().bool(forKey: weeklyRemindersKey(for: blog)) - } - - static func setHasShownWeeklyRemindersFlow(for blog: Blog) { - UserPersistentStoreFactory.instance().set(true, forKey: weeklyRemindersKey(for: blog)) - } - - private static func weeklyRemindersKey(for blog: Blog) -> String { - // weekly reminders key prefix - let prefix = "blogging-reminder-weekly-" - return prefix + blog.objectID.uriRepresentation().absoluteString - } - - /// By making this private we ensure this can't be instantiated. - /// - private init() { - assertionFailure() - } -} diff --git a/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/BloggingRemindersFlowIntroViewController.swift b/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/BloggingRemindersFlowIntroViewController.swift deleted file mode 100644 index 36666edd5eb8..000000000000 --- a/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/BloggingRemindersFlowIntroViewController.swift +++ /dev/null @@ -1,203 +0,0 @@ -import UIKit -import WordPressUI - -class BloggingRemindersFlowIntroViewController: UIViewController { - - // MARK: - Subviews - - private let stackView: UIStackView = { - let stackView = UIStackView() - stackView.translatesAutoresizingMaskIntoConstraints = false - stackView.spacing = Metrics.stackSpacing - stackView.axis = .vertical - stackView.alignment = .center - stackView.distribution = .equalSpacing - return stackView - }() - - private let imageView: UIImageView = { - let imageView = UIImageView(image: UIImage(named: Images.celebrationImageName)) - imageView.translatesAutoresizingMaskIntoConstraints = false - imageView.tintColor = .systemYellow - return imageView - }() - - private let titleLabel: UILabel = { - let label = UILabel() - label.adjustsFontForContentSizeCategory = true - label.adjustsFontSizeToFitWidth = true - label.font = WPStyleGuide.serifFontForTextStyle(.title1, fontWeight: .semibold) - label.numberOfLines = 2 - label.textAlignment = .center - label.text = Strings.introTitle - return label - }() - - private let promptLabel: UILabel = { - let label = UILabel() - label.adjustsFontForContentSizeCategory = true - label.adjustsFontSizeToFitWidth = true - label.font = .preferredFont(forTextStyle: .body) - label.numberOfLines = 5 - label.textAlignment = .center - return label - }() - - private lazy var getStartedButton: UIButton = { - let button = FancyButton() - button.isPrimary = true - button.setTitle(Strings.introButtonTitle, for: .normal) - button.addTarget(self, action: #selector(getStartedTapped), for: .touchUpInside) - return button - }() - - // MARK: - Initializers - - private let blog: Blog - private let tracker: BloggingRemindersTracker - private let source: BloggingRemindersTracker.FlowStartSource - private weak var delegate: BloggingRemindersFlowDelegate? - - init(for blog: Blog, - tracker: BloggingRemindersTracker, - source: BloggingRemindersTracker.FlowStartSource, - delegate: BloggingRemindersFlowDelegate? = nil) { - self.blog = blog - self.tracker = tracker - self.source = source - self.delegate = delegate - - super.init(nibName: nil, bundle: nil) - } - - required init?(coder: NSCoder) { - // This VC is designed to be instantiated programmatically. If we ever need to initialize this VC - // from a coder, we can implement support for it - but I don't think it's necessary right now. - // - diegoreymendez - fatalError("Use init(tracker:) instead") - } - - // MARK: - View Lifecycle - - override func viewDidLoad() { - super.viewDidLoad() - - view.backgroundColor = .systemBackground - - configureStackView() - configureConstraints() - promptLabel.text = Strings.introDescription - } - - override func viewDidAppear(_ animated: Bool) { - tracker.screenShown(.main) - - super.viewDidAppear(animated) - } - - override func viewDidDisappear(_ animated: Bool) { - super.viewDidDisappear(animated) - - // If a parent VC is being dismissed, and this is the last view shown in its navigation controller, we'll assume - // the flow was interrupted. - if isBeingDismissedDirectlyOrByAncestor() && navigationController?.viewControllers.last == self { - tracker.flowDismissed(source: .main) - } - } - - override func viewDidLayoutSubviews() { - super.viewDidLayoutSubviews() - calculatePreferredContentSize() - } - - private func calculatePreferredContentSize() { - let size = CGSize(width: view.bounds.width, height: UIView.layoutFittingCompressedSize.height) - preferredContentSize = view.systemLayoutSizeFitting(size) - } - - override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { - super.traitCollectionDidChange(previousTraitCollection) - - view.setNeedsLayout() - } - - // MARK: - View Configuration - - private func configureStackView() { - view.addSubview(stackView) - stackView.addArrangedSubviews([ - imageView, - titleLabel, - promptLabel, - getStartedButton - ]) - stackView.setCustomSpacing(Metrics.afterPromptSpacing, after: promptLabel) - } - - private func configureConstraints() { - NSLayoutConstraint.activate([ - stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: Metrics.edgeMargins.left), - stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -Metrics.edgeMargins.right), - stackView.topAnchor.constraint(equalTo: view.topAnchor, constant: Metrics.edgeMargins.top), - stackView.bottomAnchor.constraint(lessThanOrEqualTo: view.safeBottomAnchor, constant: -Metrics.edgeMargins.bottom), - - getStartedButton.heightAnchor.constraint(greaterThanOrEqualToConstant: Metrics.getStartedButtonHeight), - getStartedButton.widthAnchor.constraint(equalTo: stackView.widthAnchor), - ]) - } - - @objc private func getStartedTapped() { - tracker.buttonPressed(button: .continue, screen: .main) - - do { - let flowSettingsViewController = try BloggingRemindersFlowSettingsViewController(for: blog, tracker: tracker, delegate: delegate) - - navigationController?.pushViewController(flowSettingsViewController, animated: true) - } catch { - DDLogError("Could not instantiate the blogging reminders settings VC: \(error.localizedDescription)") - dismiss(animated: true, completion: nil) - } - } -} - -extension BloggingRemindersFlowIntroViewController: BloggingRemindersActions { - - @objc private func dismissTapped() { - dismiss(from: .dismiss, screen: .main, tracker: tracker) - } -} - -// MARK: - DrawerPresentable - -extension BloggingRemindersFlowIntroViewController: DrawerPresentable { - var collapsedHeight: DrawerHeight { - return .intrinsicHeight - } -} - -// MARK: - ChildDrawerPositionable - -extension BloggingRemindersFlowIntroViewController: ChildDrawerPositionable { - var preferredDrawerPosition: DrawerPosition { - return .collapsed - } -} - -// MARK: - Constants - -private enum Strings { - static let introTitle = NSLocalizedString("bloggingRemindersPrompt.intro.title", value: "Blogging Reminders", comment: "Title of the Blogging Reminders Settings screen.") - static let introDescription = NSLocalizedString("bloggingRemindersPrompt.intro.details", value: "Set up your blogging reminders on days you want to post.", comment: "Description on the first screen of the Blogging Reminders Settings flow called aftet post publishing.") - static let introButtonTitle = NSLocalizedString("bloggingRemindersPrompt.intro.continueButton", value: "Set reminders", comment: "Title of the set goals button in the Blogging Reminders Settings flow.") -} - -private enum Images { - static let celebrationImageName = "reminders-celebration" -} - -private enum Metrics { - static let edgeMargins = UIEdgeInsets(top: 46, left: 20, bottom: 20, right: 20) - static let stackSpacing: CGFloat = 20.0 - static let afterPromptSpacing: CGFloat = 24.0 - static let getStartedButtonHeight: CGFloat = 44.0 -} diff --git a/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/BloggingRemindersNavigationController.swift b/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/BloggingRemindersNavigationController.swift deleted file mode 100644 index df093f371e63..000000000000 --- a/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/BloggingRemindersNavigationController.swift +++ /dev/null @@ -1,123 +0,0 @@ -import UIKit -import WordPressUI - -protocol ChildDrawerPositionable { - var preferredDrawerPosition: DrawerPosition { get } -} - -class BloggingRemindersNavigationController: LightNavigationController { - - typealias DismissClosure = () -> Void - - private let onDismiss: DismissClosure? - - required init(rootViewController: UIViewController, onDismiss: DismissClosure? = nil) { - self.onDismiss = onDismiss - - super.init(rootViewController: rootViewController) - - delegate = self - setNavigationBarHidden(true, animated: false) - } - - required init?(coder aDecoder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override func viewDidDisappear(_ animated: Bool) { - super.viewDidDisappear(animated) - - if isBeingDismissedDirectlyOrByAncestor() { - onDismiss?() - } - } - - override var supportedInterfaceOrientations: UIInterfaceOrientationMask { - return .portrait - } - - override public var preferredContentSize: CGSize { - set { - viewControllers.last?.preferredContentSize = newValue - super.preferredContentSize = newValue - } - get { - guard let visibleViewController = viewControllers.last else { - return .zero - } - - return visibleViewController.preferredContentSize - } - } - - override func pushViewController(_ viewController: UIViewController, animated: Bool) { - super.pushViewController(viewController, animated: animated) - - updateDrawerPosition() - } - - override func popViewController(animated: Bool) -> UIViewController? { - let viewController = super.popViewController(animated: animated) - - updateDrawerPosition() - - return viewController - } - - private func updateDrawerPosition() { - if let bottomSheet = self.parent as? BottomSheetViewController, - let presentedVC = bottomSheet.presentedVC, - let currentVC = topViewController as? ChildDrawerPositionable { - presentedVC.transition(to: currentVC.preferredDrawerPosition) - } - } -} - -// MARK: - DrawerPresentable - -extension BloggingRemindersNavigationController: DrawerPresentable { - var allowsUserTransition: Bool { - return false - } - - var allowsDragToDismiss: Bool { - return true - } - - var allowsTapToDismiss: Bool { - return true - } - - var expandedHeight: DrawerHeight { - return .maxHeight - } - - var collapsedHeight: DrawerHeight { - if let viewController = viewControllers.last as? DrawerPresentable { - return viewController.collapsedHeight - } - - return .intrinsicHeight - } - - func handleDismiss() { - (children.last as? DrawerPresentable)?.handleDismiss() - } -} - -// MARK: - NavigationControllerDelegate - -extension BloggingRemindersNavigationController: UINavigationControllerDelegate { - - /// This implementation uses the custom `BloggingRemindersAnimator` to improve screen transitions - /// in the blogging reminders setup flow. - func navigationController(_ navigationController: UINavigationController, - animationControllerFor operation: UINavigationController.Operation, - from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? { - - let animator = BloggingRemindersAnimator() - animator.popStyle = (operation == .pop) - - return animator - } -} diff --git a/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/Time Selector/TimeSelectionViewController.swift b/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/Time Selector/TimeSelectionViewController.swift deleted file mode 100644 index 16305668ca88..000000000000 --- a/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/Time Selector/TimeSelectionViewController.swift +++ /dev/null @@ -1,86 +0,0 @@ -import UIKit -import WordPressUI - -class TimeSelectionViewController: UIViewController { - - var preferredWidth: CGFloat? - - private let scheduledTime: Date - - private let tracker: BloggingRemindersTracker - - private var onDismiss: ((Date) -> Void)? - - private lazy var timeSelectionView: TimeSelectionView = { - let view = TimeSelectionView(selectedTime: scheduledTime) - view.translatesAutoresizingMaskIntoConstraints = false - return view - }() - - init(scheduledTime: Date, tracker: BloggingRemindersTracker, onDismiss: ((Date) -> Void)? = nil) { - self.scheduledTime = scheduledTime - self.tracker = tracker - self.onDismiss = onDismiss - super.init(nibName: nil, bundle: nil) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override func loadView() { - let mainView = timeSelectionView - if let width = preferredWidth { - mainView.widthAnchor.constraint(equalToConstant: width).isActive = true - } - self.view = mainView - } - - override func viewDidLayoutSubviews() { - super.viewDidLayoutSubviews() - calculatePreferredSize() - } - - private func calculatePreferredSize() { - let targetSize = CGSize(width: view.bounds.width, - height: UIView.layoutFittingCompressedSize.height) - preferredContentSize = view.systemLayoutSizeFitting(targetSize) - navigationController?.preferredContentSize = preferredContentSize - } - - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - navigationController?.setNavigationBarHidden(false, animated: false) - } - - override func viewWillDisappear(_ animated: Bool) { - super.viewWillDisappear(animated) - navigationController?.setNavigationBarHidden(true, animated: false) - if isMovingFromParent { - onDismiss?(timeSelectionView.getDate()) - } - } - - override func viewDidDisappear(_ animated: Bool) { - super.viewDidDisappear(animated) - - // If a parent VC is being dismissed, and this is the last view shown in its navigation controller, we'll assume - // the flow was interrupted. - if isBeingDismissedDirectlyOrByAncestor() && navigationController?.viewControllers.last == self { - tracker.flowDismissed(source: .timePicker) - } - } -} - -// MARK: - DrawerPresentable -extension TimeSelectionViewController: DrawerPresentable { - var collapsedHeight: DrawerHeight { - return .intrinsicHeight - } -} - -extension TimeSelectionViewController: ChildDrawerPositionable { - var preferredDrawerPosition: DrawerPosition { - return .collapsed - } -} diff --git a/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/BloggingRemindersActions.swift b/WordPress/Classes/ViewRelated/Blog/BloggingReminders/BloggingRemindersActions.swift similarity index 97% rename from WordPress/Classes/ViewRelated/Blog/Blogging Reminders/BloggingRemindersActions.swift rename to WordPress/Classes/ViewRelated/Blog/BloggingReminders/BloggingRemindersActions.swift index b1105e99422a..22b0ac2d858b 100644 --- a/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/BloggingRemindersActions.swift +++ b/WordPress/Classes/ViewRelated/Blog/BloggingReminders/BloggingRemindersActions.swift @@ -1,3 +1,5 @@ +import UIKit + /// Conform to this protocol to implement common actions for the blogging reminders flow protocol BloggingRemindersActions: UIViewController { func dismiss(from button: BloggingRemindersTracker.Button, diff --git a/WordPress/Classes/ViewRelated/Blog/BloggingReminders/BloggingRemindersFlow.swift b/WordPress/Classes/ViewRelated/Blog/BloggingReminders/BloggingRemindersFlow.swift new file mode 100644 index 000000000000..361b0d81fb55 --- /dev/null +++ b/WordPress/Classes/ViewRelated/Blog/BloggingReminders/BloggingRemindersFlow.swift @@ -0,0 +1,84 @@ +import UIKit +import WordPressFlux +import WordPressUI + +final class BloggingRemindersFlow { + static func present( + from presentingViewController: UIViewController, + for blog: Blog, + source: BloggingRemindersTracker.FlowStartSource, + alwaysShow: Bool = true, + delegate: BloggingRemindersFlowDelegate? = nil, + onDismiss: (() -> Void)? = nil + ) { + guard blog.areBloggingRemindersAllowed() else { + return + } + + guard alwaysShow || !hasShownWeeklyRemindersFlow(for: blog) else { + return + } + + let blogType: BloggingRemindersTracker.BlogType = blog.isHostedAtWPcom ? .wpcom : .selfHosted + + let tracker = BloggingRemindersTracker(blogType: blogType) + tracker.flowStarted(source: source) + + let showSettings = { [weak presentingViewController] in + do { + let settingsVC = try BloggingRemindersFlowSettingsViewController(for: blog, tracker: tracker, delegate: delegate) + let navigationController = BloggingRemindersNavigationController(rootViewController: settingsVC, onDismiss: { + onDismiss?() + }) + presentingViewController?.present(navigationController, animated: true) + } catch { + wpAssertionFailure("Could not instantiate the blogging reminders settings VC", userInfo: ["error": "\(error)"]) + } + } + + if hasShownWeeklyRemindersFlow(for: blog) { + showSettings() + } else { + let introVC = BloggingRemindersFlowIntroViewController(tracker: tracker) { [weak presentingViewController] in + presentingViewController?.dismiss(animated: true) { + showSettings() + } + } + let navigationVC = UINavigationController(rootViewController: introVC) + if presentingViewController.traitCollection.horizontalSizeClass == .regular { + navigationVC.preferredContentSize = CGSize(width: 375, height: 420) + } else { + navigationVC.sheetPresentationController?.detents = [.medium()] + navigationVC.sheetPresentationController?.preferredCornerRadius = 16 + } + presentingViewController.present(navigationVC, animated: true) + } + + setHasShownWeeklyRemindersFlow(for: blog) + ActionDispatcher.dispatch(NoticeAction.dismiss) + } + + // MARK: - Weekly reminders flow presentation status + // + // stores a key for each blog in UserDefaults to determine if + // the flow was presented for the given blog. + private static func hasShownWeeklyRemindersFlow(for blog: Blog) -> Bool { + UserPersistentStoreFactory.instance().bool(forKey: weeklyRemindersKey(for: blog)) + } + + static func setHasShownWeeklyRemindersFlow(for blog: Blog) { + UserPersistentStoreFactory.instance().set(true, forKey: weeklyRemindersKey(for: blog)) + } + + private static func weeklyRemindersKey(for blog: Blog) -> String { + // weekly reminders key prefix + let prefix = "blogging-reminder-weekly-" + return prefix + blog.objectID.uriRepresentation().absoluteString + } + + /// By making this private we ensure this can't be instantiated. + /// + private init() { + assertionFailure() + } +} diff --git a/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/BloggingRemindersFlowCompletionViewController.swift b/WordPress/Classes/ViewRelated/Blog/BloggingReminders/BloggingRemindersFlowCompletionViewController.swift similarity index 68% rename from WordPress/Classes/ViewRelated/Blog/Blogging Reminders/BloggingRemindersFlowCompletionViewController.swift rename to WordPress/Classes/ViewRelated/Blog/BloggingReminders/BloggingRemindersFlowCompletionViewController.swift index 63a439c3f8ab..86d16817cfb4 100644 --- a/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/BloggingRemindersFlowCompletionViewController.swift +++ b/WordPress/Classes/ViewRelated/Blog/BloggingReminders/BloggingRemindersFlowCompletionViewController.swift @@ -1,22 +1,14 @@ import UIKit import WordPressUI -class BloggingRemindersFlowCompletionViewController: UIViewController { +final class BloggingRemindersFlowCompletionViewController: UIViewController { // MARK: - Subviews - private let stackView: UIStackView = { - let stackView = UIStackView() - stackView.translatesAutoresizingMaskIntoConstraints = false - stackView.spacing = Metrics.stackSpacing - stackView.axis = .vertical - stackView.alignment = .center - stackView.distribution = .equalSpacing - return stackView - }() + private let scrollView = UIScrollView() private let imageView: UIImageView = { - let imageView = UIImageView(image: UIImage(named: Images.bellImageName)) + let imageView = UIImageView(image: UIImage(named: "reminders-bell")) imageView.translatesAutoresizingMaskIntoConstraints = false imageView.tintColor = .systemYellow return imageView @@ -25,7 +17,6 @@ class BloggingRemindersFlowCompletionViewController: UIViewController { private let titleLabel: UILabel = { let label = UILabel() label.adjustsFontForContentSizeCategory = true - label.adjustsFontSizeToFitWidth = true label.font = WPStyleGuide.serifFontForTextStyle(.title1, fontWeight: .semibold) label.numberOfLines = 2 label.textAlignment = .center @@ -36,7 +27,6 @@ class BloggingRemindersFlowCompletionViewController: UIViewController { private let promptLabel: UILabel = { let label = UILabel() label.adjustsFontForContentSizeCategory = true - label.adjustsFontSizeToFitWidth = true label.font = .preferredFont(forTextStyle: .body) label.numberOfLines = 6 label.textAlignment = .center @@ -47,7 +37,6 @@ class BloggingRemindersFlowCompletionViewController: UIViewController { private let hintLabel: UILabel = { let label = UILabel() label.adjustsFontForContentSizeCategory = true - label.adjustsFontSizeToFitWidth = true label.font = .preferredFont(forTextStyle: .footnote) label.text = TextContent.completionUpdateHint label.numberOfLines = 3 @@ -57,13 +46,17 @@ class BloggingRemindersFlowCompletionViewController: UIViewController { }() private lazy var doneButton: UIButton = { - let button = FancyButton() - button.isPrimary = true + var configuration = UIButton.Configuration.primary() + configuration.title = TextContent.doneButtonTitle + + let button = UIButton(configuration: configuration, primaryAction: nil) button.setTitle(TextContent.doneButtonTitle, for: .normal) button.addTarget(self, action: #selector(doneButtonTapped), for: .touchUpInside) return button }() + private let bottomBarView = BottomToolbarView() + // MARK: - Initializers let blog: Blog @@ -94,10 +87,12 @@ class BloggingRemindersFlowCompletionViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() + view.backgroundColor = .systemBackground - configureStackView() - configureConstraints() + setupView() + setupBottomBar() + configurePromptLabel() configureTitleLabel() @@ -105,9 +100,9 @@ class BloggingRemindersFlowCompletionViewController: UIViewController { } override func viewDidAppear(_ animated: Bool) { - tracker.screenShown(.allSet) - super.viewDidAppear(animated) + + tracker.screenShown(.allSet) } override func viewDidDisappear(_ animated: Bool) { @@ -118,50 +113,39 @@ class BloggingRemindersFlowCompletionViewController: UIViewController { if isBeingDismissedDirectlyOrByAncestor() && navigationController?.viewControllers.last == self { tracker.flowCompleted() } - - } - - override func viewDidLayoutSubviews() { - super.viewDidLayoutSubviews() - calculatePreferredContentSize() - } - - override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { - super.traitCollectionDidChange(previousTraitCollection) - - hintLabel.isHidden = traitCollection.preferredContentSizeCategory.isAccessibilityCategory - } - - func calculatePreferredContentSize() { - let size = CGSize(width: view.bounds.width, height: UIView.layoutFittingCompressedSize.height) - preferredContentSize = view.systemLayoutSizeFitting(size) } // MARK: - View Configuration - private func configureStackView() { - view.addSubview(stackView) - - stackView.addArrangedSubviews([ + private func setupView() { + let stackView = UIStackView(axis: .vertical, alignment: .center, spacing: 8, [ imageView, titleLabel, promptLabel, - hintLabel, - doneButton + hintLabel ]) - stackView.setCustomSpacing(Metrics.afterHintSpacing, after: hintLabel) + stackView.setCustomSpacing(16, after: titleLabel) + + scrollView.showsVerticalScrollIndicator = false + scrollView.alwaysBounceVertical = false + + scrollView.addSubview(stackView) + view.addSubview(scrollView) + + var insets = UIEdgeInsets(.all, 20) + insets.top = 48 + + stackView.pinEdges(insets: insets) + stackView.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -40).isActive = true + + scrollView.pinEdges() } - private func configureConstraints() { - NSLayoutConstraint.activate([ - stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: Metrics.edgeMargins.left), - stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -Metrics.edgeMargins.right), - stackView.topAnchor.constraint(equalTo: view.topAnchor, constant: Metrics.edgeMargins.top), - stackView.bottomAnchor.constraint(lessThanOrEqualTo: view.safeBottomAnchor, constant: -Metrics.edgeMargins.bottom), + private func setupBottomBar() { + bottomBarView.contentView.addSubview(doneButton) + doneButton.pinEdges() - doneButton.heightAnchor.constraint(greaterThanOrEqualToConstant: Metrics.doneButtonHeight), - doneButton.widthAnchor.constraint(equalTo: stackView.widthAnchor), - ]) + bottomBarView.configure(in: self, scrollView: scrollView) } // Populates the prompt label with formatted text detailing the reminders set by the user. @@ -223,20 +207,6 @@ extension BloggingRemindersFlowCompletionViewController: BloggingRemindersAction } } -// MARK: - DrawerPresentable - -extension BloggingRemindersFlowCompletionViewController: DrawerPresentable { - var collapsedHeight: DrawerHeight { - return .intrinsicHeight - } -} - -extension BloggingRemindersFlowCompletionViewController: ChildDrawerPositionable { - var preferredDrawerPosition: DrawerPosition { - return .collapsed - } -} - // MARK: - Constants private enum TextContent { @@ -250,14 +220,6 @@ private enum TextContent { static let doneButtonTitle = NSLocalizedString("Done", comment: "Title for a Done button.") } -private enum Images { - static let bellImageName = "reminders-bell" -} - private enum Metrics { - static let edgeMargins = UIEdgeInsets(top: 46, left: 20, bottom: 20, right: 20) - static let stackSpacing: CGFloat = 20.0 - static let doneButtonHeight: CGFloat = 44.0 - static let afterHintSpacing: CGFloat = 24.0 static let promptTextLineSpacing: CGFloat = 1.5 } diff --git a/WordPress/Classes/ViewRelated/Blog/BloggingReminders/BloggingRemindersFlowIntroViewController.swift b/WordPress/Classes/ViewRelated/Blog/BloggingReminders/BloggingRemindersFlowIntroViewController.swift new file mode 100644 index 000000000000..8d62ab6b8cd4 --- /dev/null +++ b/WordPress/Classes/ViewRelated/Blog/BloggingReminders/BloggingRemindersFlowIntroViewController.swift @@ -0,0 +1,138 @@ +import UIKit + import WordPressUI + +final class BloggingRemindersFlowIntroViewController: UIViewController { + private let scrollView = UIScrollView() + + private let imageView: UIImageView = { + let imageView = UIImageView(image: UIImage(named: "reminders-celebration")) + imageView.tintColor = .systemYellow + return imageView + }() + + private let titleLabel: UILabel = { + let label = UILabel() + label.adjustsFontForContentSizeCategory = true + label.font = .preferredFont(forTextStyle: .title1).withWeight(.semibold) + label.numberOfLines = 2 + label.textAlignment = .center + label.text = Strings.introTitle + return label + }() + + private let promptLabel: UILabel = { + let label = UILabel() + label.adjustsFontForContentSizeCategory = true + label.font = .preferredFont(forTextStyle: .body) + label.numberOfLines = 5 + label.textAlignment = .center + return label + }() + + private lazy var buttonNext: UIButton = { + var configuration = UIButton.Configuration.primary() + configuration.title = Strings.introButtonTitle + + let button = UIButton(configuration: configuration, primaryAction: .init { [weak self] _ in + self?.buttonContinueTapped() + }) + button.titleLabel?.adjustsFontForContentSizeCategory = true + return button + }() + + private let bottomBarView = BottomToolbarView() + + private let tracker: BloggingRemindersTracker + private var isOnNextTapped = false + private let onNextTapped: () -> Void + + init(tracker: BloggingRemindersTracker, onNextTapped: @escaping () -> Void) { + self.tracker = tracker + self.onNextTapped = onNextTapped + + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("Use init(tracker:) instead") + } + + // MARK: - View Lifecycle + + override func viewDidLoad() { + super.viewDidLoad() + + view.backgroundColor = .systemBackground + + setupView() + setupBottomBar() + + promptLabel.text = Strings.introDescription + + navigationItem.rightBarButtonItem = UIBarButtonItem(systemItem: .close, primaryAction: .init(handler: { [weak self] _ in + self?.buttonCloseTapped() + })) + } + + override func viewDidAppear(_ animated: Bool) { + tracker.screenShown(.main) + + super.viewDidAppear(animated) + } + + override func viewDidDisappear(_ animated: Bool) { + super.viewDidDisappear(animated) + + if !isOnNextTapped { + tracker.flowDismissed(source: .main) + } + } + + // MARK: - View Configuration + + private func setupView() { + let stackView = UIStackView(axis: .vertical, alignment: .center, spacing: 20, [ + imageView, + titleLabel, + promptLabel + ]) + stackView.setCustomSpacing(8, after: titleLabel) + + scrollView.showsVerticalScrollIndicator = false + scrollView.alwaysBounceVertical = false + + scrollView.addSubview(stackView) + view.addSubview(scrollView) + + stackView.pinEdges(insets: UIEdgeInsets(.all, 20)) + stackView.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -40).isActive = true + + scrollView.pinEdges() + } + + private func setupBottomBar() { + bottomBarView.contentView.addSubview(buttonNext) + buttonNext.pinEdges() + + bottomBarView.configure(in: self, scrollView: scrollView) + } + + // MARK: Actions + + private func buttonContinueTapped() { + tracker.buttonPressed(button: .continue, screen: .main) + isOnNextTapped = true + onNextTapped() + } + + private func buttonCloseTapped() { + tracker.buttonPressed(button: .dismiss, screen: .main) + presentingViewController?.dismiss(animated: true, completion: nil) + } +} + +private enum Strings { + static let introTitle = NSLocalizedString("bloggingRemindersPrompt.intro.title", value: "Blogging Reminders", comment: "Title of the Blogging Reminders Settings screen.") + static let introDescription = NSLocalizedString("bloggingRemindersPrompt.intro.details", value: "Set up your blogging reminders on days you want to post.", comment: "Description on the first screen of the Blogging Reminders Settings flow called aftet post publishing.") + static let introButtonTitle = NSLocalizedString("bloggingRemindersPrompt.intro.continueButton", value: "Set Reminders", comment: "Title of the set goals button in the Blogging Reminders Settings flow.") +} diff --git a/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/BloggingRemindersFlowSettingsViewController.swift b/WordPress/Classes/ViewRelated/Blog/BloggingReminders/BloggingRemindersFlowSettingsViewController.swift similarity index 96% rename from WordPress/Classes/ViewRelated/Blog/Blogging Reminders/BloggingRemindersFlowSettingsViewController.swift rename to WordPress/Classes/ViewRelated/Blog/BloggingReminders/BloggingRemindersFlowSettingsViewController.swift index 17af112e0157..99f93f2931e4 100644 --- a/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/BloggingRemindersFlowSettingsViewController.swift +++ b/WordPress/Classes/ViewRelated/Blog/BloggingReminders/BloggingRemindersFlowSettingsViewController.swift @@ -6,7 +6,7 @@ protocol BloggingRemindersFlowDelegate: AnyObject { func didSetUpBloggingReminders() } -class BloggingRemindersFlowSettingsViewController: UIViewController { +final class BloggingRemindersFlowSettingsViewController: UIViewController { // MARK: - Subviews @@ -54,8 +54,8 @@ class BloggingRemindersFlowSettingsViewController: UIViewController { }() private lazy var button: UIButton = { - let button = FancyButton() - button.isPrimary = true + var configuration = UIButton.Configuration.primary() + let button = UIButton(configuration: configuration, primaryAction: nil) button.addTarget(self, action: #selector(notifyMeButtonTapped), for: .touchUpInside) return button }() @@ -110,8 +110,8 @@ class BloggingRemindersFlowSettingsViewController: UIViewController { makeDivider() }() - private lazy var timeSelectionButton: TimeSelectionButton = { - let button = TimeSelectionButton(selectedTime: scheduledTime.toLocalTime()) + private lazy var timeSelectionButton: BloggingRemindersTimeSelectionButton = { + let button = BloggingRemindersTimeSelectionButton(selectedTime: scheduledTime.toLocalTime()) button.isUserInteractionEnabled = true button.translatesAutoresizingMaskIntoConstraints = false button.addTarget(self, action: #selector(navigateToTimePicker), for: .touchUpInside) @@ -279,13 +279,16 @@ class BloggingRemindersFlowSettingsViewController: UIViewController { refreshFrequencyLabel() showFullUI(shouldShowFullUI) + + navigationItem.rightBarButtonItem = UIBarButtonItem(systemItem: .close, primaryAction: .init(handler: { [weak self] _ in + self?.presentingViewController?.dismiss(animated: true) + })) } override func viewDidAppear(_ animated: Bool) { - tracker.screenShown(.dayPicker) - super.viewDidAppear(animated) - calculatePreferredContentSize() + + tracker.screenShown(.dayPicker) } override func viewDidDisappear(_ animated: Bool) { @@ -298,11 +301,6 @@ class BloggingRemindersFlowSettingsViewController: UIViewController { } } - override func viewDidLayoutSubviews() { - super.viewDidLayoutSubviews() - calculatePreferredContentSize() - } - override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) @@ -311,8 +309,8 @@ class BloggingRemindersFlowSettingsViewController: UIViewController { override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransition(to: size, with: coordinator) + showFullUI(shouldShowFullUI) - calculatePreferredContentSize() } // MARK: - Actions @@ -408,14 +406,12 @@ class BloggingRemindersFlowSettingsViewController: UIViewController { private extension BloggingRemindersFlowSettingsViewController { func pushTimeSelectionViewController() { - let viewController = TimeSelectionViewController(scheduledTime: scheduler.scheduledTime(for: blog), - tracker: tracker) { [weak self] date in + let viewController = BloggingRemindersTimeSelectionViewController(scheduledTime: scheduler.scheduledTime(for: blog), tracker: tracker) { [weak self] date in self?.scheduledTime = date self?.timeSelectionButton.setSelectedTime(date.toLocalTime()) self?.refreshNextButton() self?.refreshFrequencyLabel() } - viewController.preferredWidth = self.view.frame.width navigationController?.pushViewController(viewController, animated: true) } @@ -499,11 +495,6 @@ private extension BloggingRemindersFlowSettingsViewController { frequencyLabel.sizeToFit() } - func calculatePreferredContentSize() { - let size = CGSize(width: view.bounds.width, height: UIView.layoutFittingCompressedSize.height) - preferredContentSize = view.systemLayoutSizeFitting(size) - } - func configureStackView() { view.addSubview(stackView) @@ -653,18 +644,6 @@ extension BloggingRemindersFlowSettingsViewController: BloggingRemindersActions } } -extension BloggingRemindersFlowSettingsViewController: DrawerPresentable { - var collapsedHeight: DrawerHeight { - return .maxHeight - } -} - -extension BloggingRemindersFlowSettingsViewController: ChildDrawerPositionable { - var preferredDrawerPosition: DrawerPosition { - return .expanded - } -} - // MARK: - Blogging Prompts Helpers private extension BloggingRemindersFlowSettingsViewController { diff --git a/WordPress/Classes/ViewRelated/Blog/BloggingReminders/BloggingRemindersNavigationController.swift b/WordPress/Classes/ViewRelated/Blog/BloggingReminders/BloggingRemindersNavigationController.swift new file mode 100644 index 000000000000..ae119f8e8ad3 --- /dev/null +++ b/WordPress/Classes/ViewRelated/Blog/BloggingReminders/BloggingRemindersNavigationController.swift @@ -0,0 +1,30 @@ +import UIKit +import WordPressUI + +final class BloggingRemindersNavigationController: UINavigationController { + private let onDismiss: (() -> Void)? + + required init(rootViewController: UIViewController, onDismiss: (() -> Void)? = nil) { + self.onDismiss = onDismiss + + super.init(rootViewController: rootViewController) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func viewDidLoad() { + super.viewDidLoad() + + view.backgroundColor = .systemBackground + } + + override func viewDidDisappear(_ animated: Bool) { + super.viewDidDisappear(animated) + + if isBeingDismissedDirectlyOrByAncestor() { + onDismiss?() + } + } +} diff --git a/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/BloggingRemindersPushPromptViewController.swift b/WordPress/Classes/ViewRelated/Blog/BloggingReminders/BloggingRemindersPushPromptViewController.swift similarity index 79% rename from WordPress/Classes/ViewRelated/Blog/Blogging Reminders/BloggingRemindersPushPromptViewController.swift rename to WordPress/Classes/ViewRelated/Blog/BloggingReminders/BloggingRemindersPushPromptViewController.swift index 5c694e8b4118..51e05e817800 100644 --- a/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/BloggingRemindersPushPromptViewController.swift +++ b/WordPress/Classes/ViewRelated/Blog/BloggingReminders/BloggingRemindersPushPromptViewController.swift @@ -1,7 +1,7 @@ import UIKit import WordPressUI -class BloggingRemindersPushPromptViewController: UIViewController { +final class BloggingRemindersPushPromptViewController: UIViewController { // MARK: - Subviews @@ -58,21 +58,12 @@ class BloggingRemindersPushPromptViewController: UIViewController { }() private lazy var turnOnNotificationsButton: UIButton = { - let button = FancyButton() - button.translatesAutoresizingMaskIntoConstraints = false - button.isPrimary = true - button.setTitle(TextContent.turnOnButtonTitle, for: .normal) - button.addTarget(self, action: #selector(turnOnButtonTapped), for: .touchUpInside) - button.titleLabel?.adjustsFontSizeToFitWidth = true - return button - }() + var configuration = UIButton.Configuration.primary() + configuration.title = TextContent.turnOnButtonTitle - private lazy var dismissButton: UIButton = { - let button = UIButton(type: .custom) + let button = UIButton(configuration: configuration, primaryAction: nil) button.translatesAutoresizingMaskIntoConstraints = false - button.setImage(.gridicon(.cross), for: .normal) - button.tintColor = .secondaryLabel - button.addTarget(self, action: #selector(dismissTapped), for: .touchUpInside) + button.addTarget(self, action: #selector(turnOnButtonTapped), for: .touchUpInside) return button }() @@ -118,14 +109,11 @@ class BloggingRemindersPushPromptViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .systemBackground - view.addSubview(dismissButton) configureStackView() view.addSubview(turnOnNotificationsButton) configureConstraints() - - navigationController?.setNavigationBarHidden(true, animated: false) } override func viewDidAppear(_ animated: Bool) { @@ -145,22 +133,12 @@ class BloggingRemindersPushPromptViewController: UIViewController { } - override func viewDidLayoutSubviews() { - super.viewDidLayoutSubviews() - calculatePreferredContentSize() - } - override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) hintLabel.isHidden = traitCollection.preferredContentSizeCategory.isAccessibilityCategory } - private func calculatePreferredContentSize() { - let size = CGSize(width: view.bounds.width, height: UIView.layoutFittingCompressedSize.height) - preferredContentSize = view.systemLayoutSizeFitting(size) - } - @objc private func applicationBecameActive() { refreshPushAuthorizationStatus() @@ -186,13 +164,9 @@ class BloggingRemindersPushPromptViewController: UIViewController { stackView.topAnchor.constraint(equalTo: view.topAnchor, constant: Metrics.edgeMargins.top), turnOnNotificationsButton.topAnchor.constraint(greaterThanOrEqualTo: stackView.bottomAnchor, constant: Metrics.edgeMargins.bottom), - turnOnNotificationsButton.heightAnchor.constraint(greaterThanOrEqualToConstant: Metrics.turnOnButtonHeight), turnOnNotificationsButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: Metrics.edgeMargins.left), turnOnNotificationsButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -Metrics.edgeMargins.right), - turnOnNotificationsButton.bottomAnchor.constraint(equalTo: view.safeBottomAnchor, constant: -Metrics.edgeMargins.bottom), - - dismissButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -Metrics.dismissButtonMargin), - dismissButton.topAnchor.constraint(equalTo: view.topAnchor, constant: Metrics.dismissButtonMargin) + turnOnNotificationsButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -Metrics.edgeMargins.bottom), ]) } @@ -230,20 +204,6 @@ extension BloggingRemindersPushPromptViewController: BloggingRemindersActions { } } -// MARK: - DrawerPresentable - -extension BloggingRemindersPushPromptViewController: DrawerPresentable { - var collapsedHeight: DrawerHeight { - return .maxHeight - } -} - -extension BloggingRemindersPushPromptViewController: ChildDrawerPositionable { - var preferredDrawerPosition: DrawerPosition { - return .expanded - } -} - // MARK: - Constants private enum TextContent { @@ -263,8 +223,6 @@ private enum Images { } private enum Metrics { - static let dismissButtonMargin: CGFloat = 20.0 - static let edgeMargins = UIEdgeInsets(top: 80, left: 28, bottom: 80, right: 28) + static let edgeMargins = UIEdgeInsets(top: 80, left: 20, bottom: 20, right: 20) static let stackSpacing: CGFloat = 20.0 - static let turnOnButtonHeight: CGFloat = 44.0 } diff --git a/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/BloggingRemindersTracker.swift b/WordPress/Classes/ViewRelated/Blog/BloggingReminders/BloggingRemindersTracker.swift similarity index 100% rename from WordPress/Classes/ViewRelated/Blog/Blogging Reminders/BloggingRemindersTracker.swift rename to WordPress/Classes/ViewRelated/Blog/BloggingReminders/BloggingRemindersTracker.swift diff --git a/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/CalendarDayToggleButton.swift b/WordPress/Classes/ViewRelated/Blog/BloggingReminders/CalendarDayToggleButton.swift similarity index 100% rename from WordPress/Classes/ViewRelated/Blog/Blogging Reminders/CalendarDayToggleButton.swift rename to WordPress/Classes/ViewRelated/Blog/BloggingReminders/CalendarDayToggleButton.swift diff --git a/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/Time Selector/TimeSelectionButton.swift b/WordPress/Classes/ViewRelated/Blog/BloggingReminders/TimeSelector/BloggingRemindersTimeSelectionButton.swift similarity index 97% rename from WordPress/Classes/ViewRelated/Blog/Blogging Reminders/Time Selector/TimeSelectionButton.swift rename to WordPress/Classes/ViewRelated/Blog/BloggingReminders/TimeSelector/BloggingRemindersTimeSelectionButton.swift index 2dd59d12c661..ab64a5d8ef73 100644 --- a/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/Time Selector/TimeSelectionButton.swift +++ b/WordPress/Classes/ViewRelated/Blog/BloggingReminders/TimeSelector/BloggingRemindersTimeSelectionButton.swift @@ -1,6 +1,6 @@ import UIKit -class TimeSelectionButton: UIButton { +final class BloggingRemindersTimeSelectionButton: UIButton { private(set) var selectedTime: String { didSet { diff --git a/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/Time Selector/TimeSelectionView.swift b/WordPress/Classes/ViewRelated/Blog/BloggingReminders/TimeSelector/BloggingRemindersTimeSelectionView.swift similarity index 88% rename from WordPress/Classes/ViewRelated/Blog/Blogging Reminders/Time Selector/TimeSelectionView.swift rename to WordPress/Classes/ViewRelated/Blog/BloggingReminders/TimeSelector/BloggingRemindersTimeSelectionView.swift index 973353ba2781..0160e57fc9c7 100644 --- a/WordPress/Classes/ViewRelated/Blog/Blogging Reminders/Time Selector/TimeSelectionView.swift +++ b/WordPress/Classes/ViewRelated/Blog/BloggingReminders/TimeSelector/BloggingRemindersTimeSelectionView.swift @@ -1,7 +1,8 @@ import UIKit +import WordPressUI /// A view that contains a time picker and a title reporting the selected time -class TimeSelectionView: UIView { +final class BloggingRemindersTimeSelectionView: UIView { private var selectedTime: Date @@ -19,8 +20,8 @@ class TimeSelectionView: UIView { titleBar.setSelectedTime(timePicker.date.toLocalTime()) } - private lazy var titleBar: TimeSelectionButton = { - let button = TimeSelectionButton(selectedTime: selectedTime.toLocalTime(), insets: Self.titleInsets) + private lazy var titleBar: BloggingRemindersTimeSelectionButton = { + let button = BloggingRemindersTimeSelectionButton(selectedTime: selectedTime.toLocalTime(), insets: Self.titleInsets) button.translatesAutoresizingMaskIntoConstraints = false button.isUserInteractionEnabled = false button.isChevronHidden = true @@ -65,9 +66,9 @@ class TimeSelectionView: UIView { self.selectedTime = selectedTime super.init(frame: .zero) - backgroundColor = .systemBackground addSubview(verticalStackView) - pinSubviewToSafeArea(verticalStackView) + verticalStackView.pinEdges(to: safeAreaLayoutGuide) + NSLayoutConstraint.activate([ timePicker.centerXAnchor.constraint(equalTo: centerXAnchor), titleBar.widthAnchor.constraint(equalTo: widthAnchor), diff --git a/WordPress/Classes/ViewRelated/Blog/BloggingReminders/TimeSelector/BloggingRemindersTimeSelectionViewController.swift b/WordPress/Classes/ViewRelated/Blog/BloggingReminders/TimeSelector/BloggingRemindersTimeSelectionViewController.swift new file mode 100644 index 000000000000..99b75e03bda1 --- /dev/null +++ b/WordPress/Classes/ViewRelated/Blog/BloggingReminders/TimeSelector/BloggingRemindersTimeSelectionViewController.swift @@ -0,0 +1,50 @@ +import UIKit +import WordPressUI + +final class BloggingRemindersTimeSelectionViewController: UIViewController { + private let scheduledTime: Date + + private let tracker: BloggingRemindersTracker + + private var onDismiss: ((Date) -> Void)? + + private lazy var timeSelectionView = BloggingRemindersTimeSelectionView(selectedTime: scheduledTime) + + init(scheduledTime: Date, tracker: BloggingRemindersTracker, onDismiss: ((Date) -> Void)? = nil) { + self.scheduledTime = scheduledTime + self.tracker = tracker + self.onDismiss = onDismiss + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func viewDidLoad() { + super.viewDidLoad() + + view.backgroundColor = .systemBackground + + view.addSubview(timeSelectionView) + timeSelectionView.pinEdges([.top, .horizontal]) + } + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + + if isMovingFromParent { + onDismiss?(timeSelectionView.getDate()) + } + } + + override func viewDidDisappear(_ animated: Bool) { + super.viewDidDisappear(animated) + + // If a parent VC is being dismissed, and this is the last view shown in its navigation controller, we'll assume + // the flow was interrupted. + if isBeingDismissedDirectlyOrByAncestor() && navigationController?.viewControllers.last == self { + tracker.flowDismissed(source: .timePicker) + } + } +} diff --git a/WordPress/Classes/ViewRelated/Blog/My Site/Header/HomeSiteHeaderViewController.swift b/WordPress/Classes/ViewRelated/Blog/My Site/Header/HomeSiteHeaderViewController.swift index 2d9150326fbb..ff200d4d21a0 100644 --- a/WordPress/Classes/ViewRelated/Blog/My Site/Header/HomeSiteHeaderViewController.swift +++ b/WordPress/Classes/ViewRelated/Blog/My Site/Header/HomeSiteHeaderViewController.swift @@ -255,7 +255,7 @@ extension HomeSiteHeaderViewController { onClose: nil ) - let navigationController = LightNavigationController(rootViewController: webViewController) + let navigationController = UINavigationController(rootViewController: webViewController) if traitCollection.userInterfaceIdiom == .pad { navigationController.modalPresentationStyle = .fullScreen diff --git a/WordPress/Classes/ViewRelated/Blog/Sharing/SharingAuthorizationHelper.m b/WordPress/Classes/ViewRelated/Blog/Sharing/SharingAuthorizationHelper.m index 30436b269ca2..0b64b9e8aef6 100644 --- a/WordPress/Classes/ViewRelated/Blog/Sharing/SharingAuthorizationHelper.m +++ b/WordPress/Classes/ViewRelated/Blog/Sharing/SharingAuthorizationHelper.m @@ -91,7 +91,7 @@ - (void)authorizeWithConnectionURL:(NSURL *)connectionURL { SharingAuthorizationWebViewController *webViewController = [[SharingAuthorizationWebViewController alloc] initWith:self.publicizeService url:connectionURL for:self.blog delegate:self]; - self.navController = [[LightNavigationController alloc] initWithRootViewController:webViewController]; + self.navController = [[UINavigationController alloc] initWithRootViewController:webViewController]; self.navController.modalPresentationStyle = UIModalPresentationFormSheet; [self.viewController presentViewController:self.navController animated:YES completion:nil]; } diff --git a/WordPress/Classes/ViewRelated/Jetpack/Branding/Overlay/JetpackOverlayViewController.swift b/WordPress/Classes/ViewRelated/Jetpack/Branding/Overlay/JetpackOverlayViewController.swift index 3f17f95d9a15..ff9c853a6cc4 100644 --- a/WordPress/Classes/ViewRelated/Jetpack/Branding/Overlay/JetpackOverlayViewController.swift +++ b/WordPress/Classes/ViewRelated/Jetpack/Branding/Overlay/JetpackOverlayViewController.swift @@ -51,9 +51,3 @@ extension JetpackOverlayViewController: DrawerPresentable { .maxWidth } } - -extension JetpackOverlayViewController: ChildDrawerPositionable { - var preferredDrawerPosition: DrawerPosition { - .collapsed - } -} diff --git a/WordPress/Classes/ViewRelated/Jetpack/Jetpack Restore/Restore Complete/JetpackRestoreCompleteViewController.swift b/WordPress/Classes/ViewRelated/Jetpack/Jetpack Restore/Restore Complete/JetpackRestoreCompleteViewController.swift index afb44f0f80a1..7075dbfcd052 100644 --- a/WordPress/Classes/ViewRelated/Jetpack/Jetpack Restore/Restore Complete/JetpackRestoreCompleteViewController.swift +++ b/WordPress/Classes/ViewRelated/Jetpack/Jetpack Restore/Restore Complete/JetpackRestoreCompleteViewController.swift @@ -54,7 +54,7 @@ class JetpackRestoreCompleteViewController: BaseRestoreCompleteViewController { } let webVC = WebViewControllerFactory.controller(url: homeURL, source: "jetpack_restore_complete") - let navigationVC = LightNavigationController(rootViewController: webVC) + let navigationVC = UINavigationController(rootViewController: webVC) self.present(navigationVC, animated: true) } diff --git a/WordPress/Classes/ViewRelated/Notifications/ReplyTextView/ReplyTextView.swift b/WordPress/Classes/ViewRelated/Notifications/ReplyTextView/ReplyTextView.swift index aada63071618..003e65a7ff59 100644 --- a/WordPress/Classes/ViewRelated/Notifications/ReplyTextView/ReplyTextView.swift +++ b/WordPress/Classes/ViewRelated/Notifications/ReplyTextView/ReplyTextView.swift @@ -216,7 +216,7 @@ import Gridicons self.resignFirstResponder() - let navController = LightNavigationController(rootViewController: editViewController) + let navController = UINavigationController(rootViewController: editViewController) rootViewController.present(navController, animated: true) } diff --git a/WordPress/Classes/ViewRelated/People/Controllers/PeopleViewController.swift b/WordPress/Classes/ViewRelated/People/Controllers/PeopleViewController.swift index f3d6ccca3ab7..a2f689990ebb 100644 --- a/WordPress/Classes/ViewRelated/People/Controllers/PeopleViewController.swift +++ b/WordPress/Classes/ViewRelated/People/Controllers/PeopleViewController.swift @@ -188,7 +188,7 @@ class PeopleViewController: UITableViewController { self?.refreshPeople() } let viewController = WebKitViewController(configuration: configuration) - let navWrapper = LightNavigationController(rootViewController: viewController) + let navWrapper = UINavigationController(rootViewController: viewController) navigationController?.present(navWrapper, animated: true) } } diff --git a/WordPress/Classes/ViewRelated/Post/Controllers/AbstractPostListViewController.swift b/WordPress/Classes/ViewRelated/Post/Controllers/AbstractPostListViewController.swift index 020e21f3b4e3..8fa79f8f1282 100644 --- a/WordPress/Classes/ViewRelated/Post/Controllers/AbstractPostListViewController.swift +++ b/WordPress/Classes/ViewRelated/Post/Controllers/AbstractPostListViewController.swift @@ -664,7 +664,7 @@ class AbstractPostListViewController: UIViewController, // NOTE: We'll set the title to match the title of the View action button. // If the button title changes we should also update the title here. controller.navigationItem.title = NSLocalizedString("View", comment: "Verb. The screen title shown when viewing a post inside the app.") - let navWrapper = LightNavigationController(rootViewController: controller) + let navWrapper = UINavigationController(rootViewController: controller) if navigationController?.traitCollection.userInterfaceIdiom == .pad { navWrapper.modalPresentationStyle = .fullScreen } diff --git a/WordPress/Classes/ViewRelated/Post/PostEditor+MoreOptions.swift b/WordPress/Classes/ViewRelated/Post/PostEditor+MoreOptions.swift index 76000b4302af..9bae8164b833 100644 --- a/WordPress/Classes/ViewRelated/Post/PostEditor+MoreOptions.swift +++ b/WordPress/Classes/ViewRelated/Post/PostEditor+MoreOptions.swift @@ -87,7 +87,7 @@ extension PostEditor { previewController = PreviewWebKitViewController(post: self.post, source: "edit_post_more_preview") } previewController.trackOpenEvent() - let navWrapper = LightNavigationController(rootViewController: previewController) + let navWrapper = UINavigationController(rootViewController: previewController) if self.navigationController?.traitCollection.userInterfaceIdiom == .pad { navWrapper.modalPresentationStyle = .fullScreen } diff --git a/WordPress/Classes/ViewRelated/Post/Scheduling/LightNavigationController.swift b/WordPress/Classes/ViewRelated/Post/Scheduling/LightNavigationController.swift deleted file mode 100644 index 6a8937bf1c91..000000000000 --- a/WordPress/Classes/ViewRelated/Post/Scheduling/LightNavigationController.swift +++ /dev/null @@ -1,7 +0,0 @@ -import Foundation - -// TODO: remove - -// A Navigation Controller with a light navigation bar style -class LightNavigationController: UINavigationController { -} diff --git a/WordPress/Classes/ViewRelated/Post/Utils/PostNoticeNavigationCoordinator.swift b/WordPress/Classes/ViewRelated/Post/Utils/PostNoticeNavigationCoordinator.swift index ad536f6b5194..8168ed23bf60 100644 --- a/WordPress/Classes/ViewRelated/Post/Utils/PostNoticeNavigationCoordinator.swift +++ b/WordPress/Classes/ViewRelated/Post/Utils/PostNoticeNavigationCoordinator.swift @@ -28,7 +28,7 @@ class PostNoticeNavigationCoordinator { controller.trackOpenEvent() controller.navigationItem.title = NSLocalizedString("View", comment: "Verb. The screen title shown when viewing a post inside the app.") - let navigationController = LightNavigationController(rootViewController: controller) + let navigationController = UINavigationController(rootViewController: controller) if presenter.traitCollection.userInterfaceIdiom == .pad { navigationController.modalPresentationStyle = .fullScreen } diff --git a/WordPress/Classes/ViewRelated/Post/Utils/PostNoticePublishSuccessView.swift b/WordPress/Classes/ViewRelated/Post/Utils/PostNoticePublishSuccessView.swift index 6b7e22e75f8f..0b3c259ed034 100644 --- a/WordPress/Classes/ViewRelated/Post/Utils/PostNoticePublishSuccessView.swift +++ b/WordPress/Classes/ViewRelated/Post/Utils/PostNoticePublishSuccessView.swift @@ -117,7 +117,7 @@ struct PostNoticePublishSuccessView: View { WPAnalytics.track(.postEpilogueView) let controller = PreviewWebKitViewController(post: post, source: "edit_post_preview") controller.trackOpenEvent() - let navWrapper = LightNavigationController(rootViewController: controller) + let navWrapper = UINavigationController(rootViewController: controller) presenter.present(navWrapper, animated: true) } diff --git a/WordPress/Classes/ViewRelated/Reader/Controllers/ReaderPostActions/ReaderVisitSiteAction.swift b/WordPress/Classes/ViewRelated/Reader/Controllers/ReaderPostActions/ReaderVisitSiteAction.swift index 0e2cb91c8c29..ddad644dfeb6 100644 --- a/WordPress/Classes/ViewRelated/Reader/Controllers/ReaderPostActions/ReaderVisitSiteAction.swift +++ b/WordPress/Classes/ViewRelated/Reader/Controllers/ReaderPostActions/ReaderVisitSiteAction.swift @@ -14,7 +14,7 @@ final class ReaderVisitSiteAction { configuration.authenticate(account: account) } let controller = WebViewControllerFactory.controller(configuration: configuration, source: "reader_visit_site") - let navController = LightNavigationController(rootViewController: controller) + let navController = UINavigationController(rootViewController: controller) origin.present(navController, animated: true) WPAnalytics.trackReader(.readerArticleVisited) } diff --git a/WordPress/Classes/ViewRelated/Reader/Detail/ReaderDetailCoordinator.swift b/WordPress/Classes/ViewRelated/Reader/Detail/ReaderDetailCoordinator.swift index c037dfef9f3a..607ff17c6c8a 100644 --- a/WordPress/Classes/ViewRelated/Reader/Detail/ReaderDetailCoordinator.swift +++ b/WordPress/Classes/ViewRelated/Reader/Detail/ReaderDetailCoordinator.swift @@ -573,7 +573,7 @@ class ReaderDetailCoordinator { configuration.authenticateWithDefaultAccount() configuration.addsWPComReferrer = true let controller = WebViewControllerFactory.controller(configuration: configuration, source: "reader_detail") - let navController = LightNavigationController(rootViewController: controller) + let navController = UINavigationController(rootViewController: controller) viewController?.present(navController, animated: true) } diff --git a/WordPress/WordPress.xcodeproj/project.pbxproj b/WordPress/WordPress.xcodeproj/project.pbxproj index 2d1bfab4901d..927371beb713 100644 --- a/WordPress/WordPress.xcodeproj/project.pbxproj +++ b/WordPress/WordPress.xcodeproj/project.pbxproj @@ -3414,7 +3414,6 @@ "ViewRelated/Aztec/Extensions/TextList+WordPress.swift", ViewRelated/Aztec/Processors/ImgUploadProcessor.swift, ViewRelated/Cells/WPReusableTableViewCells.swift, - ViewRelated/Post/Scheduling/LightNavigationController.swift, ViewRelated/Tools/TableViewKeyboardObserver.swift, ViewRelated/Views/NoResults.storyboard, ViewRelated/Views/NoResultsViewController.swift, @@ -3454,7 +3453,6 @@ "ViewRelated/Aztec/Extensions/TextList+WordPress.swift", ViewRelated/Aztec/Processors/ImgUploadProcessor.swift, ViewRelated/Cells/WPReusableTableViewCells.swift, - ViewRelated/Post/Scheduling/LightNavigationController.swift, ViewRelated/Tools/TableViewKeyboardObserver.swift, ViewRelated/Views/NoResults.storyboard, ViewRelated/Views/NoResultsViewController.swift, @@ -3585,7 +3583,6 @@ "ViewRelated/Aztec/Extensions/TextList+WordPress.swift", ViewRelated/Aztec/Processors/ImgUploadProcessor.swift, ViewRelated/Cells/WPReusableTableViewCells.swift, - ViewRelated/Post/Scheduling/LightNavigationController.swift, ViewRelated/Tools/TableViewKeyboardObserver.swift, ViewRelated/Views/NoResults.storyboard, ViewRelated/Views/NoResultsViewController.swift, @@ -3623,7 +3620,6 @@ "ViewRelated/Aztec/Extensions/TextList+WordPress.swift", ViewRelated/Aztec/Processors/ImgUploadProcessor.swift, ViewRelated/Cells/WPReusableTableViewCells.swift, - ViewRelated/Post/Scheduling/LightNavigationController.swift, ViewRelated/Tools/TableViewKeyboardObserver.swift, ViewRelated/Views/NoResults.storyboard, ViewRelated/Views/NoResultsViewController.swift, diff --git a/WordPress/WordPressTest/Comments/Controllers/FullScreenCommentReplyViewControllerTests.swift b/WordPress/WordPressTest/Comments/Controllers/FullScreenCommentReplyViewControllerTests.swift index 1e839c8ef615..7f04a1ecec65 100644 --- a/WordPress/WordPressTest/Comments/Controllers/FullScreenCommentReplyViewControllerTests.swift +++ b/WordPress/WordPressTest/Comments/Controllers/FullScreenCommentReplyViewControllerTests.swift @@ -136,7 +136,7 @@ class FullScreenCommentReplyViewControllerTests: CoreDataTestCase { /// - inWindow: The window instance you want to load it in private func load(_ controller: UIViewController, inWindow: UIWindow) { inWindow.addSubview(controller.view) - inWindow.rootViewController = LightNavigationController(rootViewController: controller) + inWindow.rootViewController = UINavigationController(rootViewController: controller) inWindow.makeKeyAndVisible() controller.beginAppearanceTransition(true, animated: false) RunLoop.current.run(until: Date())