Xamarin Form: Multiple TapGestureRecognizers not work on IOS - ios

<Image
x:Name="btnThickness"
BackgroundColor="Transparent"
Source="width"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"
WidthRequest="40"
HeightRequest="40">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="TappedBehaviourEvent"></TapGestureRecognizer>
<TapGestureRecognizer BindingContext="{x:Reference widthPicker}" Command="{Binding OpenCommand}"></TapGestureRecognizer>
</Image.GestureRecognizers>
</Image>
I have written an xaml file which have an image with two tap gesture recogniser: First TapGesture is to set the other view's visible to false and the second tap gesture is to show a selected view. On Android, it works fine and able to call the TappedBehaviourEvent and the second command whereas on IOS it only call the second line of the TapGesture not the first one.
Is there something need to be added to have it work...

Related

Xamarin.Forms (iOS Project): ListView Separator shows in all screen

I have a ListView with the default SeparatorVisibility. My Android project shows the Separator if there are elements in the ItemsSource and stops showing it below the last element. It's the result I want for my iOS project.
However, in my iOS project the screen is full of Separators no matter how many elements I have, even if I have no elements or only one, the Separators still being there.
Could someone give me a reason and how to fix it please? Thanks.
I think you can take a look to this post
these are some tips
First disable the default separator, this is done by adding following property to the ListView XAML
SeparatorColor="Transparent"
After this, wrap the complete ViewCell content inside a double StackLayout! I know this sounds like overkill but this way you’ll not run into any BoxView issues regarding margins inside the ViewCell… or other stuff.
The first StackLayout should have a BackgroundColor set to the colour you want your separator to be, the second StackLayout should have the same BackgroundColor as the rest of the container it is in… in our example the page and that is set to white. Be sure to also add a Margin to the bottom of this second StackLayout because that will represent the thickness of our separator!
I think you can play with this "Margin"... when your data is empty, remove the margin so you should not have the separator
<ListView x:Name="SeparatorListView"
SeparatorColor="Transparent"
ItemsSource="{Binding Persons}"
Margin="0,20,0,0"
RowHeight="60"
HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"
BackgroundColor="White"
Grid.Row="1">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell IsEnabled="false">
<StackLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"
BackgroundColor="Black">
<StackLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"
BackgroundColor="White"
Margin="0,0,0,0.4">
<StackLayout VerticalOptions="CenterAndExpand" HorizontalOptions="FillAndExpand" Spacing="0">
<Label Text="{Binding FullName}" TextColor="Maroon" VerticalOptions="CenterAndExpand" Margin="20,0,20,0" />
<Label Text="{Binding Profession}" TextColor="Maroon" VerticalOptions="CenterAndExpand" Margin="20,0,20,0" />
</StackLayout>
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
With that in place, you’ll get the same visual result as the preview image at the top right of this blog post.
As a bonus, you could omit one of the StackLayouts IF your page has a background color other than white. Because if this is the case, you can use that color as the separator color by playing with transparency inside the ListView.
Example of this, note will only work if the page itself also has a BackgroundColor set to Olive!
<ListView x:Name="SeparatorListView"
SeparatorColor="Transparent"
ItemsSource="{Binding Persons}"
Margin="0,20,0,0"
RowHeight="60"
HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"
BackgroundColor="Olive"
Grid.Row="1">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell IsEnabled="false">
<StackLayout BackgroundColor="#f4eac3"
Padding="0,5,0,5"
HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<StackLayout BackgroundColor="Transparent"
HorizontalOptions="FillAndExpand" VerticalOptions="CenterAndExpand"
Spacing="0"
Margin="20,0,20,0">
<Label Text="{Binding FullName}" TextColor="Maroon" VerticalOptions="CenterAndExpand" />
<Label Text="{Binding Profession}" TextColor="Maroon" VerticalOptions="CenterAndExpand" />
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer (typeof(ListView), typeof(CustomListViewRenderer))]
namespace yourNamespace
{
public class CustomListViewRenderer : ListViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.ListView> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
var listView = Control as UITableView;
listView.SeparatorInset = UIEdgeInsets.Zero;
}
}
}
}
That is due to the implementation of the ListView on the iOS side. It renders as a UITableView which (in the case of the ListView) always takes the entire height and shows empty items. To change this type of behavior you could set the ListView height dynamically in the code-behind for your page. Another option is taking a look at Xamarin's Evolve sample app which has a few pages where it uses a CardView combined with a ListView to make it appear as it does on Android.

