Monotouch 对话框 - 多行 RootElement

Monotouch Dialog - Multi line RootElement

我正在使用 MonoTouch.Dialog 在我的 Xamarin iOS 应用程序中创建一个页面。

我正在尝试利用 GetCell 方法创建多行 RootElement。这在加载时工作正常,但如果您单击不同的选项卡并返回,该元素会收缩回默认大小(同样当您单击该元素时,您会看到它在过渡之前收缩)。

到目前为止,我尝试过使用 UnevenRows 但没有成功。

public partial class TestController : UITabBarController
{
    public TestController()
        : base("TestController", null)
    {
    }

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();

        var navController = new UINavigationController
        {
            Title = "Test1"
        };
        navController.PushViewController(new TestDialogViewController(), false);

        ViewControllers = new[]
        {
            navController, 
            new UIViewController
            {
                Title = "Test2"
            },
        };
    }
}

public class TestDialogViewController : DialogViewController
{
    public TestDialogViewController() : base(new RootElement("Test"))
    {
        Root.UnevenRows = true; // has no effect

        var testSection = new Section("Test section");
        var testChildRootElement = new CustomRootElement("Multi\nLine\nElement")
        {
            UnevenRows = true // has no effect
        };

        var testChildSection = new Section("Test child section");
        var testEntryElement = new EntryElement(string.Empty, string.Empty, "Test entry element");

        testChildSection.Add(testEntryElement);
        testChildRootElement.Add(testChildSection);
        testSection.Add(testChildRootElement);

        Root.Add(testSection);
    }
}

public class CustomRootElement : RootElement
{
    public CustomRootElement(string caption) : base(caption) {}

    public override UITableViewCell GetCell(UITableView tv)
    {
        var cell = base.GetCell(tv);

        // Setup Multi-line Element
        cell.TextLabel.LineBreakMode = UILineBreakMode.WordWrap;
        cell.TextLabel.Lines = 0;
        return cell;
    }
}

找到似乎可以解决问题的解决方法

将此添加到 DialogViewController:

public override void ViewWillLayoutSubviews()
    {
        if (TableView != null && TableView.VisibleCells.Any())
        {
            foreach (var cell in TableView.VisibleCells)
            {
                cell.SizeToFit();
            }
        }
        base.ViewWillLayoutSubviews();
    }

更新:

上述解决方案不适用于多个元素,因为绘制 table 时未计算高度。

更好的解决方案是使用自定义 UITableViewSource(继承自 MonoTouch.Dialog.DialogViewController.SizingSource 默认情况下使用的具有所有额外功能) .

为清楚起见,下面是一个基本实现,但您可能不希望每次在生产版本中调用 GetHeight() 时都调用 GetCell()。

public partial class TestController : UITabBarController
{
    public TestController() : base("TestController", null) {}

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();

        var navController = new UINavigationController();
        navController.PushViewController(new TestDialogViewController(), false);
        navController.TopViewController.Title = "Tab 1";

        ViewControllers = new[]
        {
            navController, 
            new UIViewController { Title = "Test2" }
        };
    }
}

public class TestDialogViewController : DialogViewController
{
    public TestDialogViewController() : base(new RootElement("Test"))
    {
        Root.Add(new Section("Test section")
        {
            new CustomRootElement("Multi\nLine\nElement")
            {
                new Section("Test child section")
                {
                    new EntryElement("Test element", string.Empty, "value")
                },
            },
            new EntryElement("Test element", string.Empty, "value")
        });
    }

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();
        TableView.Source = new CustomTableViewSource(this);
    }

}

public class CustomTableViewSource : DialogViewController.SizingSource
{
    public CustomTableViewSource(DialogViewController controller) : base(controller) {}

    public override float GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
    {
        // Recommend storing these values, as is appropriate for your usage
        var cell = GetCell(tableView, indexPath);
        cell.SizeToFit();
        return cell.Frame.Height;
    }
}


public class CustomRootElement : RootElement
{
    public CustomRootElement(string caption) : base(caption) {}

    public override UITableViewCell GetCell(UITableView tv)
    {
        var cell = base.GetCell(tv);

        // Setup Multi-line Element
        cell.TextLabel.LineBreakMode = UILineBreakMode.WordWrap;
        cell.TextLabel.Lines = 0;

        return cell;
    }
}