我已经使用在子类中重写的必需方法子类化UITableView来填充表视图。但是,在调用NumberOfSections
时,不会调用NumberOfRowsInSection
。
以下代码来自Xamarin项目,但这与其等效的原生版本没有区别,方法名称略有不同。
partial class ShootsTable : UITableView, IUISearchResultsUpdating, IUISearchBarDelegate
{
public bool History { get; set; }
public UIViewController Parent { get; set; }
private Bootleg.API.Event[] Events { get; set; }
private List<nint> ExpandedSections { get; }
public ShootsTable (IntPtr handle) : base (handle)
{
ExpandedSections = new List<nint> ();
SetEvents();
}
private void SetEvents()
{
if (History) {
Events = AppDelegate.Api.GetShootHistory ().ToArray();
} else {
Events = AppDelegate.Api.MyEvents.ToArray();
}
}
private void AddRefreshControl()
{
var refreshControl = new UIRefreshControl ();
refreshControl.AttributedTitle = new NSAttributedString ("Pull to refresh");
refreshControl.AddTarget (async delegate(object sender, EventArgs e) {
await AppDelegate.Api.RefreshEvents();
SetEvents();
ReloadData();
refreshControl.EndRefreshing();
}, UIControlEvent.ValueChanged);
AddSubview (refreshControl);
}
private void AddSearchControl()
{
var searchControl = new UISearchController (Parent);
searchControl.SearchResultsUpdater = this;
searchControl.SearchBar.Delegate = this;
TableHeaderView = searchControl.SearchBar;
}
public void UpdateSearchResultsForSearchController (UISearchController searchController)
{
SetEvents ();
Events = Events.Where (e => e.name.Contains (searchController.SearchBar.Text)).ToArray ();
ReloadData ();
}
public override nint NumberOfSections ()
{
if (Events != null && Events.Length > 0)
{
SeparatorStyle = UITableViewCellSeparatorStyle.SingleLine;
return Events.Length;
}
var label = new UILabel (new CGRect (Bounds.X, Bounds.Y, Bounds.Size.Width, Bounds.Size.Height));
label.Text = History ? "You have not contributed to any shoots yet." : "No shoots available.";
label.Lines = 2;
label.TextAlignment = UITextAlignment.Center;
BackgroundView = label;
SeparatorStyle = UITableViewCellSeparatorStyle.None;
return 0;
}
public override nint NumberOfRowsInSection (nint section)
{
var e = Events[section];
if (e.group == null)
{
return 1;
}
return ExpandedSections.Contains (section) ? e.events.Count : 0;
}
[Export ("tableView:heightForHeaderInSection:")]
public System.nfloat GetHeightForHeader (UIKit.UITableView tableView, System.nint section)
{
return Events [section].group == null ? 0 : tableView.SectionHeaderHeight;
}
[Export ("tableView:viewForHeaderInSection:")]
public UIKit.UIView GetViewForHeader (UIKit.UITableView tableView, System.nint section)
{
var e = Events [section];
if (e.group == null)
{
return null;
}
var cell = (ShootGroupCell) tableView.DequeueReusableCell (ShootGroupCell.Key);
cell.Event = e;
cell.AddGestureRecognizer (new UITapGestureRecognizer(() => {
if (ExpandedSections.Contains(section))
{
ExpandedSections.Remove(section);
tableView.ReloadSections(new NSIndexSet((nuint) section), UITableViewRowAnimation.Automatic);
} else {
ExpandedSections.Add(section);
tableView.ReloadSections(new NSIndexSet((nuint) section), UITableViewRowAnimation.Automatic);
}
}));
return cell.ContentView;
}
public override UITableViewCell CellAt (NSIndexPath ns)
{
var e = Events[ns.Section];
e = e.group == null ? e : e.events[ns.Row];
if (History) {
var cell = (ShootCell)DequeueReusableCell (ShootCell.Key);
cell.Event = e;
cell.Parent = Parent;
return cell;
} else {
var cell = (ShootJoinCell) DequeueReusableCell (ShootJoinCell.Key);
cell.Event = e;
return cell;
}
}
[Export ("tableView:heightForRowAtIndexPath:")]
public System.nfloat GetHeightForRow (UIKit.UITableView tableView, Foundation.NSIndexPath indexPath)
{
return Events [indexPath.Section].group == null || ExpandedSections.Contains (indexPath.Section) ? tableView.RowHeight : 0;
}
[Export ("tableView:didSelectRowAtIndexPath:")]
public async void RowSelected (UIKit.UITableView tableView, Foundation.NSIndexPath indexPath)
{
if (!History)
{
var e = Events [indexPath.Section];
if (e.group != null) {
e = e.events [indexPath.Row];
}
MBHUDView.HudWithBody ("Connecting Event...", MBAlertViewHUDType.ActivityIndicator, 0, true);
await AppDelegate.Api.ConnectToEvent (e, false);
MBHUDView.DismissCurrentHUD ();
if (AppDelegate.Api.CurrentEvent.id != e.id)
{
var alert = UIAlertController.Create ("Confirm", "This event requires you to confirm you wish to join.", UIAlertControllerStyle.Alert);
alert.AddAction(UIAlertAction.Create("Join", UIAlertActionStyle.Default, async delegate {
MBHUDView.HudWithBody ("Connecting Event...", MBAlertViewHUDType.ActivityIndicator, 0, true);
await AppDelegate.Api.ConnectToEvent (e, true);
MBHUDView.DismissCurrentHUD ();
e = AppDelegate.Api.CurrentEvent;
DialogHelper.PermissionsDialog (e, delegate {
Parent.PerformSegue("phasesSegue", tableView);
}, null, Parent);
}));
alert.AddAction(UIAlertAction.Create("Cancel", UIAlertActionStyle.Cancel, null));
Parent.PresentViewController (alert, true, null);
}
else
{
e = AppDelegate.Api.CurrentEvent;
DialogHelper.PermissionsDialog (e, delegate {
Parent.PerformSegue("phasesSegue", tableView);
}, null, Parent);
}
}
}
现在我一直在寻找几种可能的解决方案,但是UITableView子类似乎很少见,而大多数解决方案都没有正确设置委托或数据源。我也看到了这个问题的SO解决方案,只是TableView不在视图中,因此不需要调用委托方法,但事实并非如此。
我不需要设置委托方法,因为我是UITableView本身的子类,只需覆盖内置方法就足够了。在故事板中,我将类设置为自定义类ShootsTable
。
有没有人有任何想法?
提前致谢。
答案 0 :(得分:0)
这似乎是一个错误。不知道它处于什么级别(Xamarin或iOS),但只要将其更改回IUITableViewDataSource实现就可以了。
我会向Xamarin报告,看看会有什么回复。