UWPではアイコンフォントがSymbol 列挙値として定義されていて簡単にアイコンフォントを表示する事ができますが、残念ながらXamarinにはこのような機能はありません。
そこでXamarin Formsでも同じアイコンフォントを使えるようにしたいと思います。
準備
Symbol 列挙値で表示されるのはSegoe MDL2 Assetsというフォントで、Windows 10から組み込まれています。
UWPアプリの開発でハンバーガーメニューを表示する際などにもSymbolThemeFontFamilyとして用いられます。
エクスプローラーで「C:\Windows\Fonts」を開き、フォントファイルを取り出します。他のフォルダにコピーすると分かりますがファイル名は「segmdl2.ttf」です。
[追記]
Segoe MDL2 Assetsフォントのライセンスについて記載されたドキュメントが見つからない為、ソフトウェアに組み込んで配布可能であるか不明です。このブログ記事ではこれを許可や推奨するものではありません。
Font Awesome フォント
さて、UWPのアイコンフォントをiOSとAndroidでも表示したいというのが発端でしたが、せっかくなので他のアイコンフォントも表示してみます。 今回は「Font Awesome」のアイコンフォントを使います。ダウンロードかGitHubから「FontAwesome.otf」を入手します。
フォントの登録
UWP
「FontAwesome.otf」をUWPプロジェクトのどこかに格納しプロパティを以下に設定します。
今回はAssets配下に「Fonts」フォルダを作成して格納します。
Assets/Fonts/FontAwesome.otf
ビルドアクション : コンテンツ
出力ディレクトリにコピー : コピーしない
Android
「segmdl2.ttf」と「FontAwesome.otf」をAndroidプロジェクトの「Assets」に格納しプロパティを以下に設定します。
今回は「Fonts」フォルダを作成して格納します。
Assets/Fonts/FontAwesome.otf
Assets/Fonts/segmdl2.ttf
ビルドアクション : AndroidAsset
出力ディレクトリにコピー : コピーしない
iOS
「segmdl2.ttf」と「FontAwesome.otf」をiOSプロジェクトの「Resources」に格納しプロパティを以下に設定します。
今回は「Fonts」フォルダを作成して格納します。
Resources/Fonts/FontAwesome.otf
Resources/Fonts/segmdl2.ttf
ビルドアクション : BundleResource
出力ディレクトリにコピー : コピーしない
次に「Info.plist」にフォント情報を追記します。「Info.plist」を右クリックし「ファイルを開くアプリケーションを選択」から「XMLテキストエディタ」を選択します。
「UIAppFonts」キーを作成してフォントファイルのパスをString配列で記載します。
※Resourcesフォルダからの相対パスです
<plist version="1.0"> <dict> <key>UIAppFonts</key> <array> <string>Fonts/FontAwesome.otf</string> <string>Fonts/segmdl2.ttf</string> </array> :
※ダブルクリックで開くとPlistEditorが表示されますが、それだとフォント情報の登録ができません。
カスタムレンダラーの作成
AndroidではLabel.FontFamily等でフォント名を指定しても独自に追加したフォントは探してくれません。そこでカスタムレンダラーを作る必要があります。
[assembly: ExportRenderer(typeof(Label), typeof(XFApp1.Droid.CustomFontLabelRenderer))] namespace XFApp1.Droid { public class CustomFontLabelRenderer : LabelRenderer { protected override void OnElementChanged(ElementChangedEventArgs<Label> e) { base.OnElementChanged(e); var fontFamily = e.NewElement.FontFamily?.ToLower(); if (fontFamily != null && (fontFamily.EndsWith(".otf") || fontFamily.EndsWith(".ttf"))) { var lable = (TextView)Control; lable.Typeface = Typeface.CreateFromAsset(Forms.Context.Assets, e.NewElement.FontFamily); } } } }
既存のフォントの指定と追加したフォントの指定とを区別する為、後者はファイル名で指定する仕様としました。
XAMLの記述
LabelのFontFamilyを以下のルールで記載します。
iOS
既存のフォント : フォント名
追加したフォント : フォント名
Android
既存のフォント : フォント名
追加したフォント : フォントファイルのパス
※Assetsフォルダからの相対パス
UWP
既存のフォント : フォント名
追加したフォント : フォントファイルのパス#フォント名
※プロジェクトフォルダからの相対パス
<Label Text="FontAwesome" /> <Label Text="     " FontSize="24"> <Label.FontFamily> <OnPlatform x:TypeArguments="x:String" iOS="FontAwesome" Android="Fonts/FontAwesome.otf" WinPhone="Assets/Fonts/FontAwesome.otf#FontAwesome"> </OnPlatform> </Label.FontFamily> </Label> <Label Text="Segoe MDL2 Assets" /> <Label Text="     " FontSize="24"> <Label.FontFamily> <OnPlatform x:TypeArguments="x:String" iOS="Segoe MDL2 Assets" Android="Fonts/segmdl2.ttf" WinPhone="Segoe MDL2 Assets"> </OnPlatform> </Label.FontFamily> </Label>
※アイコンに対応する文字コードは下記を参照
Font Awesome Cheatsheet
Segoe MDL2 アイコンのガイドライン
これで各プラットフォームでアイコンフォントが表示できるようになりました。