Swiping elements inside a TabView - Xamarin.Froms - xaml

I have an horizontal TabView with 2 TabViewItems. In one of them I have a WebView that loads a certain website. The website has a long string of text that can be swiped horizontally.
<TabView>
<TabViewItem>
<WebView />
</TabViewItem>
<TabViewItem>
<!-- More XAML code -->
</TabViewItem>
<TabView>
Here is the problem: When IsSwipeEnabled is set to True (which is the default value of the property) the swipe gesture has no effect on the text. The focus is on the tab and swiping horizontally just brings on screen the other tab.
Is there a way to keep IsSwipedEnabled set to True but pass the focus to the text when the gesture happens on it?

Check TabView source code we can find actually it uses CarouselView to implement the scrolling effect.
However , it's not recommended to place a Webview on a CarouselView/ScrollView , the swipe gesture would generate conflict.
The workaround is
Disable Swipe gesture of TableView in Webview page , and recover it in another page .
<TabView IsSwipeEnabled="False" SelectionChanged="TabView_SelectionChanged">
<TabViewItem Text="111">
<WebView/>
</TabViewItem>
<TabViewItem Text="222">
<Label Text="test"/>
</TabViewItem>
</TabView>
private void TabView_SelectionChanged(object sender, Xamarin.CommunityToolkit.UI.Views.TabSelectionChangedEventArgs e)
{
if(e.NewPosition == 0)
{
(sender as TabView).IsSwipeEnabled = false;
}
else
{
(sender as TabView).IsSwipeEnabled = true;
}
}

Related

NavigationPage with iOS PrefersLargeTitles snaps title when scrolling

