Weird blocks when adding Elements to MonoTouch Dialog RootElement after it is shown
-
13-11-2019 - |
Question
In an app I am building I use the following pattern: If the user clicks on a hierarchical navigation element I open the next UIViewController
immediately, and it takes care about loading its data itself and shows a loading spinner if it is going over the network.
Now most list views are created using MonoTouch
. On one DialogViewController
I have an issue with adding many element to the views RootElement after the screen has already been show.
At first the StringElements
appear fine on screen, but if you scroll quickly up and down the text on each line becomes a block:
Code to reproduce the issue:
var root = new RootElement("Root");
var dvc = new DialogViewController(root) { AutoHideSearch = true, EnableSearch = true };
nav.PushViewController(dvc, true);
Task.Factory.StartNew(() => {
Thread.Sleep(TimeSpan.FromSeconds(1));
UIApplication.SharedApplication.InvokeOnMainThread(() => {
var sec = new Section();
for (int i = 0; i < 100; i++)
{
var el = new StyledStringElement("Test", "Test", UITableViewCellStyle.Value1);
sec.Add(el);
}
root.Add(sec);
});
});
Interestingly only the string on the left looks like a block, while the one on the right is fine. On a side note, in their MWC (demo) app, Xamarin created a new RootElement to repopulate the twitter list as well.
Solution
There does not seem to be a reload of the data source called on the main thread to correctly render the new values:
var dvc = new DialogViewController(new RootElement(""));
_root = new UINavigationController();
_root.PushViewController(dvc, true);
_window.RootViewController = _root;
Task.Factory.StartNew(() => {
Thread.Sleep(TimeSpan.FromSeconds(1));
var section = new Section("");
foreach (var i in Enumerable.Range(1, 100)) {
section.Add(new StyledStringElement(i.ToString(), "cell", UITableViewCellStyle.Value1));
}
dvc.Root.Add(section);
BeginInvokeOnMainThread(() => {
dvc.ReloadData();
});
});
OTHER TIPS
I exactly have the same issue when I'm rendering dynamically the element in an BeginInvokeOnMainThread statement If I do load my elements in the constructor, the UI is blocked but the elements will render well.
and thanks for the tip dvc.ReloadData will work as well for me