| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,29 @@ | |||
| 1 | + import { Observable } from "tns-core-modules/data/observable"; | ||
| 2 | + import { ScrollView } from "tns-core-modules/ui/scroll-view"; | ||
| 3 | + | ||
| 4 | + export class LayoutOutsideScrollViewModel extends Observable { | ||
| 5 | + content: string = "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium," + | ||
| 6 | + "totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. " + | ||
| 7 | + "Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos " + | ||
| 8 | + "qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, " + | ||
| 9 | + "adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. " + | ||
| 10 | + "Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? " + | ||
| 11 | + "Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, " + | ||
| 12 | + "vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"; | ||
| 13 | + isVisible: boolean = true; | ||
| 14 | + | ||
| 15 | + onChangeVisibility() { | ||
| 16 | + this.isVisible = !this.isVisible; | ||
| 17 | + this.notifyPropertyChange("isVisible", this.isVisible); | ||
| 18 | + } | ||
| 19 | + | ||
| 20 | + onScrollToBottom(args) { | ||
| 21 | + const scrollView = <ScrollView>args.object.page.getViewById("scroll-view"); | ||
| 22 | + scrollView.scrollToVerticalOffset(scrollView.scrollableHeight, false); | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + onScrollToTop(args) { | ||
| 26 | + const scrollView = <ScrollView>args.object.page.getViewById("scroll-view"); | ||
| 27 | + scrollView.scrollToVerticalOffset(0, false); | ||
| 28 | + } | ||
| 29 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,11 @@ | |||
| 1 | + import { EventData as ObservableEventData } from "tns-core-modules/data/observable"; | ||
| 2 | + import { Page } from "tns-core-modules/ui/page"; | ||
| 3 | + import { LayoutOutsideScrollViewModel } from "./layout-outside-scroll-view-model"; | ||
| 4 | + | ||
| 5 | + var viewModel = new LayoutOutsideScrollViewModel(); | ||
| 6 | + | ||
| 7 | + export function pageLoaded(args: ObservableEventData) { | ||
| 8 | + var page = <Page>args.object; | ||
| 9 | + | ||
| 10 | + page.bindingContext = viewModel; | ||
| 11 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,19 @@ | |||
| 1 | + <Page xmlns="http://schemas.nativescript.org/tns.xsd" loaded="pageLoaded" class="page"> | ||
| 2 | + <ScrollView id="scroll-view"> | ||
| 3 | + <StackLayout> | ||
| 4 | + <GridLayout rows="auto, auto, auto" backgroundColor="lightgray"> | ||
| 5 | + <Button row="0" text="Change w/ Visibility" tap="{{ onChangeVisibility }}"></Button> | ||
| 6 | + <Button row="1" text="Scroll To Bottom" tap="{{ onScrollToBottom }}"></Button> | ||
| 7 | + <Label row="2" visibility="{{ isVisible ? 'visible' : 'collapsed' }}" text="{{ content }}" color="black"></Label> | ||
| 8 | + </GridLayout> | ||
| 9 | + | ||
| 10 | + <GridLayout height="2000" backgroundColor="yellow"></GridLayout> | ||
| 11 | + | ||
| 12 | + <GridLayout rows="auto, auto, auto" backgroundColor="lightgray"> | ||
| 13 | + <Button row="0" text="Change w/ Visibility" tap="{{ onChangeVisibility }}"></Button> | ||
| 14 | + <Button row="1" text="Scroll To Top" tap="{{ onScrollToTop }}"></Button> | ||
| 15 | + <Label row="2" visibility="{{ isVisible ? 'visible' : 'collapsed' }}" text="{{ content }}" color="black"></Label> | ||
| 16 | + </GridLayout> | ||
| 17 | + </StackLayout> | ||
| 18 | + </ScrollView> | ||
| 19 | + </Page> | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -16,5 +16,6 @@ export function loadExamples() { | |||
| 16 | 16 | examples.set("safe-area-sub-element", "scroll-view/safe-area-sub-element"); | |
| 17 | 17 | examples.set("safe-area-images", "scroll-view/safe-area-images"); | |
| 18 | 18 | examples.set("safe-area-images-overflow", "scroll-view/safe-area-images-overflow"); | |
| 19 | + examples.set("layout-outside-scroll", "scroll-view/layout-outside-scroll"); | ||
| 19 | 20 | return examples; | |
| 20 | 21 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -789,36 +789,32 @@ export namespace ios { | |||
| 789 | 789 | } | |
| 790 | 790 | ||
| 791 | 791 | export function expandBeyondSafeArea(view: View, frame: CGRect): CGRect { | |
| 792 | - const locationInWindow = view.getLocationInWindow(); | ||
| 793 | - const inWindowLeft = layout.round(layout.toDevicePixels(locationInWindow.x)); | ||
| 794 | - const inWindowTop = layout.round(layout.toDevicePixels(locationInWindow.y)); | ||
| 795 | - const inWindowRight = inWindowLeft + layout.round(layout.toDevicePixels(frame.size.width)); | ||
| 796 | - const inWindowBottom = inWindowTop + layout.round(layout.toDevicePixels(frame.size.height)); | ||
| 797 | - | ||
| 798 | - const availableSpace = getAvailableSpaceFromParent(view); | ||
| 792 | + const availableSpace = getAvailableSpaceFromParent(view, frame); | ||
| 799 | 793 | const safeArea = availableSpace.safeArea; | |
| 800 | 794 | const fullscreen = availableSpace.fullscreen; | |
| 795 | + const inWindow = availableSpace.inWindow; | ||
| 801 | 796 | ||
| 802 | 797 | const position = ios.getPositionFromFrame(frame); | |
| 803 | 798 | const safeAreaPosition = ios.getPositionFromFrame(safeArea); | |
| 804 | 799 | const fullscreenPosition = ios.getPositionFromFrame(fullscreen); | |
| 800 | + const inWindowPosition = ios.getPositionFromFrame(inWindow); | ||
| 805 | 801 | ||
| 806 | 802 | const adjustedPosition = position; | |
| 807 | 803 | ||
| 808 | - if (position.left && inWindowLeft <= safeAreaPosition.left) { | ||
| 804 | + if (position.left && inWindowPosition.left <= safeAreaPosition.left) { | ||
| 809 | 805 | adjustedPosition.left = fullscreenPosition.left; | |
| 810 | 806 | } | |
| 811 | 807 | ||
| 812 | - if (position.top && inWindowTop <= safeAreaPosition.top) { | ||
| 808 | + if (position.top && inWindowPosition.top <= safeAreaPosition.top) { | ||
| 813 | 809 | adjustedPosition.top = fullscreenPosition.top; | |
| 814 | 810 | } | |
| 815 | 811 | ||
| 816 | - if (inWindowRight < fullscreenPosition.right && inWindowRight >= safeAreaPosition.right + fullscreenPosition.left) { | ||
| 817 | - adjustedPosition.right += fullscreenPosition.right - inWindowRight; | ||
| 812 | + if (inWindowPosition.right < fullscreenPosition.right && inWindowPosition.right >= safeAreaPosition.right + fullscreenPosition.left) { | ||
| 813 | + adjustedPosition.right += fullscreenPosition.right - inWindowPosition.right; | ||
| 818 | 814 | } | |
| 819 | 815 | ||
| 820 | - if (inWindowBottom < fullscreenPosition.bottom && inWindowBottom >= safeAreaPosition.bottom + fullscreenPosition.top) { | ||
| 821 | - adjustedPosition.bottom += fullscreenPosition.bottom - inWindowBottom; | ||
| 816 | + if (inWindowPosition.bottom < fullscreenPosition.bottom && inWindowPosition.bottom >= safeAreaPosition.bottom + fullscreenPosition.top) { | ||
| 817 | + adjustedPosition.bottom += fullscreenPosition.bottom - inWindowPosition.bottom; | ||
| 822 | 818 | } | |
| 823 | 819 | ||
| 824 | 820 | const adjustedFrame = CGRectMake(layout.toDeviceIndependentPixels(adjustedPosition.left), layout.toDeviceIndependentPixels(adjustedPosition.top), layout.toDeviceIndependentPixels(adjustedPosition.right - adjustedPosition.left), layout.toDeviceIndependentPixels(adjustedPosition.bottom - adjustedPosition.top)); | |
@@ -849,37 +845,54 @@ export namespace ios { | |||
| 849 | 845 | layoutParent(view.parent); | |
| 850 | 846 | } | |
| 851 | 847 | ||
| 852 | - function getAvailableSpaceFromParent(view: View): { safeArea: CGRect, fullscreen: CGRect } { | ||
| 848 | + function getAvailableSpaceFromParent(view: View, frame: CGRect): { safeArea: CGRect, fullscreen: CGRect, inWindow: CGRect } { | ||
| 853 | 849 | if (!view) { | |
| 854 | 850 | return; | |
| 855 | 851 | } | |
| 856 | 852 | ||
| 857 | - let fullscreen = null; | ||
| 858 | - let safeArea = null; | ||
| 853 | + let scrollView = null; | ||
| 854 | + let viewControllerView = null; | ||
| 859 | 855 | ||
| 860 | 856 | if (view.viewController) { | |
| 861 | - const nativeView = view.viewController.view; | ||
| 862 | - safeArea = nativeView.safeAreaLayoutGuide.layoutFrame; | ||
| 863 | - fullscreen = nativeView.frame; | ||
| 857 | + viewControllerView = view.viewController.view; | ||
| 864 | 858 | } else { | |
| 865 | 859 | let parent = view.parent as View; | |
| 866 | 860 | while (parent && !parent.viewController && !(parent.nativeViewProtected instanceof UIScrollView)) { | |
| 867 | 861 | parent = parent.parent as View; | |
| 868 | 862 | } | |
| 869 | 863 | ||
| 870 | 864 | if (parent.nativeViewProtected instanceof UIScrollView) { | |
| 871 | - const nativeView = parent.nativeViewProtected; | ||
| 872 | - const insets = nativeView.safeAreaInsets; | ||
| 873 | - safeArea = CGRectMake(insets.left, insets.top, nativeView.contentSize.width - insets.left - insets.right, nativeView.contentSize.height - insets.top - insets.bottom); | ||
| 874 | - fullscreen = CGRectMake(0, 0, nativeView.contentSize.width, nativeView.contentSize.height); | ||
| 865 | + scrollView = parent.nativeViewProtected; | ||
| 875 | 866 | } else if (parent.viewController) { | |
| 876 | - const nativeView = parent.viewController.view; | ||
| 877 | - safeArea = nativeView.safeAreaLayoutGuide.layoutFrame; | ||
| 878 | - fullscreen = nativeView.frame; | ||
| 867 | + viewControllerView = parent.viewController.view; | ||
| 879 | 868 | } | |
| 880 | 869 | } | |
| 881 | 870 | ||
| 882 | - return { safeArea: safeArea, fullscreen: fullscreen } | ||
| 871 | + let fullscreen = null; | ||
| 872 | + let safeArea = null; | ||
| 873 | + | ||
| 874 | + if (viewControllerView) { | ||
| 875 | + safeArea = viewControllerView.safeAreaLayoutGuide.layoutFrame; | ||
| 876 | + fullscreen = viewControllerView.frame; | ||
| 877 | + } | ||
| 878 | + else if (scrollView) { | ||
| 879 | + const insets = scrollView.safeAreaInsets; | ||
| 880 | + safeArea = CGRectMake(insets.left, insets.top, scrollView.contentSize.width - insets.left - insets.right, scrollView.contentSize.height - insets.top - insets.bottom); | ||
| 881 | + fullscreen = CGRectMake(0, 0, scrollView.contentSize.width, scrollView.contentSize.height); | ||
| 882 | + } | ||
| 883 | + | ||
| 884 | + const locationInWindow = view.getLocationInWindow(); | ||
| 885 | + let inWindowLeft = locationInWindow.x; | ||
| 886 | + let inWindowTop = locationInWindow.y; | ||
| 887 | + | ||
| 888 | + if (scrollView) { | ||
| 889 | + inWindowLeft += scrollView.contentOffset.x; | ||
| 890 | + inWindowTop += scrollView.contentOffset.y; | ||
| 891 | + } | ||
| 892 | + | ||
| 893 | + const inWindow = CGRectMake(inWindowLeft, inWindowTop, frame.size.width, frame.size.height); | ||
| 894 | + | ||
| 895 | + return { safeArea: safeArea, fullscreen: fullscreen, inWindow: inWindow } | ||
| 883 | 896 | } | |
| 884 | 897 | ||
| 885 | 898 | export class UILayoutViewController extends UIViewController { | |
| Back | FazBrowse Home | New Git URL |
0 commit comments