Возможно, проблема в том, что ViewDidLoad
вызывается до того, как вы получите countryNames
от своего веб-сервиса. GetCountries
- это асинхронный метод, поэтому он возвращает Task
сразу, а конструктор завершает работу и сразу же возвращается, поэтому ОС теперь может свободно вызывать ViewDidLoad
, что и делает ... но вы все еще ожидаетевеб-запрос приводит к тому, что countryNames
остается пустым списком при вызове CountriesTableView.Source = new StartViewController.TableSource(countryNames, this);
, поэтому поле countries
также является пустым списком, и именно здесь вы получаете данные для отображения в списке. Поэтому вам нужно обновить ваш источник, когда GetCountries
завершится ... но у вас нет способа сделать это, так как вы не ожидаете вызова на GetCountries
.
namespace Test
{
public partial class StartViewController : UIViewController
{
// No need for this here, since your TableSource will be holding
// and providing your data
//private List<String> countryNames;
//private List<String> countryLanguages;
public StartViewController() : base("StartViewController", null)
{
// Best Practice not to call async methods from a constructor
// A constructor should be fast and return, after running all
// of its code, right away.
//GetCountries();
}
public override async void ViewDidLoad()
{
base.ViewDidLoad();
// Perform any additional setup after loading the view, typically from a nib.
// Get your data and then set your source
var countries = await RefreshDataAsync();
var countryNames = new List<string>();
foreach (var c in countries)
{
countryNames.Add(c.name);
}
// since you awaited the above, countryNames is now populated
// before you set up your TableSource.
CountriesTableView.Source = new StartViewController.TableSource(countryNames, this);
// On a side note, by passing and holding onto a reference to
// this UIViewController, you are creating a circular reference
// which will cause a memory leak. You should not need a reference
// to this view controller from your TableSource.
}
...
}
...
}
Вот и, глядя на ваш код TableSource
, вы не заполняете свою ячейку какими-либо данными. Вы получаете и возвращаете ячейку, но вы не установили никаких элементов управления пользовательского интерфейса, таких как UILabel
s, текстовые (или любые другие) значения для отображения ваших данных. Также вам нужно сообщить UITableView
, сколько элементов вы должны отобразить, возвращая количество элементов из метода RowsInSection
. На самом деле вы говорите UITableView
, что у вас есть только один предмет. Вам нужно сделать что-то вроде:
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
UITableViewCell cell;
// try to get a reusable cell
cell = tableView.DequeueReusableCell("countries");
if (cell == null)
{
cell = new UITableViewCell( UITableViewCellStyle.Subtitle, "countries");
}
// Get data for row
string countryName = countries[indexPath.Row];
// Display data in the cell
cell.TextLabel.Text = countryName;
return cell;
}
public override nint RowsInSection(UITableView tableview, nint section)
{
// return the number of items you need to display
return countries.Count;
}
Если бы я был на вашем месте, у вас было бы TableSource
поле List<CountryInfo>
вместо List<string>
. Таким образом, ваш TableSource
может предоставить любые данные о стране, которые UITableView
может потребовать для отображения.