Reputation: 11
I am using MonoTouch.Dialog to create a page in my Xamarin iOS app.
I am trying to create a multi-line RootElement by leveraging the GetCell method. This works fine on load, but if you click to a different tab and back the element shrinks back to default size (also when you click the element you see it shrink before the transition).
I have tried messing with UnevenRows with no success so far.
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;
}
}
Upvotes: 0
Views: 421
Reputation: 11
Found a workaround that seems to do the trick
Add this to the DialogViewController:
public override void ViewWillLayoutSubviews()
{
if (TableView != null && TableView.VisibleCells.Any())
{
foreach (var cell in TableView.VisibleCells)
{
cell.SizeToFit();
}
}
base.ViewWillLayoutSubviews();
}
UPDATED:
The above solution did not work with multiple elements, as the heights were not being calculated when the table was drawn.
A better solution was to use a custom UITableViewSource (inherit from the MonoTouch.Dialog.DialogViewController.SizingSource which is used by default has all the extra functionality).
Below is a basic implementation for clarity, but you probably won't want to be calling GetCell() every time GetHeight() is called in a production version.
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;
}
}
Upvotes: 1