Angular Nativescript - Using a ScrollView within an AbsoluteLayout

I'm building a photo browser app where the user should swipe between pages to see different photos. Here is the view that currently works for me.
<ScrollView orientation="horizontal" ios.pagingEnabled="true" >
<StackLayout orientation="horizontal">
<Image *ngFor="#picture of buffer" [src]="picture.originUrl" stretch="aspectFit"></Image>
</StackLayout>
</ScrollView>
The problem comes when I try to apply an overlay. So I tried to wrap the whole thing in an AbsoluteLayout so that I could have the ScrollView operate as normal but keep the overlay in place on top. When I do this scrolling breaks all-together. Here is the view that breaks scrolling:
<AbsoluteLayout>
<Label text="overlay" left="0" tope="0"></Label>
<ScrollView orientation="horizontal" ios.pagingEnabled="true" left="0" top="0">
<StackLayout orientation="horizontal">
<Image *ngFor="#picture of buffer" [src]="picture.originUrl" stretch="aspectFit"></Image>
</StackLayout>
</ScrollView>
</AbsoluteLayout>
The layouts appear to work correctly, but scrolling breaks.
Anybody have any ideas on how to accomplish this?
If I was doing this layout I would do this:
<GridLayout rows="*">
<ScrollView row="0" orientation="horizontal" ios.pagingEnabled="true">
<StackLayout orientation="horizontal">
<Image *ngFor="#picture of buffer" [src]="picture.originUrl" stretch="aspectFit"></Image>
</StackLayout>
</ScrollView>
<Label row="0" text="overlay"></Label>
</GridLayout>
By using the same row they will be positioned in the same place. I use this technique to create a entire search interface that will overlay part of the screen when they click the search button. Please note; the items later in the GridLayout show above items earlier in the GridLayout. So that is why the Label was moved to the bottom of the GridLayout, so it will be visible above the ScrollLayout.
Here is the actual test template I did:
<Page id="Page" onloaded="pageLoaded" class="">
<GridLayout rows="100,*">
<ScrollView row="0">
<StackLayout>
<Label visibility="{{ pageData.visible ? 'visible' : 'collapsed' }}" text="Hi1 this should appear/disappear" class ="lab1"/>
<Label visibility="{{ pageObs.visible ? 'visible' : 'collapsed' }}" text="Hi2 this should appear/disappear" class ="lab1"/>
<Label visibility="{{pageData, pageData.visible ? 'visible' : 'collapsed' }}" text="Hi3 this should appear/disappear" class ="lab1"/>
<Label left="10" top="70" visibility="{{visible ? 'visible' : 'collapsed' }}" text="Hi4 this should appear/disappear" class ="lab1"/>
<Label text="{{pageObs.visible}}"/>
<Label text="I'm at 120"/>
<Button text="tap" tap="onTap"/>
<Label text="Another text"/>
<Label text="Another text 2"/>
</StackLayout>
</ScrollView>
<Label row="0" text="Overlay"/>
<Label row="1" text="Grid row 1"/>
</GridLayout>
</Page>
This layout has two Grid rows, so that you can see where the ScrollView ends; the first row has the ScrollView AND the "Overlay"
I got an answer from a bug I filed: https://github.com/NativeScript/nativescript-angular/issues/184
The problem comes from the fact that AbsoluteLayout measures all its children with infinity space, so the ScrollView is as big as its content and indeed scrolling will not work. A possible fix is it to set a size for the ScrollView. In this specific case % layout size can be used.
<AbsoluteLayout>
<Label text="overlay" left="0" top="0"></Label>
<ScrollView orientation="horizontal" ios.pagingEnabled="true" left="0" top="0" width="100%" height="75%">
<StackLayout orientation="horizontal">
<Image *ngFor="#picture of pictures" [src]="picture.originUrl" stretch="aspectFit"></Image>
</StackLayout>
</ScrollView>
</AbsoluteLayout>
Both % values are % from the size that parent layout control is measured (AbsoluteLayout). Since Absolute layout is a root element actually these values will be % of the screen size.

