简体   繁体   English

UITableView子类一些未调用的重写方法

[英]UITableView subclass some overridden methods not being called

I have subclassed UITableView with the required methods overridden in the subclass to populate the table view. 我将UITableView子类化,并在子类中重写了必需的方法以填充表视图。 However while NumberOfSections is called, NumberOfRowsInSection is not called. 但是同时NumberOfSections叫, NumberOfRowsInSection不叫。

The code below is from a Xamarin project but this is no different to its equivalent native version with slight differences in method names. 下面的代码来自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);
            }
        }
    }

Now I have been looking at several possible solutions however it seems quite uncommon to sub-class UITableView with the majority of solutions simply being not setting the delegate or data source properly. 现在,我一直在研究几种可能的解决方案,但是子类UITableView似乎很不常见,因为大多数解决方案只是未正确设置委托或数据源。 I have also seen a SO solution to this issue simply being the TableView not being in view and therefore the delegate methods do not need to be called however this is not the case. 我还看到了针对此问题的SO解决方案,只是不使用TableView,因此不需要调用委托方法,但是事实并非如此。

I do not need to set delegate methods as I am subclassing UITableView itself and it is sufficient to just override the built in methods. 我不需要设置委托方法,因为我继承了UITableView本身,并且只需覆盖内置方法就足够了。 In the storyboard I set the class to my custom class ShootsTable . 在情节ShootsTable将类设置为自定义类ShootsTable

Does anyone have any ideas? 有人有什么想法吗?

Thanks in advance. 提前致谢。

This appears to be a bug. 这似乎是一个错误。 Not sure what level (Xamarin or iOS) it is at but as soon as this is changed back to a IUITableViewDataSource implementation it works. 不确定它处于什么级别(Xamarin或iOS),但是一旦将其更改回IUITableViewDataSource实现,它就会起作用。

I will report this to Xamarin and see what comes back. 我将报告给Xamarin,看看会回来什么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM