C# Xamarin表单iOS自定义UITableViewCell动态高度
我正在尝试为Xamarin表单创建自定义UITableViewCell,它将根据包含的文本自动调整其高度 我已经找到了通过Designer制作的解决方案,但我需要在代码中这样做 这是我在分析Designer解决方案后得到的结果,但它不起作用:C# Xamarin表单iOS自定义UITableViewCell动态高度,c#,ios,xamarin.forms,C#,Ios,Xamarin.forms,我正在尝试为Xamarin表单创建自定义UITableViewCell,它将根据包含的文本自动调整其高度 我已经找到了通过Designer制作的解决方案,但我需要在代码中这样做 这是我在分析Designer解决方案后得到的结果,但它不起作用: public class FormLabelCellView : UITableViewCell, INativeElementView { public UILabel Label { get; private set; } public
public class FormLabelCellView : UITableViewCell, INativeElementView
{
public UILabel Label { get; private set; }
public FormLabelCell Cell { get; set; }
public Element Element => Cell;
public FormLabelCellView(FormLabelCell cell) : base(UITableViewCellStyle.Default, cell.GetType().FullName)
{
Cell = cell;
// in the custom ContentView solution I can't set the cell to expand and contract according to the text it contains
Label = new UILabel();
Label.TranslatesAutoresizingMaskIntoConstraints = false;
Label.SetContentCompressionResistancePriority(751, UILayoutConstraintAxis.Vertical);
Label.SetContentHuggingPriority(251, UILayoutConstraintAxis.Vertical);
this.ContentView.AddSubview(Label);
this.ContentView.AddConstraint(NSLayoutConstraint.Create(Label, NSLayoutAttribute.Left, NSLayoutRelation.Equal, this.ContentView, NSLayoutAttribute.Left, 1, 0));
this.ContentView.AddConstraint(NSLayoutConstraint.Create(Label, NSLayoutAttribute.Right, NSLayoutRelation.Equal, this.ContentView, NSLayoutAttribute.Right, 1, 0));
this.ContentView.AddConstraint(NSLayoutConstraint.Create(Label, NSLayoutAttribute.Top, NSLayoutRelation.Equal, this.ContentView, NSLayoutAttribute.Top, 1, 0));
this.ContentView.AddConstraint(NSLayoutConstraint.Create(Label, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, this.ContentView, NSLayoutAttribute.Bottom, 1, 0));
}
}
这是结果(行高可能是默认的行高44):
在任何人询问赛艇高度和估计高度之前。是,我已设置行高=UITableView.AutomaticDimension和估计值为24在我的自定义ListViewRenderer中
当我将自定义UITableViewCell修改为以下内容时,我还可以验证它是否有效:
public class FormLabelCellView : UITableViewCell, INativeElementView
{
public UILabel Label { get; private set; }
public FormLabelCell Cell { get; set; }
public Element Element => Cell;
public FormLabelCellView(FormLabelCell cell) : base(UITableViewCellStyle.Default, cell.GetType().FullName)
{
Cell = cell;
// this solution works, but I can't remove the margins / padding and set background color
Label = this.TextLabel;
}
}
结果如下所示:
我认为我没有正确地创建约束。有人能帮我吗
编辑:在尝试为测试目的创建自定义UITableViewSource后,我发现问题出在ListViewDataSource和ListViewDataSource的Xamarin实现中。这是不幸的,因为这些类是内部类,所以我无法扩展它们并重写GetHeightForRow函数。在我的测试中,如果我设置
RowHeight=UITableView.AutomaticDimension代码>和<代码>估计值为24代码>在listViewRenderer中,我将获得与您显示的相同的效果:TableView的行高似乎相等
但当我尝试使用另一种方法时:在tableView的源代码中使用override方法,如:
public override nfloat GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
{
return UITableView.AutomaticDimension;
}
public override nfloat EstimatedHeight(UITableView tableView, NSIndexPath indexPath)
{
return 24;
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
MyListViewCell cell = tableView.DequeueReusableCell("Cell") as MyListViewCell;
if (cell == null)
{
cell = new MyListViewCell(new NSString("Cell"));
}
//Update your data
return Cell;
}
它工作正常(单元格将在运行时自动调整其行高)
此外,我真的建议您使用此方法来构建单元格:
public MyListViewCell(NSString cellId) : base(UITableViewCellStyle.Default, cellId)
{
//add your controls in the cell's ContentView
}
然后我们可以在源代码中使用它,如:
public override nfloat GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
{
return UITableView.AutomaticDimension;
}
public override nfloat EstimatedHeight(UITableView tableView, NSIndexPath indexPath)
{
return 24;
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
MyListViewCell cell = tableView.DequeueReusableCell("Cell") as MyListViewCell;
if (cell == null)
{
cell = new MyListViewCell(new NSString("Cell"));
}
//Update your data
return Cell;
}
当我调用cell.SetUpCell()
时,我在上面演示的构造函数内部实例化的participantnamelab
上得到一个空引用
public MyListViewCell(NSString cellId) : base(UITableViewCellStyle.Default, cellId)
{
//add your controls in the cell's ContentView
}
如果我把实例化放在下面的构造函数中,我就不会得到这个空引用
public PeopleCell(IntPtr handle) : base(handle)
{
}
我遗漏了什么?因此,请回答我自己的问题。问题在于Xamarin实现内部类ListViewDataSource和ListViewDataSource。因为我们不能扩展这些类,所以ListView中的动态行高有两种可能的解决方案
创建自己的UITableViewSource实现
使用ViewCell创建自定义单元格
我使用了第二个选项,因为我正在做多平台应用程序,我不想创建复杂的UITableViewSource实现
这是自定义ViewCell的示例实现:
public class CustomLabelCell : ViewCell
{
private Label label;
public static readonly BindableProperty TextProperty = BindableProperty.Create("Text", typeof(string), typeof(CustomLabelCell), null);
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
// disable public set on View property
public new View View
{
get { return base.View; }
private set { base.View = value; }
}
public CustomLabelCell()
{
this.label = new Label()
{
Text = this.Text
};
ContentView frame = new ContentView()
{
Padding = new Thickness(4.0),
Content = label
};
this.View = frame;
}
protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
base.OnPropertyChanged(propertyName);
if (propertyName == TextProperty.PropertyName)
{
this.label.Text = this.Text;
ForceUpdateSize();
}
}
}
下面是在ListView中使用它的方式:
ListView listView = new ListView(ListViewCachingStrategy.RecycleElement)
{
HasUnevenRows = true,
ItemsSource = new ObservableCollection<TestObj> { new TestObj("one - example text that will reach s e c o n d row"), new TestObj("two"), new TestObj("three - longer example text with more words for third row that will span across three rows"), new TestObj("four"), new TestObj("five") },
ItemTemplate = new DataTemplate(typeof(CustomLabelCell))
};
listView.ItemTemplate.SetBinding(CustomLabelCell.TextProperty, "Name");
正如您所见,没有必要在特定于平台的代码中创建自定义渲染器和自定义单元格。可能是VisualStudio或symulator的问题。我对iOS上的自定义渲染器有问题。直到我重新启动VS和模拟器,它才开始工作。不幸的是,没有。我为此挣扎了很长一段时间。我尝试了很多东西,但没有任何东西能给我想要的结果。我想我一定是做错了什么,但我不知道是什么。我没有提到这一点,但我没有使用自定义UITableViewSource。我使用的是xamarin在ListView中填充ItemsSource属性时创建的默认数据源。我只想扩展默认的ListView,而不是重新创建已经存在的所有功能。但我尝试了你的建议,创建了非常基本的自定义UITableViewSource,它很管用。另外,我也不必重写GetHeightForRow并估计其正确工作的高度。也许您应该发布PeopleCell类的实现,这样我们就可以看到问题所在。我放弃了创建自定义UITableViewCell和自定义UITableViewSource的方法,而是使用ViewCell创建自定义单元格。