在Xamarin.IOS中多次使用带有原型单元格的TableViewController

时间:2017-06-27 22:23:28

标签: c# uitableview xamarin xamarin.ios

我正在尝试在Xamarin IOS中创建一个tabview,用户可以通过按下按钮添加新标签。我希望所有选项卡都是从我在故事板中创建的单个tableview控制器创建的,其上有几个原型单元。当我尝试使用视图控制器创建选项卡时,它会加载正确数量的单元格,但所有单元格都是空白的。我也没有遇到任何错误。

以下是我的原型单元格的代码:

using Foundation;
using System;
using UIKit;

namespace NewEPA
{
    public partial class ACUnitCell : UITableViewCell
    {
        public static readonly NSString Key = new NSString("AC");
        public static readonly UINib Nib;
        static ACUnitCell()
        {
            Nib = UINib.FromName("AC", NSBundle.MainBundle);

        }
        public ACUnitCell (IntPtr handle) : base (handle)
        {
        }

        public ACUnitCell(string cellId) : base(UITableViewCellStyle.Default, cellId)
        {

        }
    }
}

以下是tableview控制器的代码:

using Foundation;
using System;
using UIKit;
using System.Linq;
using System.Collections.Generic;

namespace NewEPA
{
    public partial class OptionConfigurationTableController : UITableViewController
    {

        static NSString ACCellId = new NSString("AC");
        public OptionConfigurationTableController (IntPtr handle) : base (handle)
        {
        }
        public OptionConfigurationTableController()
        {
            TableView.RegisterClassForCellReuse(typeof(ACUnitCell), ACCellId);
        }


        private OptionSource dataSource;
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();
            ProjectObject currentProject = new ProjectObject();



            dataSource = new OptionSource(currentProject);



            TableView.Source = dataSource;
            TableView.ReloadData();

        }




    }





    public class OptionSource : UITableViewSource
    {


        private const int AC_UNITS = 0, DUCT_WORK = 1, INSULATION = 2, THERMOSTAT = 3, ZONES = 4, ROOF = 5, ADDITIONAL_OPTIONS = 6;
        protected string cellIdentifier = "";
        static NSString ACCellId = new NSString("AC");
        protected string[] SectionNames = new string[] { "AC Units", "Duct Work", "Insulation", "Thermostat", "Zones", "Roof", "Additional Options"};

        public OptionSource(ProjectObject currentOption)
        {

        }


        public override nint NumberOfSections(UITableView tableView)
        {
            return 7;
        }

        public override nint RowsInSection(UITableView tableview, nint section)
        {
            //include switch statement to figure out which section has however many rows. set to 4 for testing
            return 4;
        }


        public override string TitleForHeader(UITableView tableView, nint section)
        {
            return SectionNames[section];
        }

        public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
        {
            switch(indexPath.Section)
            {
                case AC_UNITS:
                    cellIdentifier = "AC";
                    ACUnitCell cell0 = tableView.DequeueReusableCell(ACCellId) as ACUnitCell;
                    if (cell0 == null)
                        cell0 = new ACUnitCell(ACCellId);
                    //code to populate cell
                    return cell0;
                case DUCT_WORK:
                    cellIdentifier = "DuctWork";
                    DuctCell cell1 = tableView.DequeueReusableCell(cellIdentifier) as DuctCell;
                    if (cell1 == null)
                        cell1 = new DuctCell(cellIdentifier);
                    //code to populate cell
                    return cell1;
                case INSULATION:
                    cellIdentifier = "InsulationWork";
                    InsulationCell cell2 = tableView.DequeueReusableCell(cellIdentifier) as InsulationCell;
                    if (cell2 == null)
                        cell2 = new InsulationCell(cellIdentifier);
                    //code to populate cell
                    return cell2;
                case THERMOSTAT:
                    cellIdentifier = "ThermostatWork";
                    ThermostatCell cell3 = tableView.DequeueReusableCell(cellIdentifier) as ThermostatCell;
                    if (cell3 == null)
                        cell3 = new ThermostatCell(cellIdentifier);
                    //code to populate cell
                    return cell3;
                case ZONES:
                    cellIdentifier = "ZoneWork";
                    ZoneCell cell4 = tableView.DequeueReusableCell(cellIdentifier) as ZoneCell;
                    if (cell4 == null)
                        cell4 = new ZoneCell(cellIdentifier);
                    //code to populate cell
                    return cell4;
                case ROOF:
                    cellIdentifier = "RoofWork";
                    RoofCell cell5 = tableView.DequeueReusableCell(cellIdentifier) as RoofCell;
                    if (cell5 == null)
                        cell5 = new RoofCell(cellIdentifier);
                    //code to populate cell
                    return cell5;
                case ADDITIONAL_OPTIONS:
                    cellIdentifier = "OtherOptionWork";
                    OtherOptionCell cell6 = tableView.DequeueReusableCell(cellIdentifier) as OtherOptionCell;
                    if (cell6 == null)
                        cell6 = new OtherOptionCell(cellIdentifier);
                    //code to populate cell
                    return cell6;

                    //i addeed in this default case so all paths would return a cell, but if the code here executes it's gonn eff stuff up
                    //it should never execute though...
                default:
                    cellIdentifier = "OtherOptionWork";
                    OtherOptionCell cell7 = tableView.DequeueReusableCell(cellIdentifier) as OtherOptionCell;
                    if (cell7 == null)
                        cell7 = new OtherOptionCell(cellIdentifier);
                    //code to populate cell
                    return cell7;
            }
        }

        public override nfloat GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
        {
            return 80;
        }

    }

