How can I code-behind use Font Awesome in Xamarin Forms? - xamarin

I'm having difficulty creating a form with Font Awesome text. Everything works fine when I'm doing it in .xaml file, like this:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
x:Name="contentPage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="myappname.Main">
<Label Text=""
FontFamily="Font Awesome 5 Free-Solid-900.otf#Regular"
FontSize="40" />
</ContentPage>
The result is:
Assets catalog:
I'm not creating my app for iOS so I haven't added any additional configuration, i.e. configuring ResourceDictionary. This is what I've tried in Main.xaml.cs (I'll show three ways of doing it because I'm not sure how exactly it should work):
protected override async void OnAppearing()
{
Label newLabel = new Label()
{
Text = "",
FontFamily = "Font Awesome 5 Free-Solid-900.otf#Regular",
FontSize = 40
};
contentPage.Content = newLabel;
}
protected override async void OnAppearing()
{
Label newLabel = new Label()
{
Text = "",
FontFamily = "Font Awesome 5 Free-Solid-900.otf#Font Awesome 5 Free-Solid-900.otf",
FontSize = 40
};
contentPage.Content = newLabel;
}
protected override async void OnAppearing()
{
Label newLabel = new Label()
{
Text = "",
FontFamily = "Font Awesome 5 Free-Solid-900.otf#Font Awesome 5 Free-Solid-900",
FontSize = 40
};
contentPage.Content = newLabel;
}
The result in every of them is:
What am I doing wrong?

Try using \u instead of &#x
so it should look like this:
Text = "\uf00c",

Related

Xamarin: Adding borders to the selected tab item

In Xamarin.Forms on Android, I'm working on a section that uses a tabbed page. I'm attempting to place a set of borders around the selected item like such:
and
Is there any way that such a goal can be achieved using custom renderers?
According to your description, if you want to change selected item color in TabbedPage, you can use the following code:
<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage
x:Class="TabbedPageDemo.TabbedPage2"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
xmlns:local="clr-namespace:TabbedPageDemo"
android:TabbedPage.BarItemColor="Gray"
android:TabbedPage.BarSelectedItemColor="#3C9BDF"
android:TabbedPage.ToolbarPlacement="Bottom"
BarTextColor="Gray">
<!-- Pages can be added as references or inline -->
<ContentPage Title="Tab 1" />
<ContentPage Title="Tab 2" />
<ContentPage Title="Tab 3" />
</TabbedPage>
If you want to change selected item text size, you can use custom render to do this:
[assembly: ExportRenderer(typeof(ExtendedTabbedPage), typeof(ExtendedTabbedPageRenderer))]
namespace CustomTabbedPage.Droid
{
public class ExtendedTabbedPageRenderer : TabbedPageRenderer
{
Xamarin.Forms.TabbedPage tabbedPage;
BottomNavigationView bottomNavigationView;
Android.Views.IMenuItem lastItemSelected;
private bool firstTime = true;
int lastItemId=-1;
public ExtendedTabbedPageRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.TabbedPage> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
tabbedPage = e.NewElement as ExtendedTabbedPage;
bottomNavigationView = (GetChildAt(0) as Android.Widget.RelativeLayout).GetChildAt(1) as BottomNavigationView;
//Call to change the font
ChangeFont();
}
}
//Change Tab font
void ChangeFont()
{
var fontFace = Typeface.CreateFromAsset(Context.Assets, "gilsansultrabold.ttf");
var bottomNavMenuView = bottomNavigationView.GetChildAt(0) as BottomNavigationMenuView;
for (int i = 0; i < bottomNavMenuView.ChildCount; i++)
{
var item = bottomNavMenuView.GetChildAt(i) as BottomNavigationItemView;
var itemTitle = item.GetChildAt(1);
var smallTextView = ((TextView)((BaselineLayout)itemTitle).GetChildAt(0));
var largeTextView = ((TextView)((BaselineLayout)itemTitle).GetChildAt(1));
lastItemId = bottomNavMenuView.SelectedItemId;
//smallTextView.SetTypeface(fontFace, TypefaceStyle.Bold);
//largeTextView.SetTypeface(fontFace, TypefaceStyle.Bold);
smallTextView.TextSize = 18;
largeTextView.TextSize = 18;
//Set text color
var textColor = (item.Id == bottomNavMenuView.SelectedItemId) ? tabbedPage.On<Xamarin.Forms.PlatformConfiguration.Android>().GetBarSelectedItemColor().ToAndroid() : tabbedPage.On<Xamarin.Forms.PlatformConfiguration.Android>().GetBarItemColor().ToAndroid();
smallTextView.SetTextColor(textColor);
largeTextView.SetTextColor(textColor);
}
}
}
}
If you want to add border line for tabbar, please take a look this thread:
Xamarin Tab Bar top(border) line

