Skip to content

Draft: Liquid Glass Adaptation on UIScrollView#4275

Open
johnzhou721 wants to merge 29 commits intobeeware:mainfrom
johnzhou721:solarium
Open

Draft: Liquid Glass Adaptation on UIScrollView#4275
johnzhou721 wants to merge 29 commits intobeeware:mainfrom
johnzhou721:solarium

Conversation

@johnzhou721
Copy link
Copy Markdown
Contributor

@johnzhou721 johnzhou721 commented Mar 26, 2026

This PR implements the automatic extension of UIScrollViews and other scrolling widgets into system bar areas on iOS. This ensures that system effects can apply over these scroll views, ensuring native appearances.

This also takes the opportunity to fix issues regarding the calculation of scroll insets in scroll and maximum positions, and also for the content layout size.

The logic is this:

  • On each Container is a flag of whether ScrollContainers can extend into each edge. For MainWindows on iOS, this flag is True.
  • If a ScrollContainer is scrollable and reaches an edge, the bounds are extended into unsafe area. On iOS 18, there is an additional requirement that the ScrollContainer must be the content of the container; this is because of questions such as https://stackoverflow.com/questions/49845927/uitableview-wont-scroll-behind-blur-views-tab-bar-or-navigation-bar that indicates that the detection mechanism for the blurring of the navigation bar is unreliable on iOS 18, but for iOS 26 it works for arbitrary layouts.

Tests are also added. This is especially vital to Liquid Glass effects, but it enables the scroll edge effect for iOS 18- as well.

OptionContainers/tab bars are not handled, because the current view hierarchy prevents them from being handled correctly, until #4299 is fixed.

FAQ:

  1. How are nested scroll views dealed with? — currently there is no handling; this is because vertical scroll views nested in a large horizontal one do not get the proper top bar blur when the verticle scroll views scroll up. This will change with horizontal scroll views nested in a vertical scroller when there is a Sidebar on iOS 26+; I have a logic planned will share details on how those are handled later.

Missing:

  • Detect iOS 18 broken blur effect in some cases
  • Add appropriate parameters to other types of scrolling content:
    • DetailedList
    • MapView
    • WebView
  • Audit scroll control behaviors
  • Fix up existing tests
  • Add new tests for behavior
    • TODO: Test contnet inset behavior
  • Document behavior

PR Checklist:

  • All new features have been tested
  • All new features have been documented
  • I have read the CONTRIBUTING.md file
  • I will abide by the code of conduct

@johnzhou721 johnzhou721 marked this pull request as draft March 26, 2026 01:38
# a scrolling event is unreliable.
@objc_method
def wantsForwardedScrollEventsForAxis_(self, axis: int) -> None: # pragma: no cover
def wantsForwardedScrollEventsForAxis_(self, axis: int) -> bool: # pragma: no cover
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drive-by fix.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW: I've opened a separate #4370 for this drive-by, so that we can get it in sooner.

@johnzhou721
Copy link
Copy Markdown
Contributor Author

johnzhou721 commented Apr 26, 2026

Before I finalize this by adding other widgets to use this fix and adding tests, I would like to provide insights on what type of issues are being solved here.  I'm going to do all of these with the example app in this branch (which I've modified to show these effects)
 

  1. With the example app in this branch, ScrollContainers now transparenty extend beyond standard areas into top bar without compromising usability by way of system effects and correct insets.  This is always done on iOS 26, and on iOS 18 or design compatibility mode, it is only done if the scrollcontainer is the content of the window itself.  This is because iOS 18 fails to apply these system effects if the view hierarchy is more complex.  On iOS 18 and 26, this will not work for bottom OptionContainer bar, as they will be refactored anyways to use Scaffolds.
     
    Before, iOS 18 and 26 (18 has small visual differences in the controls, but the scrollview is the same appearnce):
     
    https://github.com/user-attachments/assets/85ac4ce6-c98d-4900-916d-83178ced0fc9
     
    After, iOS 26:
     
    https://github.com/user-attachments/assets/bfcaaf1b-f219-4a00-99f4-cf371cf44fb7
     
    After, iOS 18 — note, the Toggle Controls button reassigns window content to just be the scroll view itself:
     
    https://github.com/user-attachments/assets/a150657f-f354-45e3-8349-448703932db9
     
  2. When a ScrollContainer has a width or height smaller than that of the scrollable area, vertically it can still be "bounced".  Vertical and non-tall here.
     
    Before, iOS 18 and 26 — they have same conceptual visual appearnace but may contain minor rendering differences
     
    https://github.com/user-attachments/assets/f1b7e053-473c-4a27-bec7-1b466849b69e
     
    After, iOS 18 and 26 — they have same conceptual visual appearnace but may contain minor rendering differences
     
    https://github.com/user-attachments/assets/fa401e25-fc62-4788-ad94-7b7bb5bde98e
     
    A side-effect of this is that the system will know to insert padding in the scrollable direction properly to avoid notches, and align the Toga interface “scrollable” to the actual scrollable detections used by the native system.
     
  3. When a ScrollContainer overlaps with the bars/notch in the scrollable direction (after the fix in item 3, these areas will be padded consistently by the system), the layout height is now correct.  Below, I pressed Toggle Controls to ensrue that the scroll container is the content of hte window itself, and Tall is turned off.
     
    Before, iOS 18 and 26 — they have same conceptual visual appearnace but may contain minor rendering differences
     
