我正在尝试在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++;
}
我无法弄清楚为什么所有细胞都是空白的。一切似乎工作正常,因为我没有得到任何错误。任何帮助将不胜感激。
答案 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时,设计器中会进行单元格注册。
选择原型单元格,然后在属性选项卡中,使用您的单元格类名称更新类和标识符。
看起来像这样:
不相关,但这是我的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
}
希望这会有所帮助.-