Xamarin iOS images overlapping inside Grid - xamarin

Heyo,
So in Xamarin I have a <Grid> with an <Image> and a couple <Label>s inside it, all wrapped inside a <ViewCell>. This looks totally fine in Xamarin.Android, however in Xamarin.iOS the images overlap the labels. I'm not sure what the difference could be - why does it look good in Xamarin.Android but in iOS its all wonky?
Below is my XAML and a couple mockups to show what I mean.
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Grid>
<Grid.ColumnDefinitions>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Grid.Column="0" Grid.Row="0" Aspect="AspectFill" Source="{Binding ImageOverlayEN}" />
<Label Grid.Column="0" Grid.Row="1" VerticalTextAlignment="Start" LineBreakMode="WordWrap" Text="{Binding DynamicOfferText}" FontSize="18">
<Label.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<OnPlatform.iOS>RobotoCondensed-Regular</OnPlatform.iOS>
<OnPlatform.Android>RobotoCondensed-Regular.ttf#RobotoCondensed-Regular</OnPlatform.Android>
<OnPlatform.WinPhone>RobotoCondensed-Regular.ttf#RobotoCondensed</OnPlatform.WinPhone>
</OnPlatform>
</Label.FontFamily>
</Label>
<Label Grid.Column="0" Grid.Row="2" VerticalTextAlignment="Start" LineBreakMode="WordWrap" Text="{Binding DynamicOfferDetail}" FontSize="16">
<Label.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<OnPlatform.iOS>RobotoCondensed-Regular</OnPlatform.iOS>
<OnPlatform.Android>RobotoCondensed-Regular.ttf#RobotoCondensed-Regular</OnPlatform.Android>
<OnPlatform.WinPhone>RobotoCondensed-Regular.ttf#RobotoCondensed</OnPlatform.WinPhone>
</OnPlatform>
</Label.FontFamily>
</Label>
</Grid>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
I tried setting the HeightRequest but that didn't seem to make a difference:
#if __IOS__
if (viewModel.Items.Count > 0)
{
MyListView.HeightRequest = 300 * viewModel.Items.Count;
}
#endif
Here is a visual representation of what is happening:

Figured it out - had to do with my RowDefinitions being all set to Auto
This got it looking just right:
<RowDefinition Height="1*" />
<RowDefinition Height="0.18*" />
<RowDefinition Height="0.77*" />
I think what was happening is the ListView renders first, the Auto row definition heights set the height of each row before the image is done loading, then the image finishes loading and overlaps the rest of the list view's item (including the labels). This might just be a quirk of iOS, where as Android calculates the row heights after the images are done loading (explaining why it looked fine in Android)

Related

Xamarin grid with buttons inside not clicking

Good afternoon all,
Having an interesting issue here where by I have 4 buttons within a grid that all work ... kind of ... the top two buttons work without an issue however the bottom two you can only click the top half of the button otherwise it does not register the action.
Below is the Xaml code I am using ... Hope this helps... so far everything I have read doesn't seem to work so I can only assume I am missing something very simple.
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="HomemasterMobileApplication.Views.HomePage"
Title=""
BackgroundImageSource = "HousingBackground2">
<ContentView >
<ScrollView>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
<RowDefinition Height="100"/>
<RowDefinition Height="15"/>
<RowDefinition Height="260"/>
</Grid.RowDefinitions>
<StackLayout Grid.Row="1" />
<StackLayout Grid.Row="1" Orientation="Horizontal" HorizontalOptions="Center" Padding="0,0,0,0" VerticalOptions="Center" Opacity="0.8" BackgroundColor="#002D485D" >
<ContentView>
<ImageButton Source="HomeMasterLogo.png" HeightRequest="100" CornerRadius="25"/>
</ContentView>
</StackLayout>
<StackLayout Grid.Row="3" Orientation="Horizontal" Padding="0,15,0,0" Spacing="5" HorizontalOptions="Center">
<Grid>
<Grid.ColumnDefinitions >
<!--0--><ColumnDefinition Width="10*"/>
<!--1--><ColumnDefinition Width="40*"/>
<!--2--><ColumnDefinition Width="10*"/>
<!--3--><ColumnDefinition Width="40*"/>
<!--4--><ColumnDefinition Width="10*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<!--0--><RowDefinition Height="10"/>
<!--1--><RowDefinition Height="125"/>
<!--2--><RowDefinition Height="40"/>
<!--3--><RowDefinition Height="125"/>
</Grid.RowDefinitions>
<Button ImageSource="homeuser24px"
BackgroundColor="#00AAA9"
BorderColor="White"
Opacity="1"
Text="Your Account"
TextTransform="Default"
BorderWidth="2"
CornerRadius="100"
TextColor="White"
FontSize="14"
Clicked="OnAccountClick"
Grid.Row="1" Grid.Column="1"
/>
<Button ImageSource="toolsadd24px"
BackgroundColor="#00AAA9"
BorderColor="White"
Opacity="1"
Text="Log a Repair"
TextTransform="Default"
BorderWidth="2"
CornerRadius="100"
TextColor="White"
FontSize="14"
Clicked="OnRepairRequestClick"
Grid.Row="1" Grid.Column="3"
/>
<Button ImageSource="toolsinfo24px"
BackgroundColor="#00AAA9"
BorderColor="White"
TextTransform="Default"
Opacity="1"
BorderWidth="2"
CornerRadius="100"
TextColor="White"
Text="Track a Repair"
FontSize="14"
Clicked="OnCheckRepairsClick"
Grid.Row="3" Grid.Column="1"
/>
<Button
Clicked="OnPersonalDetailsClick"
ImageSource="userinfo24px"
BackgroundColor="#00AAA9"
BorderColor="White"
TextTransform="Default"
Opacity="1"
BorderWidth="2"
CornerRadius="100"
TextColor="White"
Text="My Details"
FontSize="14"
Grid.Row="3" Grid.Column="3"
/>
</Grid>
</StackLayout>
</Grid>
</ScrollView>
</ContentView>
You need to use the DN function within the grid to adjust the grid height.
First, you define the grid on the outermost layer. The problem lies in Grid.Row="3".
Then you create another Grid in Grid.Row="3",But the height of Grid.Row="3" you define in the outer Grid is 260.Your internal view height exceeds it. Therefore, the view will be overwritten.
In general, you only need to increase the height of the external Grid.
<ScrollView>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
<RowDefinition Height="100"/>
<RowDefinition Height="15"/>
<RowDefinition Height="400"/>
<!--Change the bottom height to 400-->
</Grid.RowDefinitions>
....
</ScrollView>

How to change the style of tab in segment control in xamarin forms

