I have been having issues with using the ScrollToAsync function of a ScrollView when running on Android, not tested on iOS yet.
I'm using Xamarin.Forms version 2.5.1.444934 using .Net Standard
Testing on the Android Emulator (8.0, API26) and a Google Pixel (8.1 API27), both have the same issue.
I use NavigationPage and Navigation.PushAsync to move between pages (therefore have navigation bars on every page).
I want to create an auto populate field control, the user types in the first few letters and I look up the results in a database / static list of string and display the results below for the user to click/tap.
I have this working using a composite control (the contents of the frame marked interesting below).
The problem I have is scrolling the view to show the results.
My page has this layout hierarchy:-
ContentPage
StackLayout
ScrollView
StackLayout
Frame (some label and entry fields inside a stack layout)
Frame (some label and entry fields inside a stack layout)
Frame (some label and entry fields inside a stack layout)
Frame (the interesting one that deals with scrolling)
StackLayout
Heading Label
StackLayout
Label x:Name="ScrollToLabel"
Entry x:Name="ScrollToEntry"
Grid x:Name="ScrollToGrid"
Entry x:Name="Hidden" Text="I should stay visible as you type"
/StackLayout
/StackLayout
/Frame
Frame (some label and entry fields inside a stack layout)
Frame (some label and entry fields inside a stack layout)
/StackLayout
/ScrollView
StackLayout
Button Text = Done
/StackLayout
/StackLayout
/ContentPage
When the user clicks/taps in to ScrollToEntry, the keyboard opens and pans the control to above the keyboard (ok so far).
When the user starts typing in ScrollToEntry, the code populates ScrollToGrid with up to 5 results.
At this point I want to make sure that the grid results are visible for the user to tap on.
I have tried 2 different options, ScrollToAsync(ScrollToLabel, Start) and ScrollToAsync(Hidden, MakeVisible).
Neither work as I would like 100% of the time.
ScrollToAsync(ScrollToLabel, Start)
If the ScrollToEntry is at the bottom of the screen, the navigation bar is hidden and the view pans up too far.
The ScrollToLabel is now off the top of the screen.
When the second letter is clicked/tapped, the Navigation bar is restored and the scroll scrolls correctly, ScrollToLabel at the top of the screen.
If the ScrollToEntry is near the top of the screen, the navigation bar is not hidden and it scrolls correctly.
ScrollToAsync(Hidden, MakeVisible)
This is my preferred option because it would only scroll as far as needed to display all the results (not all the way to the top).
This works even worse than the first one.
In most cases, it does not scroll at all, I assume it thinks it already visible but is actually behind the keyboard?
If it does scroll, the label Hidden is still not displayed (I tested with both a HeightRequest="0" version and a visible version, both the same result).
I tried using the below code to change the adjust to resize.
Application.Current.On<Xamarin.Forms.PlatformConfiguration.Android>().UseWindowSoftInputModeAdjust(WindowSoftInputModeAdjust.Resize);
2 issues,
1. Because it resizes, the Done button now is above the keyboard, taking up space.
2. When clicking the hardware back button (not the done or navigation back button) the previous view now has a white space where the keyboard was.
If using the done or navigation back, the screen initially appears with the white space but then refreshes to full screen.
I have created a sample app that highlights the issues (by default using pan, not resize).
It's the most simple version of the layout I'm using...
Am I doing something wrong or is this just how it works? If its how it works, this must be a bug? If I'm doing it wrong, can someone tell me what or suggest a different way of doing it?
Related
I´m working on a tool only for tablets (Android, iPad) based on Cordova and jQuery Mobile (1.4.5). In the first phase of this tool, many of the users who have to work with it were asking for some more comfort regarding the behavior of the form popups.
The problem was:
As a user came to one section, I provided him with a collapsible-set, consisting of sub-sections. In this sub-sections, the user gets data-grids with Add, Edit and Delete buttons next to each data-set.
So, as the user tapped on Edit button (or Add), I opened up a popup with the necessary form and form-elements to edit this data-set or add new data to the database. But in many of the upcoming popups the amount of the form-elements is as high, so the popup appears higher or even much higher then the collapsible-set (including the data grid) behind the modal popup is.
The popup of jQuery Mobile is centered by default and even if I positionTo origin and pass x and y coordinates to it, the library/widget wants to position the popup to this coordinates by the center point, rather then the upper left corner.
Users always had to scroll around to come to the start point of the form and after submitting the form, they had to scroll up again to where they tapped on the button to open the popup.
Now I tried to do everything I could imagine, to force the popups top position to 20 pixels below the top position of the visible area on the tablet, regardless of where I am, when tapping on any Edit or Add button.
I was playing around with offset() (window.pageYOffset), etc. and set the position of the popup by:
popup2open.popup('open').css({'top':popupTopValue+'px','left':popupLeftValue+'px'});
In fact, the popup is positioned to exactly where I want it, if the top offset is between 0 and 100. On all values above 100, the top position of the popup increases by absolutely incomprehensible value. The only consistent fact is, that the more I scroll down before I tap on a button, the more this value increases - so it does not in/decrease by random.
(BTW: I found out that I have to set "popupLeftValue" to 0, so the popup is positioned in the center horizontally.)
I just can´t see any regularity on increasing value...
Can anybody give me a hint or a punch to the right direction?
Thank you in advance!
PS: I experimented also with .css({'position':'[fixed|absolute]','top':popupTopValue+'px','left':popupLeftValue+'px'}); and that worked well. Only to find out one show-stopper: If I set the focus to an input-field inside the form and than closing the virtual keyboard on the tablet, a reposition-event is triggered and by this, the popup is re-positioned massively below the former position (in fact around 300 pixels below and just marginalized to the right border of visual area). The Cancel and Save buttons are even out of scroll-able area.
(some more funny fact, btw.: if I set the focus to the same input-field, than not closing the virtual-keyboard but directly setting the focus to a select element and after this pressing the back button of the tablet to escape the select menu, no reposition-event is triggered...!?)
On 18th of July 2013 Gabriel Schulhof added this line to a feature-request from one user, who asked exactly for what I´m struggling around with:
"We are indeed considering adding such a feature..."
I'm trying out both DockFX (https://github.com/RobertBColton/DockFX) and AnchorFX (https://github.com/alexbodogit) (using Clojure as the host language, in Win7 x64)
The nice thing about DockFX is that you can drag from the tabs, and set the title bar to NULL to make the pane non-draggable, but the DockingPane still allows siblings next to (which is ok), or on top of (which is not okay) the non-draggable DockNode, leaving a skinny little section of tab representing the non-draggable node when another pane is dragged on top, as shown here. This is what it looks like when a non-draggable TableView gets a TreeView dragged on top.
Question for DockFX:
How to prevent things from being dragged on top of a non-draggable DockNode, so I don't see a skinny vestigial tab?
For AnchorFX, I like how you can create substations, etc., and it feels a little snappier (actually about 1/10th the time to create a Station compared to DockFX). I modified the code so a null title removes the title bar and makes the node non-draggable.
Questions for AnchorFX:
How to prevent things from being dropped on top? (next to is okay).
How to eliminate title bar when a node is tabbed on top of other nodes?
How to drag from tab instead of title bar?
I modified the DockFX code so the popup does not appear if the DockTitleBar is null.
Inherently fixed by above.
Already works with DockFX, haven't tried fixing this with AnchorFX.
I have a very simple setup. It's a single window with a toolbar, completely filled with a NSScrollView. The window is setup as follows:
window.styleMask = [.titled, .resizable, .closable, .fullSizeContentView]
window.titleVisibility = .hidden
This looks pretty gorgeous! However, I need to change how the content of the document view behaves as its frame changes. The problem is that docuentView.visibleRect reports that the minY is 0.0 until it hits the top of the window, not the bottom of the toolbar! So some of my custom drawing and behavior is cut off, and that is not so gorgeous.
How do I find the actually-usable rect of that document view, which excludes the part of it beneath the toolbar?
There is a property on the window called contentLayoutRect, which represents the portion of the window content that is visible (using non-flipped coordinates). You can use this to position the content view and rest assured that this will still work if Apple decides some other edge of the window becomes obscured.
As soon as I display my search bar in the navigation controller, the behavior of the search results table changes - the table content is offset vertically by about 60px.
Changing the table's contentOffset on the delegate ResultsWill/Did Appear makes no difference.
Setting displayInNavigationController = false restores expected alignment of results (directly below search bar with no gap).
The blank area appears to be part of the table/scrollview, as I can force the results cells to temporarily display in the blank section by scrolling down.
Any idea how to get those first result cells to display at the top of the results window?
It looks like you have viewController.automaticallyAdjustsScrollViewInsets set, but you don't actually want this adjustment. You can turn this option off via either Interface Builder (find "Adjust scroll view insets" checkbox) or programmatically.
In Xcode 5, I've opened a new project and added the following:
A Tab View Controller with two Tabs (thus two View Controllers).
In each Controller View, I've added a CollectionView, with both a Label and a Button under it.
I've applied the Default constraints. No warnings.
... clicked Run.
In the iOS simulator, the first Tab looks ok, all elements in the View are aligned to the bottom of the layout, which is the top of the tab bar. Perfect.
When clicking on the second Tab, instead of aligning to the bottom of the layout, it aligns everything to the bottom of the container. So all the elements in the View drop in height by that much. Clicking back to the first tab will now show this incorrect positioning as well.
Strangely, rotating the device fixes this... showing the correct alignments in both tabs and for both orientations.
Any idea what am I doing wrong?
Thanks,
I now believe this is a bug in XCode 5.
I got around it by replacing the constraint for a pin, like so:
Editor -> Pin -> Bottom Space to Superview.