最后,这是我在tabcontroller中用来创建第一个标签的代码:

namespace NewEPA
{
    public partial class OptionTabController : UITabBarController
    {
        OptionConfigurationTableController tab1;
        //tracks how many options are being used. starts out with one option by default
        int count = 1;
        //option limit sets limit on how many options can be created. default 5
        const int optionLimit = 5;

        public OptionTabController (IntPtr handle) : base (handle)
        {

            //creates single option tab
            tab1 = new OptionConfigurationTableController()
            {
                Title = "Option " + count
            };
            var tabs = new OptionConfigurationTableController[] {tab1};

            ViewControllers = tabs;

            count++;

        }

我无法弄清楚为什么所有细胞都是空白的。一切似乎工作正常,因为我没有得到任何错误。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

我真的不了解Tabs的部分,但修复空单元格只需删除这一行:

TableView.RegisterClassForCellReuse(typeof(ACUnitCell), ACCellId);

当您使用Prototypes单元格时,如果在Storyboard中的Prototype单元格中设置ReuseIdentifier,则不需要它。

一些事情:

由于您使用的是UITableViewController,因此您无需定义单独的UITableViewSource,只需在OptionConfigurationTableController类中覆盖相同的方法。

如果您NumberOfSections返回SectionNames.Length,则TitleForHeader会更安全,因此您的IndexOutOfRangeException方法无法到达static NSString ACCellId = new NSString("AC"); ..... ..... tableView.DequeueReusableCell(ACCellId) as ACUnitCell;

要使单元格出列,您可以使用单元格中的静态密钥

改变这个:

tableView.DequeueReusableCell(ACUnitCell.Key, indexPath) as ACUnitCell;

为此:

public partial class LeTableViewCell : UITableViewCell
{
    public static readonly NSString Key = new NSString("LeTableViewCell");
    public static readonly UINib Nib;

    static LeTableViewCell()
    {
        Nib = UINib.FromName("LeTableViewCell", NSBundle.MainBundle);
    }

    protected LeTableViewCell(IntPtr handle) : base(handle)
    {
        // Note: this .ctor should not contain any initialization logic.
    }
}

另请注意我使用indexPath的方法重载。

<强>更新

在StoryBoard中使用Prototypes Cells时,设计器中会进行单元格注册。

选择原型单元格,然后在属性选项卡中,使用您的单元格类名称更新标识符

看起来像这样:

enter image description here

不相关,但这是我的CustomCell的代码:

func DownloadFromS3() ([]byte, error) {
 retries := 5
 awsSession = session.Must(session.NewSessionWithOptions(session.Options{
    SharedConfigState: session.SharedConfigEnable,
    Config: aws.Config{
        MaxRetries: &retries,
        LogLevel: aws.LogLevel(aws.LogDebugWithHTTPBody),
    },
    }))

    // Create S3 service client
    serviceS3 = s3.New(awsSession)
    d := s3manager.NewDownloaderWithClient(serviceS3,func(d *s3manager.Downloader) {
        d.Concurrency = 10 // should be ignored
        d.PartSize = 1     // should be ignored
    })
    w := &aws.WriteAtBuffer{}
    n, err := d.Download(w, &s3.GetObjectInput{
        Bucket: aws.String("mybucket"),
        Key:    aws.String("key1"),
        Range:  aws.String("bytes=0-9"),
    })
    if err != nil {
        return nil, err
    }
    return w.Bytes(), err
}

希望这会有所帮助.-