UITableView子类一些被覆盖的方法没有被调用

本文关键字:方法 调用 覆盖 子类 UITableView | 更新日期: 2023-09-27 18:19:02

我已经创建了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

有人有什么想法吗?

UITableView子类一些被覆盖的方法没有被调用

这似乎是一个bug。不确定什么级别(Xamarin或iOS),但一旦这是改变回IUITableViewDataSource实现它的工作。

我将把这个报告给Xamarin,看看结果如何。