10
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Xamarin.Forms の Label から iOS の UILabel を取り出す

Last updated at Posted at 2014-06-12

Xamarin.Forms でどうにかしたい iOS と Android の違い の「文字の自動縮小」の自己回答。

Xamarin.Forms で定義した Label は、iOS では UILabel となるはずなので、その過程のどこかでフックできれば UILabel.AdjustsFontSizeToFitWidth が仕込める、と目論んで、ホントにできたのでメモ。

要点

Forms→ネイティブのフックは PageRenderer でできる。その中で得られる UIView(のサブクラス)は、Label と UILabel の両方の参照を持っているので、あとは使うだけ。

ページでなく、UIパーツレベルでフックできたので、全面的に書き換えた。

やってみる

参考にしたのは https://github.com/xamarin/xamarin-forms-samples/tree/master/Forms2Native

このサンプルをちょっと改造して試した。

まずは Forms側の MySecondPage.cs を修正。

MySecondPage.cs
public class MySecondPage : ContentPage
{
    public Label MyLabel { get; private set; }

	public MySecondPage ()
	{
        this.MyLabel = new Label
        {
            Text = "Too loooooooooooooooooooooooong label",
            Font = Font.SystemFontOfSize(30d),
            LineBreakMode = LineBreakMode.NoWrap
        };

        Content = new StackLayout
        {
            Orientation = StackOrientation.Vertical,
            VerticalOptions = LayoutOptions.CenterAndExpand,
            Children = 
            {
                this.MyLabel
            }
        };
	}
}

ラベルを配置。とても文字が長いので全部は表示しきれない。

次に iOS側に MyLabelRenderer.cs を作成。

MyLabelRenderer.cs
using System;
using Xamarin.Forms;
using Forms2Native;
using Xamarin.Forms.Platform.iOS;
using MonoTouch.UIKit;

[assembly:ExportRenderer(typeof(Label), typeof(MyLabelRenderer))]

namespace Forms2Native
{
    public class MyLabelRenderer : LabelRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
        {
            base.OnElementChanged(e);
            this.Control.AdjustsFontSizeToFitWidth = true;
        }
    }
}

ExportRenderer で「FormsのLabelは、MyLabelRendererを使う」と定義している。
するとすべての Label の生成時を OnElementChanged でフックでき、ControlUILabel は取り出せるので、あとはご自由に、という感じ。

この実装だと、すべての Label に Ajusts が適用されてしまう。個別に行いたい場合は、Forms側に Labelから派生した AjustableLabel を作成して使い、ExportRenderer(typeof(Label),… のところを ExportRenderer(typeof(AjustableLabel),… にすればいけるはず。そしてこの方法はカスタムビューを作る手順に通じる(というかそのもの?)はず。

ちなみにこの OnElementChanged は、Nuget の Xamarin.Formsパッケージの Ver1.1.0.6201から利用できる。

実行する

こんな感じで、ちゃんと文字サイズが縮小されました。

Android の方も同じ要領でいけるは…ず。

10
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?