StackLayout ignoring EndAndExpand on iOS - xamarin

It seems that there is a confirmed Bug in Xamarin.Forms in iOS, when you have a content/label with a text too large that needs 2 lines to display it in a StackLayout (lets say layoutA), the others siblings and parent elements takes the width of the layoutA.
Kent Boogaart filled a Bug with the following example to reproduce the error.
<StackLayout Margin="0,20,0,0">
<!-- works (by virtue of no wrapping) -->
<StackLayout Orientation="Horizontal">
<Switch/>
<Label Text="Some text"/>
<Button Text="A Button" HorizontalOptions="EndAndExpand"/>
</StackLayout>
<!-- works (by virtue of no switch) -->
<StackLayout Orientation="Horizontal">
<Label Text="Some longer text that wraps over two lines"/>
<Button Text="A Button" HorizontalOptions="EndAndExpand"/>
</StackLayout>
<!-- does not work -->
<StackLayout Orientation="Horizontal">
<Switch/>
<Label Text="Some longer text that wraps over two lines"/>
<Button Text="A Button" HorizontalOptions="EndAndExpand"/>
</StackLayout>
</StackLayout>
Is there a solution/fix/workaround for this problem?
EDIT
Here is the code used:
<ListView HasUnevenRows="True" SeparatorVisibility="None" HorizontalOptions="StartAndExpand" CachingStrategy="RecycleElement">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="#eee" Padding="5" Margin="5" >
<ffimageloading:CachedImage HorizontalOptions="Start" VerticalOptions="Start" HeightRequest="75" Source="{Binding ID, StringFormat='https://example/api/{0}'}" CacheDuration="15">
<ffimageloading:CachedImage.Transformations>
<fftransformations:CircleTransformation/>
</ffimageloading:CachedImage.Transformations>
</ffimageloading:CachedImage>
<StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand">
<Label Text="{Binding Name}" TextColor="#f35e20" HorizontalOptions="FillAndExpand"/>
<Label Text="{Binding Description}" HorizontalOptions="FillAndExpand" TextColor="#503026" />
<Label Text="{Binding ID}" x:Name="ID" IsVisible="False"></Label>
<Button Text="Ver productos" TextColor="#FF5F6D" HorizontalOptions="End" BackgroundColor="Transparent"></Button>
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
These are actual screenshots of the app in iOS, in Android it just work great.
As you can see, in the Image1 the first card is OK, the button ("Agregar al carrito" or "Ver Productos") is at the end.
But in the second card as the text is too large, the button gets down out of the card.
And in the second image, the text in the middle needs 2 lines, and the StackLayout that wraps the content (the 2 labels and the button) gets just as wide as the label with the large text.
I draw a red square in the large text, and a red line so you can see that because of that large text, the StackLayout gets narrow.

This is a known issue that when setting the padding on stacklayout inside Cell , the row height displays incorrectly.
Solution: Use StackLayout to wrap the content under the Cell.
<ViewCell>
<StackLayout > //add this
<StackLayout Orientation="Horizontal" Padding="5" Margin="5" >
</ffimageloading:CachedImage>
<StackLayout BackgroundColor="Brown" Orientation="Vertical">
<Label TextColor="#f35e20" HorizontalOptions="FillAndExpand"/>
<Label/>
<Label Text="fff" x:Name="ID" IsVisible="False"></Label>
<Button Text="Ver productos" TextColor="#FF5F6D" BackgroundColor="Yellow"></Button>
</StackLayout>
</StackLayout>
</StackLayout>
</ViewCell>

Related

How to make Grid Row dynamic in CollectionView control of .Net MAUI?

