0
votes

I saw this example:

Xamarin Forms - How to create custom render to give TableSection the default iOS Footer?

It does 75% of what I am looking for with this code:

using CoreGraphics;
using Foundation;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(TableView), typeof(Japanese.iOS.TableViewCustomRenderer))]
namespace Japanese.iOS
{
    public class TableViewCustomRenderer : TableViewRenderer
    {
        UITableView tableView;

        protected override void OnElementChanged(ElementChangedEventArgs<TableView> e)
        {
            base.OnElementChanged(e);
            if (Control == null)
                return;

            var tableView = Control as UITableView;
            var formsTableView = Element as TableView;
            tableView.WeakDelegate = new CustomFooterTableViewModelRenderer(formsTableView);
        }


        void Current_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {

        }

        private class CustomFooterTableViewModelRenderer : TableViewModelRenderer
        {
            public CustomFooterTableViewModelRenderer(TableView model) : base(model)
            {
            }

            public override nfloat GetHeightForFooter(UITableView tableView, nint section)
            {
                return 10;
            }

            public override string TitleForFooter(UITableView tableView, nint section)
            {
                return "This is the title for this given section";
            }

        }

    }
}

1. However what I would like is to be able to extend TableView so that I am able to put in the XAML some way to set or leave unset the footer text and height. Something like:

<ExtTableView FooterText="abc" FooterHeight="50". ..

2. From experiments with the code above I tried hardcoding in some text and realize that there is no spacing set. So I would also like to find out if there is a way to set the spacing and font so it appears just like in the iOS settings pages?

Could someone suggest how I could go about creating what I am looking for which is I guess something like an ExtTableView class that can accept additional arguments.

2
So you know how to change the footer height but just want to be able to pass the value in XAML code?Jordy Dieltjens
Yes I am not sure how I could do that in this situation.Alan2

2 Answers

2
votes

As hankide said , I just provide more details.

  1. However what I would like is to be able to extend TableView so that I am able to put in the XAML some way to set or leave unset the footer text and height.

Create MyTableView that inherits from TableView

public class MyTableView : TableView
{
    public static readonly BindableProperty FooterHeightProperty =
         BindableProperty.Create("FooterHeight", typeof(string), typeof(MyTableView), "");

    public string FooterHeight
    {
        get { return (string)GetValue(FooterHeightProperty); }
        set { SetValue(FooterHeightProperty, value); }
    }

    public static readonly BindableProperty FooterTextProperty =
        BindableProperty.Create("FooterText", typeof(string), typeof(MyTableView), "");

    public string FooterText
    {
        get { return (string)GetValue(FooterTextProperty); }
        set { SetValue(FooterTextProperty, value); }
    }
}

Get the value that you set in XMAL and assign them to CustomFooterTableViewModelRenderer

protected override void OnElementChanged(ElementChangedEventArgs<TableView> e)
    {
        base.OnElementChanged(e);
        if (Control == null)
            return;

        var tableView = Control as UITableView;
        var formsTableView = Element as MyTableView;

        CustomFooterTableViewModelRenderer render = new CustomFooterTableViewModelRenderer(formsTableView);
        render.height = float.Parse(formsTableView.FooterHeight);
        render.text = formsTableView.FooterText;
        tableView.WeakDelegate = render;
    }

    private class CustomFooterTableViewModelRenderer : TableViewModelRenderer
    {
        public float height { get; set; }
        public String text { get; set; }


        public CustomFooterTableViewModelRenderer(TableView model) : base(model)
        {
        }

        public override UIView GetViewForFooter(UITableView tableView, nint section)
        {

            UIView view = new UIView(new CGRect(0, 0, tableView.Frame.Width, 50));
            view.BackgroundColor = UIColor.Gray;

            UILabel label = new UILabel();
            label.Frame = new CGRect(0, 0, tableView.Frame.Width, height);
            label.BackgroundColor = UIColor.Red;
            label.Text = text;
            label.Font = UIFont.SystemFontOfSize(15);

            view.Add(label);
            return view;
        }

        public override nfloat GetHeightForFooter(UITableView tableView, nint section)
        {
            return 50;
        }
    }

Usage:

    <local:MyTableView FooterHeight="20" FooterText="ABC">
        <TableRoot>
            <TableSection>
                <TextCell Text="22222" ></TextCell>
            </TableSection>
        </TableRoot>
    </local:MyTableView>

From experiments with the code above I tried hardcoding in some text and realize that there is no spacing set. So I would also like to find out if there is a way to set the spacing and font so it appears just like in the iOS settings pages?

You could override the method GetViewForFooter to change the defalut style of footer,find it in the code above .

My test :

enter image description here

2
votes

You had the right idea about creating the custom control. Here's what to do:

  1. Create ExtTableView class that inherits from TableView

    public class ExtTableView : TableView { }
    
  2. Create BindableProperties for both FooterText and FooterHeight, as outlined here.

  3. After that you can set the properties in XAML

    <ExtTableView FooterText="abc" FooterHeight="50" ...
    
  4. Within the renderer, you can get the values from Element (which points to our Xamarin.Forms ExtTableView).

    // Modify the native control with these values
    var text = Element.FooterText;
    var height = Element.FooterHeight;