Skip to content

Commit 27e19ee

Browse files
authored
Enhance BloggingRemindersFlow (#23931)
2 parents f08ebcc + 84ac565 commit 27e19ee

File tree

44 files changed

+565
-768
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+565
-768
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import UIKit
2+
3+
extension UIButton.Configuration {
4+
public static func primary() -> UIButton.Configuration {
5+
var configuration = UIButton.Configuration.borderedProminent()
6+
configuration.titleTextAttributesTransformer = .init { attributes in
7+
var attributes = attributes
8+
attributes.font = UIFont.preferredFont(forTextStyle: .headline)
9+
return attributes
10+
}
11+
configuration.buttonSize = .large
12+
return configuration
13+
}
14+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import UIKit
2+
import Combine
3+
4+
/// A custom bottom toolbar implementation that, unlike the native toolbar,
5+
/// can accommodate larger buttons but shares a lot of its behavior including
6+
/// edge appearance.
7+
public class BottomToolbarView: UIView {
8+
private let separator = SeparatorView.horizontal()
9+
private let effectView = UIVisualEffectView()
10+
private var isEdgeAppearanceEnabled = false
11+
private weak var scrollView: UIScrollView?
12+
private var cancellable: AnyCancellable?
13+
14+
public let contentView = UIView()
15+
16+
public override init(frame: CGRect) {
17+
super.init(frame: frame)
18+
19+
addSubview(effectView)
20+
addSubview(separator)
21+
22+
separator.pinEdges([.top, .horizontal])
23+
effectView.pinEdges()
24+
25+
effectView.contentView.addSubview(contentView)
26+
27+
contentView.pinEdges(to: effectView.contentView.safeAreaLayoutGuide, insets: UIEdgeInsets(.all, 20))
28+
}
29+
30+
public required init?(coder: NSCoder) {
31+
fatalError("init(coder:) has not been implemented")
32+
}
33+
34+
public override func layoutSubviews() {
35+
super.layoutSubviews()
36+
37+
updateScrollViewContentInsets()
38+
}
39+
40+
public override func safeAreaInsetsDidChange() {
41+
super.safeAreaInsetsDidChange()
42+
43+
updateScrollViewContentInsets()
44+
}
45+
46+
/// - warning: If you use this view, you'll typically need to take over the
47+
/// scroll view content inset adjustment.
48+
public func configure(in viewController: UIViewController, scrollView: UIScrollView) {
49+
viewController.view.addSubview(self)
50+
pinEdges([.horizontal, .bottom])
51+
self.scrollView = scrollView
52+
53+
cancellable = scrollView.publisher(for: \.contentOffset, options: [.new]).sink { [weak self] offset in
54+
self?.updateEdgeAppearance(animated: true)
55+
}
56+
updateScrollViewContentInsets()
57+
updateEdgeAppearance(animated: false)
58+
}
59+
60+
private func updateEdgeAppearance(animated: Bool) {
61+
guard let scrollView, let superview else { return }
62+
63+
let isContentOverlapping = superview.convert(scrollView.contentLayoutGuide.layoutFrame, from: scrollView).maxY > (frame.minY + 16)
64+
setEdgeAppearanceEnabled(!isContentOverlapping, animated: animated)
65+
}
66+
67+
private func setEdgeAppearanceEnabled(_ isEnabled: Bool, animated: Bool) {
68+
guard isEdgeAppearanceEnabled != isEnabled else { return }
69+
isEdgeAppearanceEnabled = isEnabled
70+
71+
UIView.animate(withDuration: animated ? 0 : 0.33, delay: 0.0, options: [.allowUserInteraction, .beginFromCurrentState]) {
72+
self.effectView.effect = isEnabled ? nil : UIBlurEffect(style: .extraLight)
73+
self.separator.alpha = isEnabled ? 0 : 1
74+
}
75+
}
76+
77+
// The toolbar does no extend the safe area because it itself depends on it,
78+
// so it resorts to changing `contentInset` instead.
79+
private func updateScrollViewContentInsets() {
80+
guard let scrollView else { return }
81+
let bottomInset = bounds.height - safeAreaInsets.bottom
82+
if scrollView.contentInset.bottom != bottomInset {
83+
scrollView.contentInset.bottom = bottomInset
84+
}
85+
}
86+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import UIKit
2+
3+
public final class SeparatorView: UIView {
4+
public static func horizontal() -> SeparatorView {
5+
let view = SeparatorView()
6+
view.heightAnchor.constraint(equalToConstant: 0.5).isActive = true
7+
return view
8+
}
9+
10+
public static func vertical() -> SeparatorView {
11+
let view = SeparatorView()
12+
view.widthAnchor.constraint(equalToConstant: 0.5).isActive = true
13+
return view
14+
}
15+
16+
public override init(frame: CGRect) {
17+
super.init(frame: frame)
18+
19+
backgroundColor = .separator
20+
}
21+
22+
public required init?(coder: NSCoder) {
23+
fatalError("init(coder:) has not been implemented")
24+
}
25+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import UIKit
2+
3+
public final class SpacerView: UIView {
4+
public convenience init(minWidth: CGFloat) {
5+
self.init()
6+
7+
widthAnchor.constraint(greaterThanOrEqualToConstant: minWidth).isActive = true
8+
}
9+
10+
public convenience init(minHeight: CGFloat) {
11+
self.init()
12+
13+
heightAnchor.constraint(greaterThanOrEqualToConstant: minHeight).isActive = true
14+
}
15+
16+
public convenience init(width: CGFloat) {
17+
self.init()
18+
19+
widthAnchor.constraint(equalToConstant: width).isActive = true
20+
}
21+
22+
public convenience init(height: CGFloat) {
23+
self.init()
24+
25+
heightAnchor.constraint(equalToConstant: height).isActive = true
26+
}
27+
28+
public override init(frame: CGRect) {
29+
super.init(frame: .zero)
30+
31+
// Make sure it compresses or expands before any other views if needed.
32+
setContentCompressionResistancePriority(.init(10), for: .horizontal)
33+
setContentCompressionResistancePriority(.init(10), for: .vertical)
34+
setContentHuggingPriority(.init(10), for: .horizontal)
35+
setContentHuggingPriority(.init(10), for: .vertical)
36+
}
37+
38+
public override var intrinsicContentSize: CGSize {
39+
CGSizeMake(0, 0) // Avoid ambiguous layout
40+
}
41+
42+
public required init?(coder aDecoder: NSCoder) {
43+
super.init(coder: aDecoder)
44+
}
45+
46+
override public class var layerClass: AnyClass {
47+
CATransformLayer.self // Draws nothing
48+
}
49+
50+
override public var backgroundColor: UIColor? {
51+
get { return nil }
52+
set { /* Do nothing */ }
53+
}
54+
}

RELEASE-NOTES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* [**] Add new lightbox screen for images with modern transitions and enhanced performance [#23922]
44
* [*] Add prefetching to Reader streams [#23928]
55
* [*] Fix an issue with blogging reminders prompt not being shown after publishing a new post [#23930]
6+
* [*] Fix transitions in Blogging Reminders flow, improve accessibiliy, add close buttons [#23931]
67

78
25.6
89
-----

WordPress/Classes/Utility/Blogging Reminders/BloggingRemindersScheduler.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ extension InteractiveNotificationsManager: PushNotificationAuthorizer {
1717

1818
/// Main interface for scheduling blogging reminders
1919
///
20-
class BloggingRemindersScheduler {
20+
final class BloggingRemindersScheduler {
2121

2222
// MARK: - Convenience Typealiases
2323

WordPress/Classes/Utility/Spotlight/SearchManager.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ fileprivate extension SearchManager {
458458

459459
let controller = PreviewWebKitViewController(post: apost, source: "spotlight_preview_post")
460460
controller.trackOpenEvent()
461-
let navWrapper = LightNavigationController(rootViewController: controller)
461+
let navWrapper = UINavigationController(rootViewController: controller)
462462
let rootViewController = RootViewCoordinator.sharedPresenter.rootViewController
463463
if rootViewController.traitCollection.userInterfaceIdiom == .pad {
464464
navWrapper.modalPresentationStyle = .fullScreen

0 commit comments

Comments
 (0)