LoginSignup
4
4

More than 5 years have passed since last update.

Xamarin.Forms MasterDetailPage の Master の幅を可変にする (iOS 編)

Posted at

MasterDetailPage で表示される Master の幅はサイズが固定になっています。
これを UI 側から変更できるような仕組みが欲しいと思い、MasterDetailPage の拡張クラスを作成しました。

完成イメージはこちら
Simulator Screen Shot 2016.07.16 12.15.48.png

Simulator Screen Shot 2016.07.16 12.16.04.png

MasterDetail クラスを拡張

標準で幅を変更するためのプロパティが提供されていないため、MasterDetailPage クラスを継承し、プロパティを追加します。

public static readonly BindableProperty MasterFractionProperty =
    BindableProperty.Create(
        propertyName: nameof(MasterFraction),
        returnType: typeof(double),
        declaringType: typeof(VariableMasterDetailPage),
        defaultValue: 0.0,
        defaultBindingMode: BindingMode.TwoWay,
        propertyChanged: OnMasterFractionChanged);

public double MasterFraction
{
    get { return (double)GetValue(MasterFractionProperty); }
    set { SetValue(MasterFractionProperty, value); }
}

protected static void OnMasterFractionChanged(BindableObject bindable, object oldValue, object newValue)
{
    var page = (VariableMasterDetailPage)bindable;

    var newFraction = (double)newValue;
    if (newFraction < page.MinimumFraction || page.MaximumFraction < newFraction)
        throw new ArgumentOutOfRangeException();

    var oldFraction = (double)oldValue;
    if (oldFraction.Equals(newFraction) == false)
    {
        page.MasterFraction = newFraction;
        page.OnPropertyChanged(nameof(page.MasterFraction));
    }
}

CustomRenderer

TabletMasterDetailRenderer を継承した CustomRenderer を iOS のプロジェクトに追加します。MaximumPrimaryColumnWidth を変更しておくのがポイント。

using System;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using UIKit;
using VariableMaster;
using VariableMaster.Controls;
using VariableMaster.iOS;

[assembly: ExportRenderer(typeof(VariableMasterDetailPage), typeof(VarriableMasterDetailPageRenderer))]

namespace VariableMaster.iOS
{
    public class VarriableMasterDetailPageRenderer : TabletMasterDetailRenderer
    {
        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            var page = e.NewElement as VariableMasterDetailPage;
            if (page != null)
            {
                page.PropertyChanged += (sender, args) =>
                {
                    if (args.PropertyName == "MasterFraction")
                    {
                        MaximumPrimaryColumnWidth = (nfloat)(page.Width * page.MasterFraction / 100);
                        PreferredPrimaryColumnWidthFraction = (nfloat)page.MasterFraction / 100;
                    }
                };
            }

            base.OnElementChanged(e);
        }
    }
}

全体のソースコードはこちらのリポジトリを参照してください。おかしなところがあれば PR よろしくお願いします。
https://github.com/smallgeek/VariableMaster

4
4
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
4
4