How to create a Xamarin Tooltip in code-behind

I am testing using the following example. https://github.com/CrossGeeks/TooltipSample
The sample works fine, it even works with Labels (sample uses buttons, images and boxviews). The issue is in my main App I need to create the tooltips in code behind.
To test how to do it, in the very same solution (from that above example) I created a TestPage and made it my MainPage in App.xaml.cs. The XAML looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ToolTipSample.TestPage">
<ContentPage.Content>
<StackLayout
x:Name="mainLayout"
BackgroundColor="Yellow">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Tapped="Handle_Tapped"/>
</StackLayout.GestureRecognizers>
</StackLayout>
</ContentPage.Content>
The code-behind looks like this:
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using ToolTipSample.Effects;
namespace ToolTipSample
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class TestPage : ContentPage
{
public TestPage()
{
InitializeComponent();
var actionLabel = new Label
{
Text = "Show Tooltip",
WidthRequest = 150,
VerticalOptions = LayoutOptions.StartAndExpand,
HorizontalOptions = LayoutOptions.Center,
BackgroundColor = Color.Wheat
};
// Add tooltip to action label
TooltipEffect.SetPosition(actionLabel, TooltipPosition.Bottom);
TooltipEffect.SetBackgroundColor(actionLabel, Color.Silver);
TooltipEffect.SetTextColor(actionLabel, Color.Teal);
TooltipEffect.SetText(actionLabel, "This is the tooltip");
TooltipEffect.SetHasTooltip(actionLabel, true);
actionLabel.Effects.Add(Effect.Resolve($"CrossGeeks.{nameof(TooltipEffect)}"));
mainLayout.Children.Add(actionLabel);
}
void Handle_Tapped(object sender, System.EventArgs e)
{
foreach (var c in mainLayout.Children)
{
if (TooltipEffect.GetHasTooltip(c))
{
TooltipEffect.SetHasTooltip(c, false);
TooltipEffect.SetHasTooltip(c, true);
}
}
}
}
}
All other code unchanged.
When I tap the label, the tooltip appears as expected. But when I tap the background it does not disappear (like those created in XAML in the sample).
One other thing. If I tap twice it disappears.
Can anyone see what I am missing?
Thanks.
According to your description and code, you can delete the following line code to achieve your requirement.
actionLabel.Effects.Add(Effect.Resolve($"CrossGeeks.{nameof(TooltipEffect)}"));
You don't need to add effect for control when page load, because this effect will be added when you click this control by these code:
static void OnHasTooltipChanged(BindableObject bindable, object oldValue, object newValue)
{
var view = bindable as View;
if (view == null)
{
return;
}
bool hasTooltip = (bool)newValue;
if (hasTooltip)
{
view.Effects.Add(new ControlTooltipEffect());
}
else
{
var toRemove = view.Effects.FirstOrDefault(e => e is ControlTooltipEffect);
if (toRemove != null)
{
view.Effects.Remove(toRemove);
}
}
}

Returning WebView from ContentView in Xamarin

I am trying to use a custom ContentView inside another page of my Xamarin Application. This custom ContentView is used for displaying HTML content (specifically gifs). When trying to load the ContentView from another page, it throws an error : "Value cannot be null. Parameter name thisActivity"
My code is based off the examples in here.
Am I missing a key step in getting a WebView to render via a custom ContentView?
//This is my Custom ContentView
public class GifView : ContentView
{
public GifView()
{
this.BuildPage();
}
public WebView BuildWebView()
{
var htmlSource = new HtmlWebViewSource
{
Html = #"<html><body><h1>This is a test</h1></body></html>"
};
WebView webView = new WebView
{
WidthRequest = 1000,
HeightRequest = 1000,
Source = htmlSource
};
return webView;
}
public void BuildPage()
{
var webView = this.BuildWebView();
this.Content = new StackLayout
{
Children =
{
webView
}
};
}
}
// This is the XAML where I am trying to use the custom view.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:myproject"
x:Class="myproject.MainPage"
xmlns:views="clr-namespace:myproject.Views">
<views:GifView />
</ContentPage>
OK this is a very silly error. The solution deploys fine and works on an Android phone. I guess the Design feature of Visual Studio is bugged and is displaying an incorrect error.

Search bar remove text is not working in xamarin ios