I have a segment control where I'm displaying tabs. But I'm not able to edit the style of the tab in Xamarin Forms. This is the UI I want
This is how I want to display my tabs in the segment control. I'm able to change the tint color, background color, and text color but none of that will get me a tab in this style. This is my current UI
This is XAML code where I implemented the segment control
<controls:SegmentedControl BackgroundColor="White" SelectedTextColor="Black" TintColor="#FFA500" x:Name="SegControl" ValueChanged="Handle_ValueChanged">
<controls:SegmentedControl.Children>
<controls:SegmentedControlOption Text="VENDOR NAME" />
<controls:SegmentedControlOption Text="PRODUCT/SERVICE" />
</controls:SegmentedControl.Children>
</controls:SegmentedControl>
<StackLayout x:Name="SegContent" />
</StackLayout>
<StackLayout Margin="0,30,0,0">
<StackLayout AbsoluteLayout.LayoutBounds=".20,1,1,.1" AbsoluteLayout.LayoutFlags="All" BackgroundColor="White" HorizontalOptions="FillAndExpand" Orientation="Horizontal">
<StackLayout Style="{StaticResource ButtonNavigationBarStackLayoutStyle}" x:Name="stckNear">
<Image Margin="0,10,0,10" x:Name="imgNear" Style="{StaticResource ButtonNavigationBarImageStyle}" />
<Label Text="Near" Style="{StaticResource ButtonNavigationBarLabelStyle}"></Label>
</StackLayout>
<StackLayout Style="{StaticResource ButtonNavigationBarStackLayoutStyle}" x:Name="stckSearch">
<Image Margin="0,10,0,10" x:Name="imgSearch" Style="{StaticResource ButtonNavigationBarImageStyle}" />
<Label Text="Search" Style="{StaticResource ButtonNavigationBarLabelStyle}"></Label>
</StackLayout>
<StackLayout Style="{StaticResource ButtonNavigationBarStackLayoutStyle}" x:Name="stckCart">
<Image Margin="0,10,0,10" x:Name="imgCart" Style="{StaticResource ButtonNavigationBarImageStyle}" />
<Label Text="Cart" Style="{StaticResource ButtonNavigationBarLabelStyle}"></Label>
</StackLayout>
<StackLayout Style="{StaticResource ButtonNavigationBarStackLayoutStyle}" x:Name="stckAccount">
<Image Margin="0,10,0,10" x:Name="imgAccount" Style="{StaticResource ButtonNavigationBarImageStyle}" />
<Label Text="Account" Style="{StaticResource ButtonNavigationBarLabelStyle}"></Label>
</StackLayout>
</StackLayout>
I'm not using any custom renderer for this segment control. Do I have to use a custom renderer for implementing the required UI? If yes how? Any suggestions?
SegmentedControl is not a built in Xamarin.Forms control. There are a few libraries that offer a SegmentedControl, so it would help to know which one you are using.
That said, the library author who created that SegmentedControl also made the platform renderers and so the different look on iOS vs Android is a result of that.
You can, of course, create your own custom renderer, but then why use the library?
Easier to me would be to make a control using Xamarin Forms, for instance you can use a grid that has a first row of two labels ( or Buttons) and a second row of 2 BoxViews that can act as the underline (very short height). Then just add TapGestureRecognizers to each Label (or just use a Buttons and style as needed).
Here's an example using Buttons and BoxViews:
XAML:
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button x:Name="vBtn"
Text="VENDOR NAME" Clicked="Handle_Clicked"
TextColor="Black"
BackgroundColor="Transparent"
BorderColor="Transparent"
Grid.Row="0"
Grid.Column="0"/>
<Button x:Name="pBtn"
Text="PRODUCT/SERVICE" Clicked="Handle_Clicked"
TextColor="Black"
BackgroundColor="Transparent"
BorderColor="Transparent"
Grid.Row="0"
Grid.Column="1" />
<BoxView x:Name="vBox"
Color="#FFA500" HeightRequest="5"
Grid.Row="1"
Grid.Column="0"/>
<BoxView x:Name="pBox"
Color="Silver" HeightRequest="5"
Grid.Row="1"
Grid.Column="1"/>
</Grid>
Code behind:
void Handle_Clicked(object sender, System.EventArgs e)
{
Button btn = sender as Button;
if (btn.Text == "PRODUCT/SERVICE")
{
vBox.Color = Color.Silver;
pBox.Color = Color.FromHex("#FFA500");
// Do anything else you need to do when the PRODUCT/SERVICE is tapped
}
else
{
vBox.Color = Color.FromHex("#FFA500");
pBox.Color = Color.Silver;
// Do anything else you need to do when the VENDOR NAME is tapped
}
}
No library or custom renderer needed.

Xamarin forms custom scrollview showing weird behavior

I have a customized ScrollView as per the requirement which is based on the TLScrollView.
Now when I am adding some data to it there is weird behaviour that I noticed recently a part of the screen area is unclickable, And the rest of the part works fine.
Now the same code works like a charm on Android but iOS is showing this weird behaviour,
Xaml:
<controls:TLScrollView Orientation="Horizontal" BackgroundColor="White"
x:Name="ListAddons" ItemsSource="{Binding ListAddons}" AbsoluteLayout.LayoutFlags = "All"
AbsoluteLayout.LayoutBounds = "0.5, 0.5, 1.0, 1.0">
<controls:TLScrollView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout BackgroundColor="Transparent" Margin = "0, 5, 0, 0">
<Grid BackgroundColor="White" InputTransparent="true" RowSpacing = "0" ColumnSpacing = "0">
<Grid.RowDefinitions>
<RowDefinition Height="0.5*" />
<RowDefinition Height="45.0*" />
<RowDefinition Height="45*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="1" />
</Grid.ColumnDefinitions>
<ffimageloading:CachedImage Source="{Binding Icon, Converter={StaticResource Base64ToImageConverter}}"
ErrorPlaceholder = "nopreviewlandscape" LoadingPlaceholder = "loadingicon"
Grid.Row="1" Grid.Column="0" HorizontalOptions="Center"
VerticalOptions="Center" Aspect="AspectFill" />
<Label x:Name="lblRecommendationsName" Margin="0" Text="{Binding CategoryName}"
LineBreakMode="WordWrap" XAlign="Center" TextColor="{StaticResource gray_text_color}"
VerticalOptions="Center" HorizontalOptions="Center" Grid.Row="2"
Grid.Column="0" Style="{StaticResource RecommendationName}">
<Label.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<On Platform="iOS" Value="OpenSans-Light" />
<On Platform="Android" Value="OpenSans-Light" />
</OnPlatform>
</Label.FontFamily>
<Label.TextColor>
<OnPlatform x:TypeArguments="Color">
<On Platform="Android" Value="#000000"></On>
</OnPlatform>
</Label.TextColor>
</Label>
<BoxView WidthRequest="0" Grid.Row="1" Grid.Column="1"
BackgroundColor="{StaticResource separator_color}"
Grid.RowSpan="4" Style="{StaticResource BoxViewHomeStyle}">
</BoxView>
</Grid>
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Path=BindingContext.AddonsClickCommand,Source={x:Reference ListAddons}}"
CommandParameter="{Binding CategoryId}"
/>
</StackLayout.GestureRecognizers>
</StackLayout>
</ViewCell>
</DataTemplate>
</controls:TLScrollView.ItemTemplate>
</controls:TLScrollView>
First, I thought there must be some sort of an overlapping in there which might be causing this but then I realized that the same code was working on Android devices and causing this on iOS.
The part of the image that is unclickable is inside the black box everywhere else the click event works well.
It may have nothing to do with this problem but I think "Grid.RowSpan" of BoxView may cause problem.
The Grid have only three rows(0-2 rows) definitions but BoxView specified to merge 1 to 4 rows.
<Grid.RowDefinitions>
<RowDefinition Height="0.5*" />
<RowDefinition Height="45.0*" />
<RowDefinition Height="45*" />
</Grid.RowDefinitions>
<BoxView WidthRequest="0" Grid.Row="1" Grid.Column="1"
BackgroundColor="{StaticResource separator_color}"
Grid.RowSpan="4" Style="{StaticResource BoxViewHomeStyle}">
</BoxView>
Well, I am not sure what was causing the issue but updating to the latest version of Xamarin.Forms fixed the bug!
I updated to Xamarin.Forms version 4.5.0.396
Feel free to get back if you are facing a similar issue.

Xamarin 3 StackLayouts

I am making a page where there is a top title, an image in the middle and some text under it and then two buttons at the bottom for yes or no. As you can see the buttons are getting pushed down too much and getting cut off. I can't figure out how to move the text up a little or reduce the spacing between the image and the title and text. I know I probably could do this with absolute layouts but I am not sure how it would work with larger/smaller screens.
Here is my XAML for the image.
<ContentPage BackgroundColor="#FF233D">
<ContentPage.Content>
<StackLayout Padding="10,10,10,10">
<StackLayout VerticalOptions="Start">
<Label TextColor = "White" Text="You're having trouble sleeping." FontSize="Large" HorizontalTextAlignment="Center"></Label>
<Image Scale=".65" Source="bed" >
</Image>
</StackLayout>
<StackLayout VerticalOptions="CenterAndExpand">
<Label TextColor = "White" Text="When the kidneys aren't filtering properly, toxins stay in the blood rather than leaving the body through the urine. This can make it difficult to sleep. There is also a link between obesity and chronic kidney disease, and sleep apnea is more common in those with chronic kidney disease, compared with the general population." HorizontalTextAlignment="Center"></Label>
</StackLayout>
<StackLayout Orientation="Horizontal" VerticalOptions="EndAndExpand" >
<Button Text="Yes" Clicked="YesClicked" ClassId="1Yes" x:Name="Yes1" HorizontalOptions="FillAndExpand" BackgroundColor="#27ae60" TextColor="White" BorderRadius="0">
</Button>
<Button Text="No" Clicked="NoClicked" ClassId="1No" x:Name="No1" HorizontalOptions="FillAndExpand" BackgroundColor="#c0392b" TextColor="White" BorderRadius="0" >
</Button>
</StackLayout>
</StackLayout>
</ContentPage.Content>
</ContentPage>
Any help is much appreciated.
It will be easier if you use a Grid with 4 rows and two columns
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label TextColor = "White" Text="You're having trouble sleeping." FontSize="Large" HorizontalTextAlignment="Center" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" />
<Image Scale=".65" Source="bed" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" >
<Label TextColor = "White" Text="When the kidneys aren't filtering properly, toxins stay in the blood rather than leaving the body through the urine. This can make it difficult to sleep. There is also a link between obesity and chronic kidney disease, and sleep apnea is more common in those with chronic kidney disease, compared with the general population." HorizontalTextAlignment="Center" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2"/>
<Button Text="Yes" Clicked="YesClicked" ClassId="1Yes" x:Name="Yes1" HorizontalOptions="FillAndExpand" BackgroundColor="#27ae60" TextColor="White" BorderRadius="0" Grid.Row="3" Grid.Column="1" />
<Button Text="No" Clicked="NoClicked" ClassId="1No" x:Name="No1" HorizontalOptions="FillAndExpand" BackgroundColor="#c0392b" TextColor="White" BorderRadius="0" Grid.Row="3" Grid.Column="0" />
Try to adjust rows Hheight and width if the result is different from your needs.
For more information about grids : Microsoft docs

HorizontalTextAlignment - iOS (Not working as intended)

I have a problem when using HorizontalTextAlignment="Center" on iOS cause it is properly working on Android. The problem is that it is not properly wrapping the sentence to next line as intended.
This is my result:
Code:
<Grid HorizontalOptions="CenterAndExpand" VerticalOptions="Center" Grid.Row="3">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Text="{Binding lblItem}"
TextColor="#BCBCBC"
FontFamily="Calibri"
Grid.Row="0"
Grid.Column="0"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center"
HorizontalOptions="Center">
<Label.Margin>
<OnIdiom x:TypeArguments="Thickness">
<OnIdiom.Tablet>
<OnPlatform x:TypeArguments="Thickness" iOS="0,5,0,0" Android="0,5,0,0" WinPhone="0,0,0,0"/>
</OnIdiom.Tablet>
<OnIdiom.Phone>
<OnPlatform x:TypeArguments="Thickness" iOS="0,0,0,0" Android="0,0,0,0" WinPhone="0,0,0,0"/>
</OnIdiom.Phone>
</OnIdiom>
</Label.Margin>
</Label>
</Grid>
How can I properly use the HorizontalTextAlignment="Center" to properly wrap it around in a layout?
EDIT: Seems like there is something wrong when wrapping a text that is binded behind the vm, for now I do not know why but, I am trying to look for work around. Gonna keep this post updated if ever I found a solution.
In order to wrap text around, you'll have to set the Label.LineBreakMode property to WordWrap (see here and here).
<Grid HorizontalOptions="CenterAndExpand" VerticalOptions="Center" Grid.Row="3">
<!-- ... -->
<Label Text="{Binding lblItem}"
LineBreakMode="WordWrap"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center"
HorizontalOptions="Center">
<!-- ... -->
</Label>
</Grid>
This should break the text correctly.
Maybe you have to set the HorizontalOptions to Fill instead of Center.
I have fixed the problem, seems like the Label's Horizontal/Vertical.TextAlignment has a bug on iOS if you are binding the Label's Text. In order to fix this I created a CustomRenderer for this label specifically on iOS:
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
if (e.NewElement == null) return;
var ctrl = (YourLabel)Element;
ctrl.HorizontalTextAlignment = TextAlignment.Center;
ctrl.VerticalTextAlignment = TextAlignment.Center;
}

Resources