I'm trying to achieve dynamic row height in CollectionView control, so that when ever I have more text for a particular property it will extend the height of the frame automatically.
I have tried with ListView as well using HasUnEvenRow property "true" but with that also it's not working.
Here is my code:
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<Grid RowDefinitions="*,60" BackgroundColor="{StaticResource PageBackgroundColor}" Padding="0" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<CollectionView Grid.Row="0" HorizontalOptions="Fill" VerticalOptions="Fill"
ItemsSource="{Binding Inspections}"
VerticalScrollBarVisibility="Always"
ItemsLayout="VerticalList" ItemSizingStrategy="MeasureAllItems">
<CollectionView.ItemTemplate>
<DataTemplate>
<Frame Padding="15" HasShadow="False">
<Grid HorizontalOptions="Fill"
VerticalOptions="Fill"
BackgroundColor="White"
RowSpacing="25"
RowDefinitions="Auto,Auto,Auto"
ColumnDefinitions="*,Auto">
<StackLayout
Orientation="Horizontal"
Grid.Row="0"
Grid.Column="0">
<Label Text="{Binding Path=BusinessName}"
Style="{StaticResource LabelTitleStyle}" />
<Grid Padding="15,0,0,0">
<baseChip:Chip
HorizontalOptions="Fill" VerticalOptions="Fill"
Style="{StaticResource ChipContainer}"
HasShadow="False"
BackgroundColor="{Binding Path=ChipBackgroundColor}">
</baseChip:Chip>
<Label
Text="{Binding Path=ChipText}"
Style="{StaticResource ChipLabel}"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"
TextColor="{Binding Path=ChipTextColor}"/>
</Grid>
</StackLayout>
<Image
Grid.Row="0"
Grid.Column="1"
HorizontalOptions="End"
VerticalOptions="Center"
Aspect="AspectFit">
<Image.Source>
<FontImageSource Glyph="{x:Static helper:MaterialFontHelper.FilePdfBox}"
Color="{StaticResource DarkGray}"
Size="20"
FontFamily="MaterialDesignIcons"/>
</Image.Source>
</Image>
<Grid Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
RowDefinitions="Auto, Auto"
ColumnDefinitions="*, *">
<Label
Grid.Row="0"
Grid.Column="0"
Text="Inspection Type"
Style="{StaticResource LabelKeyStyle}" />
<Label
Grid.Row="1"
Grid.Column="0"
Text="ksd kahdkahd kahd kahd aojsoiud aasjlj sdlkja dlkja da asdadas alsajdlaksjdlajd alsjdalkjd alksjd sa"
Style="{StaticResource LabelValueStyle}" />
<Label
Grid.Row="0"
Grid.Column="1"
Text="Primary Inspector"
Style="{StaticResource LabelKeyStyle}" />
<Label
Grid.Row="1"
Grid.Column="1"
Style="{StaticResource LabelValueStyle}" >
<Label.FormattedText>
<FormattedString>
<Span Text="{Binding Path=InspectorFirstName}"/>
<Span Text=" "/>
<Span Text="{Binding Path=InspectorLastName}"/>
</FormattedString>
</Label.FormattedText>
</Label>
</Grid>
<Grid Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="2"
RowDefinitions="*, *"
ColumnDefinitions="*, *">
<Label
Grid.Row="0"
Grid.Column="0"
Text="Scheduled Date"
Style="{StaticResource LabelKeyStyle}" />
<Label
Grid.Row="1"
Grid.Column="0"
Text="{Binding Path=ScheduledStartDate, Converter={StaticResource dateFormatter},ConverterParameter='long'}"
Style="{StaticResource LabelValueStyle}" />
<Label
Grid.Row="0"
Grid.Column="1"
Text="Completed Date"
Style="{StaticResource LabelKeyStyle}" />
<Label
Grid.Row="1"
Grid.Column="1"
Text="{Binding Path=CompletionDate, Converter={StaticResource dateFormatter},ConverterParameter='long'}"
Style="{StaticResource LabelValueStyle}" />
</Grid>
</Grid>
</Frame>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<StackLayout
Grid.Row="1"
VerticalOptions="End"
HorizontalOptions="FillAndExpand"
BackgroundColor="{StaticResource White}">
<controlTemplate:BeginInspectionContentView></controlTemplate:BeginInspectionContentView>
</StackLayout>
</Grid>
</StackLayout>
Output & expected output image attached here:
How to achieve dynamic height for this UI? Any help or suggestions are welcome.
There are three solutions to this problem:
You can change CollectionView to FlexLayout with BindableLayout.ItemsSource and BindableLayout.ItemTemplate. Then you don't need to set Height for item or FlexLayout because all are dynamic.
You can set a value to collectionView.HeightRequest using MVVM. When item increase, the height will increase as well. For more details about this solution, you may refer to the link.
You can use CollectionView.Behaviors to calculate the Height of every item to increase the height of ContentView. For more details about this solution, you may refer to the link.
You have Grid. With StackLayout. With Grid. With Small Grids inside it.
I will put aside for now, that this is extremely bad for rendering. (It is serious problem however...)
None of the expected output justify this organization.
If you need for element to occupy 2 columns, you can use columns span 2.
Before anything else, please combine all 4 grids in a single grid.
After you are done with that, limit your VisualElements height, or, even better, limit the content you are putting in them. (Because cut content looks bad. You should be using something like "show more" link, that opens popup or whatever).
If you have any questions, please ask.
Edit: Let me clarify:
You have the same Grid code. Most important part - columns are * , * , and rows are auto height. And every 2 rows, you create another GRID, that is copy of the first GRID.
This is extremely counterproductive.
Also, just because you can do something, and it is "working in xamarin", it doesn't mean that you should do it.
First, put everything in the same grid, instead of nesting it and copying grids, then you can start working on CLIP/Height limit/etc.
(Recommending you to test it on IOS, because once you get it running fine there, it is much easier to fine-tune it for other platforms, than the other way around.)

Xamarin Forms Grid.Row Auto --> Still Shows Scrollbar in Grid Item