image   **After, iOS 18 and 26 — they have same conceptual visual appearnace but may contain minor rendering differences**   Screenshot 2026-04-25 at 19 17 34
  1. I've also ensured that the scrolling parameters (offset, maximum) are computed properly. Although note that we should press "update scroll params" to view the latest scroll paramaters, because layout is asynchronous.

@johnzhou721
Copy link
Copy Markdown
Contributor Author

This is now ready for review.

@johnzhou721 johnzhou721 marked this pull request as ready for review May 4, 2026 23:20
@johnzhou721
Copy link
Copy Markdown
Contributor Author

@kattni Sorry for tagging you in, but since you answered an equivalent question for @HalfWhitt at #4362 (comment), would you recommend I use ScrollContainers instead of ScrollContainers in the docs? In this case, ScrollContainer is already used as a plural noun, so I went with ScrollContainers, but I want your opinion on this.

@kattni
Copy link
Copy Markdown
Contributor

kattni commented May 5, 2026

@johnzhou721 Actually, we had a conversation beyond that, that wasn't documented. The way to handle this with classes that are also descriptive of the item is make it two separate words, in this case: scroll containers. We shifted to "drawing actions" when discussing anything in plural in the docs in 4362. This isn't a universal solution; we'll take it on a case-by-case basis. For this, it works.

@johnzhou721
Copy link
Copy Markdown
Contributor Author

@johnzhou721 Actually, we had a conversation beyond that, that wasn't documented. The way to handle this with classes that are also descriptive of the item is make it two separate words, in this case: scroll containers. We shifted to "drawing actions" when discussing anything in plural in the docs in 4362. This isn't a universal solution; we'll take it on a case-by-case basis. For this, it works.

By "this" in the last sentence, you mean what I have in this PR? Thanks.

@kattni
Copy link
Copy Markdown
Contributor

kattni commented May 5, 2026

@johnzhou721 Yes. Please use "scroll containers" when referencing the concept of a "scroll container", versus directly referencing the ScrollContainer class.

In your update, I believe all references to "ScrollContainer" and "ScrollContainers" can be replaced with "scroll container" and "scroll containers".

@johnzhou721
Copy link
Copy Markdown
Contributor Author

johnzhou721 commented May 5, 2026

@kattni Thank you for the information; I've updated every file except for bugfix.2 changenote, where it explicitly references the functinos on the ScrollContainer class.

EDIT:: This PR is still ready for review after the change, cfdce36.

@freakboy3742
Copy link
Copy Markdown
Member

To set expectations - I'm currently in the middle of preparations for PyCon US, and I also need to set up my new laptop so it will let me test Liquid Glass stuff; unless all that is resolved before I fly out, it will be a couple of weeks before I get around to review this.

@johnzhou721
Copy link
Copy Markdown
Contributor Author

To set expectations - I'm currently in the middle of preparations for PyCon US, and I also need to set up my new laptop so it will let me test Liquid Glass stuff; unless all that is resolved before I fly out, it will be a couple of weeks before I get around to review this.

Thanks for letting me know. Have fun at PyCon US! (For the second year in a row, I cannot go.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants