Create Modal Layout Picker Container for new Gutenberg pages and feature flag for development#14501
Conversation
…tions" This reverts commit 1d6f65f.
Generated by 🚫 dangerJS |
|
You can trigger optional UI/connected tests for these changes by visiting CircleCI here. |
It looks like chrome system material is available on iOS 13+ so I can apply the standard blur on lower versions (this is what the footer had on previous builds). The way I have the header set up I'll need to make some changes to the layout to get that working but I can get that wrapped up in the morning probably. As for the animation of the title view, I got that setup. Let me know what you think about it. The only piece I couldn't get working great is when you scroll quickly you'll see both headers as one scrolls into view and the other is animating out. I just triggered a new build so that should be ready soon if you want to give it a try while I adjust the header. |
Sounds good 👍
This feels really solid. The momentary double-title thing doesn't bother me a whole lot, but if you are able to solve it then even better. 😀 |
There was a problem hiding this comment.
Thank you for the update @chipsnyder - It's looking a lot better now! 🙏
Landscape mode on iPhone 7 is now much better! 🎉
I added a few of code comments, only the one related to accessibility label might be a blocker for now.
The momentary double-title thing doesn't bother me a whole lot, but if you are able to solve it then even better. 😀
About the animation, it also looks good to me :)
I did a fast test anchoring the title's alpha value to the largeTitleView.frame.maxY value and got an interesting result:
In this way the alpha animation speed is controlled by the scroll itself. Seems simple enough to be implemented in this round but I won't block on this one 👍
| } | ||
|
|
||
| private static func showLayoutPicker(from controller: UIViewController, _ completion: @escaping TemplateSelectionCompletion) { | ||
| let storyboard = UIStoryboard(name: "LayoutPickerStoryboard", bundle: Bundle.main) |
There was a problem hiding this comment.
Could we have a convenience initializer here? It could return an optional instance of GutenbergLayoutPickerViewController, and its navigation controller can be accessed via UIViewController property.
Also, we have a StoryboardLoadable protocol that might be helpful
Alternatively, we could also instantiate the NavigationController in code and set its root controller to what we want. In this way the Storyboard only holds the Controller we are interested in (GutenbergLayoutPickerViewController in this case). And both the custom Navigation Controller and the Layout picker can also be used separately if needed in the future. But this also works well so ✅
There was a problem hiding this comment.
both the custom Navigation Controller and the Layout picker can also be used separately if needed in the future.
This would still be possible in one storyboard. The Navigation Controller can still be created programmatically with the standard UINavigationController init methods. I can add a storyboardID to the Gutenberg Layout Picker View Controller Scene to allow the instantiation of that separately if needed.
Alternatively, we could also instantiate the NavigationController in code and set its root controller
I'm happy to switch this over if that's our standard practice. My goal here was to follow Apple's recommendation that the storyboard contains all of the design-time elements that are related to the flow of a set of screens. GutenbergLayoutPickerViewController assumes that the navigation controller is an instance of GutenbergLightNavigationController to hide the bar's shadow properly. Although with the changes I'll be making to add the visual effects @iamthomasbishop requested, I'll hide the navigation bar for this view instead. However, GutenbergLightNavigationController does still have other considerations in it to enforce the flow displays correctly, and using the view without a navigation controller won't work as we build out the preview button which will push a new view controller.
Since this felt more connected in the flow of the UI I felt the storyboard should include it to provide the full picture. If that time came when we did want to reuse the root view controller, that would still be doable with minimal code changes. Being forced to make those changes would also prompt the future developer to consider the best way to handle the design settings of the navigation controller to accommodate all of the uses.
Ultimately I think either approach will work, I just wanted to share my thoughts on it, and I'm happy to proceed in whichever way you feel is best and most consistent.
There was a problem hiding this comment.
Thanks for the detail explanation!
Originally the main idea behind my suggestion was to hide the required init steps and configuration inside the GutenbergLayoutPickerViewController, in a way that PageCoordinator.swift doesn't need to know about storyboard details that seems internal to the controller (specially with it being tightly bounded with the navigation controller).
The Storyboard config as you explained it makes perfect sense to me! Let's keep it this way.
| <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> | ||
| <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> | ||
| <color key="backgroundColor" systemColor="systemFillColor" red="0.47058823529999999" green="0.47058823529999999" blue="0.50196078430000002" alpha="0.20000000000000001" colorSpace="custom" customColorSpace="sRGB"/> | ||
| <accessibility key="accessibilityConfiguration" label="Close"/> |
There was a problem hiding this comment.
It's more recomendable to set accessibility labels via code so they are translated.
There was a problem hiding this comment.
Is this more related to how we handle localization for our app? ie should I be setting all text programmatically?
If I localize the storyboard I get:
/* Class = "UIButton"; accessibilityLabel = "Close"; ObjectID = "Fgx-ig-LXQ"; */
"Fgx-ig-LXQ.accessibilityLabel" = "Close";
But if we don't localize the storyboards then I can move the other text values over.
There was a problem hiding this comment.
Is this more related to how we handle localization for our app? ie should I be setting all text programmatically?
Yes I believe so. Our Localization scripts make use of NSLocalizedString to gather and send the strings to GlotPress, so using localized storyboard I believe it won't work.
There was a problem hiding this comment.
Thanks for the info! I'll move those strings over.
There was a problem hiding this comment.
Thank you!
Here's some info about localization best practices (from our team):
https://github.com/wordpress-mobile/WordPress-iOS/blob/develop/docs/localization.md
WordPress/Classes/ViewRelated/Gutenberg/Layout Picker/GutenbergLayoutPickerViewController.swift
Outdated
Show resolved
Hide resolved
I'm going to revisit this path to solve the double case. It looks like you're using a different anchor point than I was. The way I tried it originally was phasing in the other small title by the % that the big title was off the screen and it didn't look great, because you would see both. I'm not sure I fully understand what you mean by Can you share the snippit you used for your quick test? |
|
@iamthomasbishop and @etoledom This is updated now with a new build ( I also didn't make any changes to the header animation. I started building in a cancel for that, but it started causing crashes. So I figured that might be better to adjust toward the end if we still want to. |
|
By
This is a quite rough example (edited a bit more concise): func scrollViewDidScroll(_ scrollView: UIScrollView) {
// ....
let alpha = (-largeTitleView.frame.maxY / 10.0).clamp(min: 0, max: 1)
titleView.isHidden = alpha == 0
titleView.alpha = alpha
}Then you removed everything related to There might be other considerations too with the code to handle small screen sizes. |
I agree with this too! 👍 |
|
@etoledom Those static strings have been moved to be programmatic now. I left the original values for the labels in place just to help the system guess an appropriate intrinsic size after loading. |
Ah ok, I see what you're doing here. When I did it, I originally had So as the large title was getting close to disappearing, the small title would appear, and then you ended up with a case where both were showing which I didn't like. I put this in place, and it seems to be working well. I just needed to make some adjustments to when it "snaps" into place and when entering compact views. There is an additional point in the scrolling where you don't see either header in this approach compared to the other however the "snap" fixes that so it wouldn't really be noticeable. Just as a quick aside where did you come up with the Edit: After doing some more testing on this approach I'm noticing the view flashes a bit. Since we're happy with the animation the way it is I think I would prefer to explore this approach at a later time. WDYT? |
There was a problem hiding this comment.
Thank you for the update!
With the changes on the header, is it still necessary to have a custom Navigation Controller?
After doing some more testing on this approach I'm noticing the view flashes a bit. Since we're happy with the animation the way it is I think I would prefer to explore this approach at a later time. WDYT?
Absolutely, let's not block this PR on the animation 👍
Just as a quick aside where did you come up with the 10? Or is this just a magic number that felt right?
Yeah, it's a magic number.
I noticed that maxY changed around 1 to 10 in the range we were interested in, so dividing that by 10 looked like a good option. But doesn't have to be strictly 10.
(Looks like kind of a t = d/v equation 🤔, so 10 would be the velocity of the transition).
About the glitch (for a future PR):
We could try fix that glitch if we start the alpha changes a bit earlier. Let's say half height of the largeTitleView earlier. Something like:
let alpha = -(maxY - (height / 2)) / 10
Very similar to what you had previously :)
In this way on the snap position, the calculation already gives alpha = 1 and it won't jump to other values.
Let's move ahead, this looks good and feels great! Nice job @chipsnyder 🎉
|
Thanks @etoledom, I appreciate your great review :)
The style for the navigation bar when we push the Preview screen is a bit different than the existing Light Navigation Controller so we'll still want the customized one for that. |


Fixes: wordpress-mobile/gutenberg-mobile#2419
Related PRs:
gutenberg-mobile: Disable Page Template picker if modal layout picker is available (Update for new capabilities mechanism) gutenberg-mobile#2505gutenberg: [Mobile] Disable Page Template picker if modal layout picker is available (Update for new capabilities mechanism) WordPress/gutenberg#24170Description
Adds feature flags and a container view for creating a new modal layout for page creation in Gutenberg.
To test:
To disable or enable the development version of Modal Layout Picker
To toggle:
Classic Editor and Gutenberg Editor with Modal Layout Picker Disabled.
Note: Modal Layout Picker should be disabled and uneditable in any Release build
Gutenberg Editor with Modal Layout Picker Enabled
On the Modal Layout Picker
Dismissing the modal
Continuing to scroll down after reaching the top should dismiss the modal
Screenshots:
Additional Context
This PR was branched off #14456 using a slightly different approach. For design feedback history please see that PR.
There are some poor layout issues in landscape mode, specifically with larger dynamic fonts. The plan is to revisit landscape at a later point after more of the screen is filled out.
PR submission checklist:
RELEASE-NOTES.txtif necessary.