I have a slight problem with XamarinForms, which I am fairly new with.
I do have a grid with several Items in it (ListView, Label, Stacklayout, Listview).
I thought setting RowDefinitions = "Auto" for each row, would make the whole Page scrollable.
But instead I have a scrollbar on each individual listView.
I have added a snippet of my code with one of the listViews inside.
How do I get the listViews shown in their full size and the scrollbar be for the whole page?
I have already tried a scrollview instead of the grid, but it did not work.
Picture of Content in Emulator
Picture of Whole Page
Xamarin Forms:
<Grid
Padding="10"
RowDefinitions="Auto,Auto,Auto,Auto"
ColumnDefinitions="*"
>
<Label Padding="20" FontAttributes="Bold" FontSize="40" Text="{Binding DisplayName}" Grid.Row="0"/>
<ListView ItemsSource="{Binding News}"
HasUnevenRows="True"
IsPullToRefreshEnabled="False"
Grid.Row="1">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="10">
<Label Text="{Binding DateTimeString}"/>
<Label Text="{Binding Text}" MaxLines="4"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.Header>
<Grid ColumnDefinitions="*,Auto"
Padding="10"
VerticalOptions="Center">
<Label Text="News"
Grid.Column="0"
FontAttributes="Bold"
FontSize="32"/>
<Label Text="mehr Anzeigen"
Grid.Column="1"
HorizontalTextAlignment="End"/>
</Grid>
</ListView.Header>
</ListView>
You can put the items in ScrollView which is capable of scrolling its content.
refer to: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/layouts/scrollview

How to show each record of list one by one in page when swipe up/down in xamarin forms

I have a list of many records and i want to show each record on one single page.
What i want is, When we do swipe up from bottom of the page, next record in list should show with animation. similarly, when we do swipe down from top of the page, previous record in list should show with animation.
I don't know how to achieve this. hope for better solution
Caraousel View with orientation and snap points should give you desired results
<CarouselView BindingContext="{x:Reference BottomTabGridPageXaml}" ItemsSource="{Binding StudentList}"
VerticalOptions="FillAndExpand">
<CarouselView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical" SnapPointsType="MandatorySingle"/>
</CarouselView.ItemsLayout>
<CarouselView.ItemTemplate>
<DataTemplate>
<StackLayout VerticalOptions="FillAndExpand">
<Label Text="{Binding Id}" HorizontalOptions="Center" VerticalOptions="CenterAndExpand"/>
<Label Text="{Binding Name}" HorizontalOptions="Center" VerticalOptions="CenterAndExpand"/>
<Label Text="{Binding Number}" HorizontalOptions="Center" VerticalOptions="CenterAndExpand"/>
<Label Text="{Binding Age}" HorizontalOptions="Center" VerticalOptions="CenterAndExpand"/>
</StackLayout>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>

Label text inside AbsoluteLayout > StackLayout overflowing beyond Grid

My label text is overflowing beyond Grid, why?
<AbsoluteLayout x:Name="alIFirst" AbsoluteLayout.LayoutBounds="1,1,1,.50" AbsoluteLayout.LayoutFlags="All" BackgroundColor="#90000000">
<StackLayout>
<StackLayout>
<Label Style="{StaticResource beNewsSnapLabel}" Text="{Binding News_Item_Title_1}"/>
</StackLayout>
<StackLayout>
<Label Style="{StaticResource beNewsSnapLabelContent}" Text="{Binding News_Item_Description_1}"/>
</StackLayout>
</StackLayout>
</AbsoluteLayout>

TextWrapped Label breaks Layout Option FillAndExpand in StackLayout

I'm having a cell view with nested StackLayouts, there's one label that will be wrapped if the text is long, which is the desired behaviour. However, the wrap breaks the LayoutOptions set to (basically) all parent views resulting in a gray gap on the right hand side.
<StackLayout Orientation="Horizontal" BackgroundColor="Gray" Margin="0,30,0,0">
<BoxView
HorizontalOptions="Start"
BackgroundColor="#EEBB00"
WidthRequest="100"
/>
<StackLayout
BackgroundColor="#CC4400"
HorizontalOptions="FillAndExpand"
>
<BoxView
BackgroundColor="Green"
HeightRequest="10"
HorizontalOptions="FillAndExpand"
/>
<Label
FontSize="16"
HorizontalOptions="FillAndExpand"
Text="Name that is toolongandwillbewrapped"
/>
<StackLayout
Orientation="Horizontal"
HorizontalOptions="FillAndExpand"
BackgroundColor="Blue"
>
<Label
FontSize="13"
Text="Left"
TextColor="White"
HorizontalOptions="StartAndExpand"
VerticalTextAlignment="End"
/>
<Label
FontSize="13"
Text="Right"
TextColor="White"
HorizontalOptions="EndAndExpand"
VerticalTextAlignment="End"
/>
</StackLayout>
</StackLayout>
</StackLayout>
The resulting views are:
So I can tell why this is happening, but well, of course I don't like it. The expected behaviour is for the right-hand-side stacklayout to expand all the way to the right. I've tried various ways to circumvent this and would not be here if I had succeeded. Does anybody have an idea?
Unfortunately, it's a bug in Xamarin.Forms (probably, iOS-only).
Bugzilla #28650
Bugzilla #31128
Bugzilla #33841
The workaround in that case is using Grid instead of StackLayout : http://forums.xamarin.com/discussion/comment/152969/#Comment_152969

Resources