Skip to content

Commit 08859e1

Browse files
authored
Merge pull request #17847 from wordpress-mobile/task/msd-fab-and-auto-scroll
My Site Dashboard: FAB + Quick Start tour auto-scroll
2 parents 67b689b + e644f7e commit 08859e1

File tree

7 files changed

+125
-17
lines changed

7 files changed

+125
-17
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import UIKit
2+
3+
extension UIScrollView {
4+
5+
// Scroll to a specific view so that it's top is at the top our scrollview
6+
@objc func scrollToView(_ view: UIView, animated: Bool) {
7+
if let origin = view.superview {
8+
9+
// Get the Y position of your child view
10+
let childStartPoint = origin.convert(view.frame.origin, to: self)
11+
12+
// Scroll to a rectangle starting at the Y of your subview, with a height of the scrollview safe area
13+
// if the bottom of the rectangle is within the content size height.
14+
//
15+
// Otherwise, scroll all the way to the bottom.
16+
//
17+
if childStartPoint.y + safeAreaLayoutGuide.layoutFrame.height < contentSize.height {
18+
let targetRect = CGRect(x: 0,
19+
y: childStartPoint.y - Constants.yOffset,
20+
width: Constants.targetRectWidth,
21+
height: safeAreaLayoutGuide.layoutFrame.height)
22+
scrollRectToVisible(targetRect, animated: animated)
23+
} else {
24+
scrollToBottom()
25+
}
26+
27+
// This ensures scrolling to the correct position, especially when there are layout changes
28+
//
29+
// See: https://stackoverflow.com/a/35437399
30+
//
31+
layoutIfNeeded()
32+
}
33+
}
34+
35+
@objc func scrollToBottom() {
36+
let bottomOffset = CGPoint(x: 0, y: contentSize.height - bounds.size.height + adjustedContentInset.bottom)
37+
if bottomOffset.y > 0 {
38+
setContentOffset(bottomOffset, animated: true)
39+
}
40+
}
41+
42+
private enum Constants {
43+
/// An arbitrary placeholder value for the target rect -- must be some value larger than 0
44+
static let targetRectWidth: CGFloat = 1
45+
46+
/// Vertical padding for the target rect
47+
static let yOffset: CGFloat = 24
48+
}
49+
}

WordPress/Classes/ViewRelated/Blog/Blog Details/BlogDetailsViewController+FancyAlerts.swift

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,25 @@ extension BlogDetailsViewController {
1616
self?.refreshSiteIcon()
1717
self?.configureTableViewData()
1818
self?.reloadTableViewPreservingSelection()
19-
if let element = QuickStartTourElement(rawValue: QuickStartTourGuide.shared.currentElementInt()) {
20-
self?.scroll(to: element)
21-
}
2219

2320
if let info = notification.userInfo?[QuickStartTourGuide.notificationElementKey] as? QuickStartTourElement {
2421
switch info {
2522
case .noSuchElement:
26-
self?.additionalSafeAreaInsets = UIEdgeInsets.zero
23+
if FeatureFlag.mySiteDashboard.enabled,
24+
let parentVC = self?.parent as? MySiteViewController {
25+
parentVC.additionalSafeAreaInsets = .zero
26+
} else {
27+
self?.additionalSafeAreaInsets = .zero
28+
}
29+
2730
case .siteIcon, .siteTitle:
2831
// handles the padding in case the element is not in the table view
2932
self?.additionalSafeAreaInsets = UIEdgeInsets(top: 0, left: 0, bottom: BlogDetailsViewController.bottomPaddingForQuickStartNotices, right: 0)
33+
case .pages, .editHomepage, .sharing, .stats:
34+
self?.scroll(to: info)
3035
case .viewSite:
36+
self?.scroll(to: info)
37+
3138
guard let self = self,
3239
let navigationController = self.navigationController,
3340
navigationController.visibleViewController != self else {

WordPress/Classes/ViewRelated/Blog/Blog Details/BlogDetailsViewController.m

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,18 @@ - (void)viewDidLoad
382382
[self startObservingQuickStart];
383383
[self addMeButtonToNavigationBarWithEmail:self.blog.account.email meScenePresenter:self.meScenePresenter];
384384

385-
[self.createButtonCoordinator addTo:self.view trailingAnchor:self.view.safeAreaLayoutGuide.trailingAnchor bottomAnchor:self.view.safeAreaLayoutGuide.bottomAnchor];
385+
if ([Feature enabled:FeatureFlagMySiteDashboard]) {
386+
MySiteViewController *parentVC = (MySiteViewController *)self.parentViewController;
387+
388+
[self.createButtonCoordinator addTo:parentVC.view
389+
trailingAnchor:parentVC.view.safeAreaLayoutGuide.trailingAnchor
390+
bottomAnchor:parentVC.view.safeAreaLayoutGuide.bottomAnchor];
391+
} else {
392+
[self.createButtonCoordinator addTo:self.view
393+
trailingAnchor:self.view.safeAreaLayoutGuide.trailingAnchor
394+
bottomAnchor:self.view.safeAreaLayoutGuide.bottomAnchor];
395+
}
396+
386397
}
387398

388399
/// Resizes the `tableHeaderView` as necessary whenever its size changes.
@@ -410,9 +421,23 @@ - (void)viewWillAppear:(BOOL)animated
410421
[super viewWillAppear:animated];
411422

412423
if ([[QuickStartTourGuide shared] currentElementInt] != NSNotFound) {
413-
self.additionalSafeAreaInsets = UIEdgeInsetsMake(0, 0, [BlogDetailsViewController bottomPaddingForQuickStartNotices], 0);
424+
425+
if ([Feature enabled:FeatureFlagMySiteDashboard]) {
426+
MySiteViewController *parentVC = (MySiteViewController *)self.parentViewController;
427+
parentVC.additionalSafeAreaInsets = UIEdgeInsetsMake(0, 0, [BlogDetailsViewController bottomPaddingForQuickStartNotices], 0);
428+
} else {
429+
self.additionalSafeAreaInsets = UIEdgeInsetsMake(0, 0, [BlogDetailsViewController bottomPaddingForQuickStartNotices], 0);
430+
}
431+
414432
} else {
415-
self.additionalSafeAreaInsets = UIEdgeInsetsZero;
433+
434+
if ([Feature enabled:FeatureFlagMySiteDashboard]) {
435+
MySiteViewController *parentVC = (MySiteViewController *)self.parentViewController;
436+
parentVC.additionalSafeAreaInsets = UIEdgeInsetsZero;
437+
} else {
438+
self.additionalSafeAreaInsets = UIEdgeInsetsZero;
439+
}
440+
416441
}
417442

418443
if (self.splitViewControllerIsHorizontallyCompact) {
@@ -1685,13 +1710,25 @@ - (void)scrollToElement:(QuickStartTourElement) element
16851710
{
16861711
int sectionCount = 0;
16871712
int rowCount = 0;
1713+
1714+
MySiteViewController *parentVC = (MySiteViewController *)self.parentViewController;
1715+
16881716
for (BlogDetailsSection *section in self.tableSections) {
16891717
rowCount = 0;
16901718
for (BlogDetailsRow *row in section.rows) {
16911719
if (row.quickStartIdentifier == element) {
1692-
self.additionalSafeAreaInsets = UIEdgeInsetsMake(0, 0, [BlogDetailsViewController bottomPaddingForQuickStartNotices], 0);
1720+
16931721
NSIndexPath *path = [NSIndexPath indexPathForRow:rowCount inSection:sectionCount];
1694-
[self.tableView scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionTop animated:true];
1722+
1723+
if ([Feature enabled:FeatureFlagMySiteDashboard]) {
1724+
parentVC.additionalSafeAreaInsets = UIEdgeInsetsMake(0, 0, [BlogDetailsViewController bottomPaddingForQuickStartNotices], 0);
1725+
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:path];
1726+
[parentVC.scrollView scrollToView:cell animated:true];
1727+
} else {
1728+
self.additionalSafeAreaInsets = UIEdgeInsetsMake(0, 0, [BlogDetailsViewController bottomPaddingForQuickStartNotices], 0);
1729+
[self.tableView scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionTop animated:true];
1730+
}
1731+
16951732
}
16961733
rowCount++;
16971734
}
@@ -1911,7 +1948,12 @@ - (void)showViewSiteFromSource:(BlogDetailsNavigationSource)source
19111948
[[QuickStartTourGuide shared] completeViewSiteTourForBlog:self.blog];
19121949
}
19131950

1914-
self.additionalSafeAreaInsets = UIEdgeInsetsZero;
1951+
if ([Feature enabled:FeatureFlagMySiteDashboard]) {
1952+
MySiteViewController *parentVC = (MySiteViewController *)self.parentViewController;
1953+
parentVC.additionalSafeAreaInsets = UIEdgeInsetsZero;
1954+
} else {
1955+
self.additionalSafeAreaInsets = UIEdgeInsetsZero;
1956+
}
19151957
}
19161958

19171959
- (void)showViewAdmin

WordPress/Classes/ViewRelated/Blog/My Site/MySiteViewController.swift

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ class MySiteViewController: UIViewController, NoResultsViewHost {
2121
return segmentedControl.selectedSegmentIndex == Section.dashboard.rawValue
2222
}
2323

24-
private lazy var scrollView: UIScrollView = {
24+
@objc
25+
private(set) lazy var scrollView: UIScrollView = {
2526
let scrollView = UIScrollView()
2627
scrollView.translatesAutoresizingMaskIntoConstraints = false
2728
scrollView.refreshControl = refreshControl
@@ -193,16 +194,13 @@ class MySiteViewController: UIViewController, NoResultsViewHost {
193194
}
194195

195196
view.addSubview(scrollView)
197+
view.pinSubviewToAllEdges(scrollView)
196198
scrollView.addSubview(stackView)
197199
scrollView.pinSubviewToAllEdges(stackView)
198200
segmentedControlContainerView.addSubview(segmentedControl)
199201
stackView.addArrangedSubviews([segmentedControlContainerView])
200202

201203
NSLayoutConstraint.activate([
202-
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
203-
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
204-
scrollView.topAnchor.constraint(equalTo: view.topAnchor),
205-
scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
206204
stackView.widthAnchor.constraint(equalTo: view.widthAnchor),
207205
segmentedControl.leadingAnchor.constraint(equalTo: segmentedControlContainerView.leadingAnchor,
208206
constant: Constants.segmentedControlXOffset),

WordPress/Classes/ViewRelated/Blog/Site Picker/SitePickerViewController+QuickStart.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ extension SitePickerViewController {
2525
self?.additionalSafeAreaInsets = UIEdgeInsets.zero
2626
case .siteIcon, .siteTitle:
2727
// handles the padding in case the element is not in the table view
28-
self?.additionalSafeAreaInsets = UIEdgeInsets(top: 0, left: 0, bottom: BlogDetailsViewController.bottomPaddingForQuickStartNotices, right: 0)
28+
guard let parentVC = self?.parent as? MySiteViewController else {
29+
return
30+
}
31+
parentVC.additionalSafeAreaInsets = UIEdgeInsets(top: 0, left: 0, bottom: BlogDetailsViewController.bottomPaddingForQuickStartNotices, right: 0)
2932
default:
3033
break
3134
}

WordPress/Classes/ViewRelated/Blog/Site Picker/SitePickerViewController.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,10 @@ extension SitePickerViewController {
242242
tourGuide.completeViewSiteTour(forBlog: blog)
243243
}
244244

245-
additionalSafeAreaInsets = .zero
245+
guard let parentVC = parent as? MySiteViewController else {
246+
return
247+
}
248+
parentVC.additionalSafeAreaInsets = .zero
246249
}
247250
}
248251

WordPress/WordPress.xcodeproj/project.pbxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2745,6 +2745,8 @@
27452745
FA1ACAA21BC6E45D00DDDCE2 /* WPStyleGuide+Themes.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA1ACAA11BC6E45D00DDDCE2 /* WPStyleGuide+Themes.swift */; };
27462746
FA1CEAC225CA9C2A005E7038 /* RestoreStatusFailedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA1CEAC125CA9C2A005E7038 /* RestoreStatusFailedView.swift */; };
27472747
FA1CEAD425CA9C40005E7038 /* RestoreStatusFailedView.xib in Resources */ = {isa = PBXBuildFile; fileRef = FA1CEAD325CA9C40005E7038 /* RestoreStatusFailedView.xib */; };
2748+
FA20751427A86B73001A644D /* UIScrollView+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA20751327A86B73001A644D /* UIScrollView+Helpers.swift */; };
2749+
FA20751527A86B73001A644D /* UIScrollView+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA20751327A86B73001A644D /* UIScrollView+Helpers.swift */; };
27482750
FA25FA212609AA9C0005E08F /* AppConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA25F9FD2609AA830005E08F /* AppConfiguration.swift */; };
27492751
FA25FA342609AAAA0005E08F /* AppConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA25FA332609AAAA0005E08F /* AppConfiguration.swift */; };
27502752
FA347AED26EB6E300096604B /* GrowAudienceCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA347AEB26EB6E300096604B /* GrowAudienceCell.swift */; };
@@ -7510,6 +7512,7 @@
75107512
FA1ACAA11BC6E45D00DDDCE2 /* WPStyleGuide+Themes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "WPStyleGuide+Themes.swift"; sourceTree = "<group>"; };
75117513
FA1CEAC125CA9C2A005E7038 /* RestoreStatusFailedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RestoreStatusFailedView.swift; sourceTree = "<group>"; };
75127514
FA1CEAD325CA9C40005E7038 /* RestoreStatusFailedView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = RestoreStatusFailedView.xib; sourceTree = "<group>"; };
7515+
FA20751327A86B73001A644D /* UIScrollView+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIScrollView+Helpers.swift"; sourceTree = "<group>"; };
75137516
FA25F9FD2609AA830005E08F /* AppConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppConfiguration.swift; sourceTree = "<group>"; };
75147517
FA25FA332609AAAA0005E08F /* AppConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppConfiguration.swift; sourceTree = "<group>"; };
75157518
FA2D12891BCED0AD006F2A15 /* WordPress 40.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "WordPress 40.xcdatamodel"; sourceTree = "<group>"; };
@@ -12785,6 +12788,7 @@
1278512788
FE02F95E269DC14A00752A44 /* Comment+Interface.swift */,
1278612789
C3C39B0626F50D3900B1238D /* WordPressSupportSourceTag+Editor.swift */,
1278712790
179A70EF2729834B006DAC0A /* Binding+OnChange.swift */,
12791+
FA20751327A86B73001A644D /* UIScrollView+Helpers.swift */,
1278812792
);
1278912793
path = Extensions;
1279012794
sourceTree = "<group>";
@@ -18216,6 +18220,7 @@
1821618220
436110E022C4241A000773AD /* UIColor+MurielColorsObjC.swift in Sources */,
1821718221
B5B68BD41C19AAED00EB59E0 /* InteractiveNotificationsManager.swift in Sources */,
1821818222
46183CF5251BD658004F9AFD /* PageTemplateLayout+CoreDataProperties.swift in Sources */,
18223+
FA20751427A86B73001A644D /* UIScrollView+Helpers.swift in Sources */,
1821918224
981D464825B0D4E7000AA65C /* ReaderSeenAction.swift in Sources */,
1822018225
F57402A7235FF9C300374346 /* SchedulingDate+Helpers.swift in Sources */,
1822118226
4395A15D2106718900844E8E /* QuickStartChecklistCell.swift in Sources */,
@@ -19759,6 +19764,7 @@
1975919764
FABB22202602FC2C00C8785C /* CustomHighlightButton.m in Sources */,
1976019765
FABB22212602FC2C00C8785C /* UniversalLinkRouter.swift in Sources */,
1976119766
FABB22222602FC2C00C8785C /* LightNavigationController.swift in Sources */,
19767+
FA20751527A86B73001A644D /* UIScrollView+Helpers.swift in Sources */,
1976219768
FABB22232602FC2C00C8785C /* PluginDirectoryCollectionViewCell.swift in Sources */,
1976319769
FABB22242602FC2C00C8785C /* GutenbergNetworking.swift in Sources */,
1976419770
FABB22252602FC2C00C8785C /* NavigationActionHelpers.swift in Sources */,

0 commit comments

Comments
 (0)