I tried to get the same large title behavior like the settings app on iOS when the user scrolls down. The transition between the large title and the small title is smooth. But on Xamarin Forms the header snaps.
In my NavigationPage i set PrefersLargeTitles="true". In the embedded content page i set LargeTitleDisplay="Always" and UseSafeArea="true". The content in the page looks like this:
<ContentPage.Content>
<AbsoluteLayout>
<ListView />
<Frame x:Name="LoadingFrame" /> <!-- Only visible until ListView is loaded -->
</AbsoluteLayout>
</ContentPage.Content>
I tried setting NavigationPage.IsNavigationBarTranslucent="True". Then it works, but only if i disable SafeArea (Page.UseSafeArea="False") in the ContentPage. Disabling SafeArea is not what i want, because now the content is behind the notch.
I had the same issue.
The trick was to change top constraint of list to superView instead of safe area which only works on Native.
extendedLayoutIncludesOpaqueBars = true;
On Xamarin.Forms, I tried these solutions:
Use a custom renderer to set the LayoutConstraints of the scrollable view (Doesn't work)
Create a UITableViewController in a custom renderer then convert the Xamarin TableView element to a UITableView and set it to the TableView property of the UITableViewController then PushViewController to the new UITableViewController. (work)
You can raise the problem on github for better support:
https://github.com/xamarin/Xamarin.Forms/issues

I cannot call another screen when I click on the image

I have two images to simulate the click on the button, but I want is when clicking the image and change call another screen. And the process does not happen because the application is stopping
<StackLayout>
<!-- Place new controls here -->
<Image Source="botaocadastrolivre.png">
<Image.GestureRecognizers>
<TapGestureRecognizer
Tapped="OnTapGestureRecognizerTapped"
NumberOfTapsRequired="1" />
</Image.GestureRecognizers>
</Image>
</StackLayout>
void OnTapGestureRecognizerTapped(object sender, EventArgs args)
{
tapCount++;
var imageSender = (Image)sender;
// watch the monkey go from color to black&white!
if (tapCount % 2 == 0)
{
imageSender.Source = "botaocadastrolivre.png";
}
else
{
imageSender.Source = "botaocadastroPresed.png";
Navigation.PushAsync(new Nova());
}
// Task.Delay(100)
//Navigation.PushAsync(new Nova());
}
Go to your App.xaml.cs file, find the line that says something like:
MainPage = new MainPage();
and change it into:
MainPage = new NavigationPage(new MainPage());
This will wrap your page into a navigation page and then the Navigation object will know how to navigate from one page to the other.
It might be wise to read up on navigation concepts in Xamarin.Forms: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/navigation/

How to call another page using Tap Gesture in Xamarin.Forms?

I created an Image Button and put a Tap Gesture into it. I want my Image Button to call another Page but I don't know how am I going to do that without using Navigation.PushAsync but it's causing me this error "PushAsync is not supported globally on Android, please use a Navigation Page."
This is my XAML code.
<Image Source="add.jpg">
<Image.GestureRecognizers>
<TapGestureRecognizer
Tapped="TapGestureRecognizer_OnTapped"
NumberOfTapsRequired="1" />
</Image.GestureRecognizers>
</Image>
and this is my XAML.CS code.
private void TapGestureRecognizer_OnTapped(SecondPage secondPage)
{
Navigation.PushAsync(new SecondPage());
}
If you need to use PushAsync, the parent Page should be a NavigationPage.When we use NavigationPage and do PushAsync the Navigation stack will be maintained and you will get a back button in Actionbar for back navigation.
Rather if we use PushModalAsync, the page will be presented modally.
Changing PushAsync to PushModalAsync will work.
private void TapGestureRecognizer_OnTapped(SecondPage secondPage)
{
Navigation. PushModalAsync(new SecondPage());
}

Keep element in view while scrolling

Simpel question, I have a windows phone page that contains a scrollviewer with inside it an image, a textblock and a richtextbox.
Now when the user starts scrolling I want to keep the textblock in view on top when the image has scrolled outside the page.
So the effect is, user starts scrolling upwards, everything scrolls upwards, when the image is outside the page, the textblock stays at the top of the page but the richtextbox keeps scrolling upwards.
Any thoughts?
Here is a way to reach this result:
First, the layout. I've set a grid, with two rows. The first is empty, and will host the header when we need to freeze it. The second row contains the scrollviewer.
Inside the scrollviewer, I've put the controls in a grid, but you can use whatever container suits you.
<ScrollViewer Grid.Row="1"
Margin="0"
Padding="0"
x:Name="ParentScroll"
ManipulationMode="Control"
MouseMove="ParentScroll_MouseMove">
<Grid x:Name="ChildGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Image Source="Picture.jpg" Grid.Row="0"/>
<TextBlock Text="Header" Grid.Row="1" x:Name="TextHeader" />
<RichTextBox Grid.Row="2" x:Name="RichText">
<Paragraph>
<Bold>RichTextBox</Bold>
<!-- More stuff -->
</Paragraph>
</RichTextBox>
</Grid>
</ScrollViewer>
I use the MouseMove event to be notified of the scrolling event. You can also dig into the template, extract the ScrollBar control, and subscribe to the ValueChanged event, as described here: http://social.msdn.microsoft.com/Forums/wpapps/en-US/81fcd34e-6ec9-48d0-891e-c53a53344553/scrollviewer-synchronization
Note that you need to set ManipulationMode to Control or the position of the controls won't be updated at a smooth rate. I guess it's due to some internal optimization.
In the code behind, I use the TransformToVisual method to compute the relative position of the controls to the ScrollViewer. This way, I can know when the header goes out of view. When it does, I remove it from the child grid, and put it outside of the ScrollViewer, in the parent grid. When the top of the RichTextBox goes out of view, I put the header back into the ScrollViewer:
private void ParentScroll_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
if (Grid.GetRow(this.TextHeader) == 1)
{
var generalTransform = TextHeader.TransformToVisual(ParentScroll);
var childToParentCoordinates = generalTransform.Transform(new Point(0, 0));
if (childToParentCoordinates.Y < 0)
{
this.ChildGrid.Children.Remove(this.TextHeader);
this.ParentGrid.Children.Add(this.TextHeader);
Grid.SetRow(this.TextHeader, 0);
}
}
else
{
var generalTransform = RichText.TransformToVisual(ParentScroll);
var childToParentCoordinates = generalTransform.Transform(new Point(0, 0));
if (childToParentCoordinates.Y > 0)
{
this.ParentGrid.Children.Remove(this.TextHeader);
this.ChildGrid.Children.Add(this.TextHeader);
Grid.SetRow(this.TextHeader, 1);
}
}
There may be less-hacky ways to reach the same results, but this solution seems to work smoothly in the emulator.
I've found a working solution myself... the complete detail is available on my blog here... it contains also the link to my demo project on GitHub.
The trick was to get hold of the VerticallScrollBar inside the ScrollViewer and to set the ManipulationMode to Control to get enough feedback on the UI thread.
With the scroll offset information of the scrollbar we than animate the specific ui element we want to keep in view.

How do you utilize the flipview and make a "selection" by tapping or clicking the screen?

In Win 8, the flipview control is a great control to browse the collection. But how or what is the best way to make a "selection" with a tap or a mouse click? I can always put a button outside of the flip view, but that's not the touch experience that everyone of a tablet would expect.
can someone give some example code (XAML/C#) of how to setup a flipview control with a selection of some sort that would navigate to a totally different page?
I wrote some sample code that works, if I'm understanding the question correctly. I am able to swipe through the FlipView and tap the individual item:
<FlipView Tapped="FlipView_Tapped_1">
<Image Source="Images/Apple.jpg" />
<Image Source="Images/Orange.jpg" />
<Image Source="Images/Banana.jpg" />
</FlipView>
And then
private YourTypeHere SelectedItem;
private void FlipView_Tapped_1(object sender, TappedRoutedEventArgs e)
{
this.SelectedItem = (sender as FlipView).SelectedItem;
}
You might not want to set a field, but you get the idea. Hopefully, you will be setting something in your view model. From there you can nav away or anything you need. A FlipView inherits from ItemsControl just like every other XAML repeater. So you can treat it exactly the same. http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.aspx