WP8 WrapPanel ItemsControl not showing all items

I'm trying to create a scrollable area to display controls using the XAML code below. My problem is that I only see one item displayed when the items are rendered. I'm using an ObservableCollection for the data.
I've attached to the CollectionChanged event on the collection and definitely see multiple items being added but the view always displays only one item.
If I manually place HubTiles inside the WrapPanel (not databound) the tiles show up correctly. Also I tried replacing the hub tile with a button control and I do see multiple buttons, so I'm wondering if perhaps there is some issue with the HubTile control.
Here's my XAML:
<Grid x:Name="dataGrid" Grid.Row="1">
<ScrollViewer x:Name="myPanel" HorizontalAlignment="Stretch" Width="Auto" Margin="0" >
<toolkit:WrapPanel MaxWidth="{Binding ActualWidth, ElementName=myPanel, Mode=OneWay}" Margin="0" HorizontalAlignment="Center" ItemHeight="230" ItemWidth="230">
<ItemsControl x:Name="images">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<toolkit:HubTile
Style="{Binding Source={StaticResource media}}"
Message="{Binding Data.Caption}"
Source="{Binding Data.Source}"
/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</toolkit:WrapPanel>
</ScrollViewer>
</Grid>
Difficult to say without more information,
but the first thing I noticed is that you have a WrapPanel in a ScrollViewer,
and that WrapPanel contains an ItemsControl, with a WrapPanel as ItemsPanel.
The "inner" WrapPanel doesn't have an ItemWidth or ItemHeight. Is there any reason you have two WrapPanel's?

Alter text in normal TextBox with Surface-On-Screen-Keyboard

Is there a possibility to use the Surface-keyboard to alter text in a normal textbox?
I'm creating a textbox and add the text in code behind. And now I want that the user can change the text if he touches the text.
<Grid x:Name="TextContainer" Margin="0,0,0,0" Background="Transparent" Height="66" Width="66">
<TextBlock x:Name="contentTextBlock" Margin="0" Text="NodeDesign_X" VerticalAlignment="Center" d:LayoutOverrides="Width" HorizontalAlignment="Center" Foreground="White" TextTrimming="CharacterEllipsis" TextWrapping="WrapWithOverflow" />
</Grid>
I didn't find possibilities to alter the SurfaceTextBox in the way my TextBlock locks now.
Thanks in advance!
Use a TextBox instead of TextBlock then the user can change the text. If you are in Surface Mode the Keyboard will be automatic popup if the TextBox gets the focus.

How do I make a Silverlight popup with a TextBox fill its parent?

I have a popup within a user control. The popup uses a TextBox to show a textual preview of data produced by the control.
How do I make the popup size itself to the user control it's inside of? With code as shown below, I find that the text box is sized according to its content, and the popup is sized according to the textbox.
It works fine if I use fixed sizes in my row and column definitions, but I would like to popup to resize itself to match the user control (which in turn matches the browser).
<UserControl
<!-- usual stuff here -->
>
<Grid>
<!-- layout for the user control here -->
<!-- and after that my popup: -->
<Popup Name="MyPopup">
<Border BorderBrush="Black" BorderThickness="2" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="22"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Text="Preview:" Margin="5" ></TextBlock>
<TextBox
Grid.Row="1"
Name="MyTextBox"
IsReadOnly="True"
HorizontalScrollBarVisibility="Visible"
VerticalScrollBarVisibility="Visible"
TextWrapping="Wrap"
Margin="5"
>
</TextBox>
</Grid>
</Border>
</Popup>
</Grid></UserControl>
The C# code to do this would be something like:
textBox1.Width = UserControl.Width;
textBox1.Height = UserControl.Height;
textBox1.Margin = UserControl.Margin;
The key here is resetting the margin. I know this works in WPF to, say, fill a Window with a TextBox. Give it a try, see if it works.

Resources