I am working with search bar in xamarin forms. I am not able to remove search text in search bar by clicking cross button. I am using custom renderer for remove cancel text in search bar. When I am using that renderer I am not able delete the text, If I remove that renderer it work's fine. what the wrong I have done in renderer file. Here is the sample code in renderer for hide the cancel button beside the search bar.
Renderer Sample code:
protected override void OnElementPropertyChanged(object sender, PropertyChnagedEventArgs e)
{
Control.ShowCancelButton = false;
}
When I try to remove text in search bar by clicking cross image in search bar it's not working in xamarin ios but it's working fine in ios.
Sample code :
<StackLayout Grid.Column = "0" Orientation = "Horizontal">
<Image Source = "backarrow.png" HorizontalOptions = "StartAndExpand" VerticalOptions = "CenterAndExpand" />
<controls:CustomSearchbar x:Name = "CustomSearchbar" BackgroundColor ="Transparent" Text ="{Binding SearchTag}" SearchCommand ="{Binding RestaurantSearchCommand}" GHorizontalOptions = "StartAndExpand" VerticalOptions = "CenterAndExpand" >
Here is the code I am using for search bar. Here 'customsearchbar' class is inherited from searchrenderer.
It works fine for me.
Here's my code for example:
MySearchBar.cs in PCL:
using Xamarin.Forms;
namespace Kevin_XF
{
public class MySearchBar : SearchBar
{
}
}
MySearchBarRenderer.cs in iOS platform:
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using Kevin_XF.iOS;
using Kevin_XF;
using System.ComponentModel;
[assembly: ExportRenderer(typeof(MySearchBar),typeof(MySearchBarRenderer))]
namespace Kevin_XF.iOS
{
public class MySearchBarRenderer: SearchBarRenderer
{
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (Control != null)
{
Control.ShowsCancelButton = false;
}
}
}
}
Xaml code in MainPage.xaml:
<StackLayout>
<local:MySearchBar x:Name = "CustomSearchbar" BackgroundColor ="Transparent" HorizontalOptions = "StartAndExpand" VerticalOptions = "CenterAndExpand" />
</StackLayout>
It works like this:

With a custom renderer can I make a TableSection.Title appear in small mixed case?

Here's what I currently have:
<TableView Intent="Settings">
<TableRoot>
<TableSection>
<TableSection.Title>
This appears in uppercase
</TableSection.Title>
Is there a way perhaps with an iOS custom renderer that I could convert the font that displays to a mixed upper and lower case and make the font size smaller such as I see Apple user in Settings > Control Center ?
For iOS you need for XF TableView TableViewRenderer with native control of UITableView. More here:
https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/custom-renderer/renderers/
Below is the solution. The code in renderer of function Draw should be done in OnElementChanged but unfortunately it seems like Xamarin has a bug https://bugzilla.xamarin.com/show_bug.cgi?id=58731 Another problem that text conversion doesn't work either https://bugzilla.xamarin.com/show_bug.cgi?id=58732
One more small optimisation - to avoid doing text conversion in renderer every time control drawn textDecapitalized was added.
Answering another question how to change text size I added hv.TextLabel.Font set (commented out but working).
so, working around these 2 bugs:
XML
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:ButtonRendererDemo;assembly=ButtonRendererDemo"
x:Class="ButtonRendererDemo.CustomTablePage">
<ContentPage.Content>
<local:CustomTableView Intent="Settings">
<TableRoot>
<TableSection Title="First Case Sensitive Header">
<SwitchCell Text="New Voice Mail" />
</TableSection>
<TableSection Title="Second Case Sensitive Header">
<SwitchCell Text="New Mail" On="true" />
</TableSection>
</TableRoot>
</local:CustomTableView>
</ContentPage.Content>
</ContentPage>
Page code
namespace ButtonRendererDemo
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class CustomTablePage : ContentPage
{
public CustomTablePage()
{
InitializeComponent();
}
}
public class CustomTableView : TableView
{
}
}
Renderer
[assembly: ExportRenderer(typeof(CustomTableView), typeof(CustomTableViewRenderer))]
namespace ButtonRendererDemo.iOS
{
public class CustomTableViewRenderer : TableViewRenderer
{
bool textDecapitalized = false;
public override void Draw(CGRect rect)
{
base.Draw(rect);
if (!textDecapitalized)
{
textDecapitalized = true;
var tableView = Control as UITableView;
var numSections = tableView.NumberOfSections();
for (nint s = 0; s < numSections; s++)
{
var hv = tableView.GetHeaderView(s);
if (hv != null) //always null in OnElementChanged. Bug reported
{
//unfortunately TextInfo doesn't work. Bug reported
//TextInfo textInfo = new CultureInfo("en-US", false).TextInfo;
// OR
//TextInfo textInfo = Thread.CurrentThread.CurrentCulture.TextInfo;
if (hv.TextLabel.Text.ToUpper().StartsWith("FIR"))
hv.TextLabel.Text = "First Case Sensitive Header";
else if (hv.TextLabel.Text.ToUpper().StartsWith("SEC"))
hv.TextLabel.Text = "Second Case Sensitive Header";
//hv.TextLabel.Font = UIFont.FromName(hv.TextLabel.Font.Name, 5f);
}
}
}
}
}
}
Final result with small font case sensitive header

Resources