I'm trying to implement CarouselView control with horizontal scroll.
I'm using Xamarin.Forms 5.0.0.2012.
This is the xaml code:
<CarouselView x:Name="carViewArticoliAlt"
Loop="False"
ItemsSource="{Binding ListaProdottiAlt}"
IndicatorView="indicatorView"
IsVisible="{Binding ArticoliAlt}"
HeightRequest="200"
PeekAreaInsets="100">
<CarouselView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal"
SnapPointsAlignment="Start"
SnapPointsType="Mandatory"
ItemSpacing="20" />
</CarouselView.ItemsLayout>
<CarouselView.ItemTemplate>
<DataTemplate>
<Frame HasShadow="True" BorderColor="LightGray"
CornerRadius="5" Padding="5"
HeightRequest="310"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" >
<Frame.GestureRecognizers>
<TapGestureRecognizer
Tapped="TapGestureRecognizer_Tapped"/>
</Frame.GestureRecognizers>
<Grid>
<StackLayout x:Name="stkArticoloAlt">
<ImageButton x:Name="ImageArt"
Source="{Binding ImageArt}"
Aspect="AspectFit"
HeightRequest="80"
Clicked="ImageArt_Clicked"
BackgroundColor="White"/>
<Label Text="{Binding Descrizione}"
Style="{StaticResource labelDescrizioneStyle}"
MaxLines="3" LineBreakMode="TailTruncation"
HeightRequest="55"
FontSize="15"/>
</StackLayout>
</StackLayout>
</Grid>
</Frame>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
<IndicatorView x:Name="indicatorView"
IndicatorColor="LightGray"
SelectedIndicatorColor="DarkGray"
HorizontalOptions="Center" />
On Android platform the control is well rendered, but on iOS the following exception is thrown: Objective-C exception thrown. Name: NSInternalInconsistencyException Reason: negative sizes are not supported in the flow layout.
I followed this tutorial:
https://learn.microsoft.com/it-it/xamarin/xamarin-forms/user-interface/carouselview/scrolling
I noticed that the cause of the exception is the PeekAreaInsets property. Infact, if I don't handle this property, the exception does not occur. However the control is not drawn correctly, since the tabs are overlapping. Android code keeps on running correctly.
As you can see in the image, the cards are all overlapped, even if LinearItemsLayout.Orientation is set to horizontal.
Name: NSInternalInconsistencyException Reason: negative sizes are not supported in the flow layout.
The error indicates that the child's size( in datatemplate) is bigger than parent layout's size.
<CarouselView x:Name="carViewArticoliAlt"
Loop="False"
ItemsSource="{Binding ListaProdottiAlt}"
IndicatorView="indicatorView"
IsVisible="{Binding ArticoliAlt}"
HeightRequest="200" --------->parent's height
PeekAreaInsets="100">
<CarouselView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal"
SnapPointsAlignment="Start"
SnapPointsType="Mandatory"
ItemSpacing="20" />
</CarouselView.ItemsLayout>
<CarouselView.ItemTemplate>
<DataTemplate>
<Frame HasShadow="True" BorderColor="LightGray"
CornerRadius="5" Padding="5"
HeightRequest="310" --------->child's height
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" >
To solve the problem try to remove HeightRequest="200" on CarouselView.
Since the Xamarin.Forms 5 release a new feature has been implemented on the CarouselView: Loop. This seems to be set to True by default and is causing some issues together with the PeakAreaInsets property. I was able to solve/work-around above crash/error by setting Loop="False". Perhaps that also works in your case?
Related
I experience this issue only my Xamarin iOS project. The Android version works correctly.
I have a standard ContentPage that is pushed via PushAsync. When the page loads, the content loads off the screen then (it seems) after binding is finished moves down the page. I have attached a screen where it shows loading off the screen and one where it re-adjusts.
Content off the screen
After binding
XAML File
<ContentPage.Content>
<AbsoluteLayout>
<Frame Padding="10"
Margin="20, 20, 20, 20"
BackgroundColor="AliceBlue"
AbsoluteLayout.LayoutBounds="0, 0, 1, 1"
AbsoluteLayout.LayoutFlags="SizeProportional">
<StackLayout Margin="10">
<Label Text="{Binding OutreachTitle}"
FontSize="Title"
TextColor="{StaticResource PrimaryTextColor}"
HorizontalOptions="Center" />
<controls:HorizontalRuleControl RuleColor="{StaticResource SecondaryColor}" />
<Label Text="{Binding OutreachText}"
Margin="0, 10, 0, 0"
TextColor="{StaticResource PrimaryTextColor}"
VerticalOptions="End"/>
</StackLayout>
</Frame>
</AbsoluteLayout>
</ContentPage.Content>
I did not reproduced the problem on my side. While I would recommend you to use StackLayout instead of AbsoluteLayout.
The problem is probably caused by resize of View in ContentPage, when you set SizeProportional of AbsoluteLayout, the size will following the changing of the View and that would cause the content loads off the screen:
<StackLayout>
<Frame Padding="10"
Margin="20, 20, 20, 20"
BackgroundColor="AliceBlue"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<StackLayout Margin="10">
<Label Text="{Binding OutreachTitle}"
FontSize="Title"
TextColor="Yellow"
HorizontalOptions="Center" />
<Label Text="{Binding OutreachText}"
Margin="0, 10, 0, 0"
TextColor="Green"
VerticalOptions="End"/>
</StackLayout>
</Frame>
</StackLayout>
When using the RadSideDrawer with a page-router-outlet in NativeScript, it seems that there is no way to not have the page-router-outlet fill 100% of the height on iOS. On Android, it works fine. The reason I'm running into this issue is because I'm trying to add a BottomNavigationBar below my router outlet. The images below show the behavior on both iOS and Android:
Here is my code:
<RadSideDrawer>
<FlexboxLayout tkDrawerContent>
<Button text="Test"></Button>
</FlexboxLayout>
<GridLayout class="main-grid" tkMainContent rows="*, auto">
<StackLayout row="0">
<page-router-outlet></page-router-outlet>
</StackLayout>
<BottomNavigationBar activeColor="white" inactiveColor="gray" backgroundColor="black" row="1">
<BottomNavigationTab title="First"></BottomNavigationTab>
<BottomNavigationTab title="Second"></BottomNavigationTab>
<BottomNavigationTab title="Third"></BottomNavigationTab>
</BottomNavigationBar>
</GridLayout>
</RadSideDrawer>
If I remove the page-router-outlet and put anything in it's place, it will then function correctly on both iOS and Android. Also, if I leave the page-router-outlet and remove the RadSideDrawer, it also functions correctly.
Any suggestions? Thanks!
EDIT:
It seems as if this issue only occurs when there are two page-router-outlets nested as in this sample playground:
https://play.nativescript.org/?template=play-ng&id=Z2a5Z7
Maybe page-router-outlets aren't supposed to be nested then? Right now I have a page-router-outlet in my app.component that lazy loads and switches between a login.component and my main app pages.component. pages.component contains the RadSideDrawer and the other page-router-outlet. I did this so I can lazy load my authorization pages and regular app content pages. Is this wrong?
It seems to be a issue with RadSideDrawer plugin (v8.0.0), the plugin is not open sourced so the best approach would be raising an issue in nativescript-ui-feedback and I see you have done that already - #1362.
I have a workaround that seem to fix the issue on my end.
MainComponent
constructor(page: Page) {
page.once(Page.navigatedToEvent, () => {
page.frame.requestLayout();
});
}
Request for relayout once the page is loaded.
Updated Playground
In my case, I have a modal page full height width over the side drawer, so I created a structure like below. Hope this helps you.
<GridLayout rows="" columns="" [class.dialogOpen]="dialogOpen">
<StackLayout>
<RadSideDrawer tkExampleTitle tkToggleNavButton drawerContentSize="320">
<StackLayout tkDrawerContent>
<app-sidenav></app-sidenav>
// my side drawer data
</StackLayout>
<GridLayout tkMainContent class="app" rows="auto,*,auto">
<GridLayout row="0" columns="*" rows="auto,auto" *ngIf="data.navbar" class="gradient">
// custom header
</GridLayout>
<!-- main content -->
<FlexboxLayout row="1">
<StackLayout #container>
<StackLayout [ngClass]="{'full': data.full }">
<ng-content></ng-content>
</StackLayout>
</StackLayout>
</FlexboxLayout>
<!-- Footer -->
<FlexboxLayout row="2" *ngIf="data.footer" class="app__footer" verticalAlignment="bottom">
// bottom tabs for my app
</FlexboxLayout>
</GridLayout>
</RadSideDrawer>
</StackLayout>
<StackLayout verticalAlignment="center" horizontalAlignment="center" height="100%" class="dialog__wrapper">
<AbsoluteLayout height="100%" backgroundColor="#FFFFFF" verticalAlignment="center" horizontalAlignment="center">
<!-- EDIT POPUP -->
<StackLayout class="dialog__container">
// cusotm dialog data
</StackLayout>
</AbsoluteLayout>
</StackLayout>
</GridLayout>
I need to put image as background in toolbar in Xamarin Forms in iOS project with master detail page and navigation bar (to have software back button in iOS). On android it works well but in iOS not good enough. I use this code in AppDelegate.cs:
UINavigationBar.Appearance.SetBackgroundImage(new UIImage("toolbar_iOS.jpg"), UIBarPosition.Any, UIBarMetrics.Default);
I put here image with pattern 400x125 pixels (less width - it displays 1 image and part of second image to the right, more pixels - image is zoomed). I want to have image displayed as aspect fill, because at page just under toolbar I have the same image with pattern and I want them exactly in the same size to match pattern.
Second way was to put an image in stack layout in Xamarin.Forms in NavigationPage.TitleView. I can modify aspect, but image is displayed only in about 70% of area of toolbar (it bypass hamburger icon and status bar), so it is not good.
<?xml version="1.0" encoding="utf-8" ?>
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Layout.xxx.Views.MainMenuPage"
xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
xmlns:ffimageloadingsvg="clr-namespace:FFImageLoading.Svg.Forms;assembly=FFImageLoading.Svg.Forms"
xmlns:pages="clr-namespace:Layout.xxx.Views">
<MasterDetailPage.Master>
<pages:MainMenuPageMaster x:Name="MasterPage"/>
</MasterDetailPage.Master>
<MasterDetailPage.Detail>
<NavigationPage>
<x:Arguments>
<pages:MainMenuPageDetail x:Name="DetailPage">
<NavigationPage.TitleView>
<Grid>
<ffimageloading:CachedImage Margin="-50,-30,0,0" Grid.Row="0" Source="background.jpg" Aspect="AspectFill" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" />
<StackLayout Grid.Row="0" VerticalOptions="Center" HorizontalOptions="FillAndExpand">
<StackLayout.Margin>
<OnPlatform x:TypeArguments="Thickness" iOS="-35,0,0,0" Android="-60,0,0,0"/>
</StackLayout.Margin>
<ffimageloadingsvg:SvgCachedImage Margin="0" Source="logo_svg.svg" Aspect="AspectFit" HeightRequest="40" VerticalOptions="Center" HorizontalOptions="Center" />
</StackLayout>
</Grid>
</NavigationPage.TitleView>
</pages:MainMenuPageDetail>
</x:Arguments>
</NavigationPage>
</MasterDetailPage.Detail>
</MasterDetailPage>
Negative margins does not help. Is there another way to have control over toolbar image in iOS?
Use this code snippet , may help
<ContentPage>
<NavigationPage.TitleView>
<StackLayout Orientation="Horizontal" VerticalOptions="Center" Spacing="10">
<Image Source="iconXamagon.png">
<Image.GestureRecognizers>
<Image.TapGestureRecognizer
Tapped="HandleTapped" />
</Image.GestureRecognizers>
</Image>
<Label Text="3.2.0" FontSize="16" TextColor="Black" VerticalTextAlignment="Center" />
</StackLayout>
</NavigationPage.TitleView>
....
If you set HasBackButton="False" for the page it should cover the whole screen, just you will have to implement the back button or the hamburger button yourself.
I'm new with xamarin and I'm trying to use a searchbar with a result listview (which is hidden) on top of a main listview (ie: mobile facebook friend search)
On iOS I'm not being able to tap on the main listview because the result listview is always on top of the other one even if it's not visible.
Here is the code:
<AbsoluteLayout>
<StackLayout Orientation="Vertical" Padding="0,50,0,0">
<StackLayout Padding="20,0,0,10">
<Label Text="{Binding SelectedAddressString, StringFormat='BCLs near {0}'}" />
</StackLayout>
<ListView x:Name="iOSlstBCLs" ItemsSource="{Binding BCLList}" IsPullToRefreshEnabled="true" RefreshCommand="{Binding RefreshCommand}" IsRefreshing="{Binding IsRefreshing, Mode=OneWay}">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Name}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
<StackLayout Orientation="Vertical" HorizontalOptions="StartAndExpand" VerticalOptions="Fill" AbsoluteLayout.LayoutFlags="WidthProportional" AbsoluteLayout.LayoutBounds="0,0,1,1">
<SearchBar Text="{Binding SearchText, Mode=TwoWay}" Placeholder="Search" AbsoluteLayout.LayoutFlags="WidthProportional" AbsoluteLayout.LayoutBounds="0,0,1,1" />
<ListView IsVisible="{Binding IsSuggestionListVisible, Mode=OneWay}" ItemsSource="{Binding SuggestionList}" SelectedItem="{Binding SelectedAddress}" VerticalOptions="Fill" AbsoluteLayout.LayoutFlags="WidthProportional" AbsoluteLayout.LayoutBounds="0,0,AutoSize,AutoSize" BackgroundColor="White">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding formatted_address}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</AbsoluteLayout>
Any ideas?
From my experience, you should never use an Absolute Layout if at all possible. It seems like it would be better to use a Stack and place both of your other stacks within that. Then set the visibility as needed. I am not positive, but I am guessing that the Absolute Layout is messing you up.
I am using autocompletebox toolkit from windowsphone7.5 version. It works well in wp7.1 toolkit.
If I use autocompletion with inner control margin it's not worked properly, it shows the result on the top,
Here I attached the autocompletion error screenshot.
This is the code :
<Grid Grid.Row="1" Height="76" VerticalAlignment="Top">
<toolkit:AutoCompleteBox VerticalAlignment="Bottom" Width="400" ValueMemberBinding="{Binding Title}" HorizontalAlignment="Left" Grid.Row="0" x:Name="acBox" Margin="10,0,10,0" ItemsSource="{Binding CategoryListitems}">
<toolkit:AutoCompleteBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}"/>
</DataTemplate>
</toolkit:AutoCompleteBox.ItemTemplate>
</toolkit:AutoCompleteBox>
</Grid>