如何为具有与内置单元格相同的布局指标的“UITableView”提供自定义“UITableCell”?
Posted
技术标签:
【中文标题】如何为具有与内置单元格相同的布局指标的“UITableView”提供自定义“UITableCell”?【英文标题】:How can I supply a custom `UITableCell` to an `UITableView` with the same layout metrics that a built-in cell would have? 【发布时间】:2018-05-30 10:40:43 【问题描述】:当我向原型表格单元格添加子视图时,假设是UITextView
,则默认情况下没有左边距。
我希望它使用与 ios 内部用于内置标准单元格布局的相同边距。
万一我错过了明显的,“使用设备/iOS默认值”标志在哪里?否则,我首选的解决方案是查询设备的设备相关和 iOS 版本相关的 UI 指标。对于这个问题,我们可以将其限制为仅UITableView
控件及其UITableCell
后代的指标。
这就是我生成自定义单元格的方式:
internal class UITextSingleline : UITableViewCell
UILabel headingLabel;
UITextView textBox;
int MultiHeight;
public bool secure;
public UITextSingleline() : this(null, 1)
public UITextSingleline(int multiheight) : this(null, multiheight)
public UITextSingleline(NSString cellId, int multiheight) : base(UITableViewCellStyle.Default, cellId)
MultiHeight = multiheight;
SelectionStyle = UITableViewCellSelectionStyle.None;
headingLabel = new UILabel()
Font = UIFont.SystemFontOfSize(16),
TextColor = UIColor.DarkTextColor,
BackgroundColor = UIColor.Clear
;
textBox = new UITextView()
ClipsToBounds = true,
Font = UIFont.SystemFontOfSize(16),
TextColor = UIColor.DarkTextColor
;
if (multiheight == 1) textBox.TextContainer.MaximumNumberOfLines = 1;
textBox.Layer.CornerRadius = 10.0f;
textBox.Layer.BorderColor = UIColor.DarkTextColor.CGColor;
textBox.Layer.BorderWidth = 1f;
ContentView.AddSubviews(new UIView[] headingLabel, textBox );
public override void LayoutSubviews()
base.LayoutSubviews();
headingLabel.Frame = new CGRect(16, 8, ContentView.Bounds.Width - 32, 20);
textBox.Frame = new CGRect(16, 32, ContentView.Bounds.Width - 32, 36 * MultiHeight); /* see? magic numbers all over the place */
public void UpdateCell(string caption, string text)
headingLabel.Text = caption;
textBox.Text = text;
public string Text
get
return textBox?.Text;
set
if (textBox != null) textBox.Text = value;
这就是它与包含表视图的链接方式:
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
switch (indexPath.Section)
case 0:
/* area/workplace */
switch (indexPath.Row)
case 0:
/* area picker (omitted) */
case 1:
/* workplace text input (single-line) */
if (txtWorkplace == null)
txtWorkplace = new UITextSingleline();
txtWorkplace.UpdateCell("Workplace", Data.Instance.Payload.report.workplace);
return txtWorkplace;
break;
case 1:
/* rest ommitted for brevity */
break;
return null;
我已经在 SO 和互联网上搜索了与 systemmetrics 等效的东西,有很多颜色和字体,但我只找到了关于尺寸、边距、插图、角半径等的少量信息:
This question 处理相反的情况,去掉任何边距,并且没有提及如何复制 iOS 默认值。 This page from apple dev 提到了整个separatorInset
的属性 TableView
,这似乎适用于左缩进,但我对将布局的一部分应用到另一部分的指标有些怀疑。
硬编码幻数不是一种选择。我们在 iPhone 和 iPad 上进行了测试,发现即使在相同的设备上,只有 iOS 版本不同,插图的默认值也会有所不同。 我也会对 Objective-C 和 Swift 提示和解决方案感到满意,只要它们在正确翻译后在 xamarin 中工作。
【问题讨论】:
【参考方案1】:如果您想根据不同的设备或不同的版本使用默认边距,为什么不尝试自动布局? NSLayoutAttribute.LeadingMargin
表示元素边距的默认前沿。在您的UITextSingleline
中将LayoutSubviews()
从硬代码修改为自动布局:
假设单元格只有一个标签来显示一些文本:
public override void LayoutSubviews()
base.LayoutSubviews();
var leadingConstraint = NSLayoutConstraint.Create(headingLabel, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.LeadingMargin, 1.0f, 0);
var topConstraint = NSLayoutConstraint.Create(headingLabel, NSLayoutAttribute.Top, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.TopMargin, 1.0f, 0);
var trailingConstraint = NSLayoutConstraint.Create(headingLabel, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.TrailingMargin, 1.0f, 0);
var bottomConstraint = NSLayoutConstraint.Create(headingLabel, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.BottomMargin, 1.0f, 0);
ContentView.AddConstraints(new NSLayoutConstraint[] leadingConstraint, topConstraint, trailingConstraint, bottomConstraint );
这样,headingLabel
将具有与“标准内置单元格的 TextLabel”相同的布局。
此外,在您的情况下,您似乎也想在您的单元格中添加UITextView
。我建议您在构造函数时添加约束,我提供我的约束供您参考:
public MyTableViewCell (IntPtr handle) : base (handle)
headingLabel = new UILabel()
Font = UIFont.SystemFontOfSize(17),
TextColor = UIColor.DarkTextColor,
BackgroundColor = UIColor.Clear,
Lines = 0
;
textBox = new UITextView()
ClipsToBounds = true,
Font = UIFont.SystemFontOfSize(16),
TextColor = UIColor.DarkTextColor
;
ContentView.AddSubview(headingLabel);
ContentView.AddSubview(textBox);
// Disable this to enable autolayout
headingLabel.TranslatesAutoresizingMaskIntoConstraints = false;
textBox.TranslatesAutoresizingMaskIntoConstraints = false;
doLayouts();
void doLayouts()
var leadingConstraint = NSLayoutConstraint.Create(headingLabel, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.LeadingMargin, 1.0f, 0);
var topConstraint = NSLayoutConstraint.Create(headingLabel, NSLayoutAttribute.Top, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.TopMargin, 1.0f, 0);
var trailingConstraint = NSLayoutConstraint.Create(headingLabel, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.TrailingMargin, 1.0f, 0);
ContentView.AddConstraints(new NSLayoutConstraint[] leadingConstraint, topConstraint, trailingConstraint );
var boxLeading = NSLayoutConstraint.Create(textBox, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.LeadingMargin, 1.0f, 0);
var boxTop = NSLayoutConstraint.Create(textBox, NSLayoutAttribute.Top, NSLayoutRelation.Equal, headingLabel, NSLayoutAttribute.Bottom, 1.0f, 4);
var boxTrailing = NSLayoutConstraint.Create(textBox, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.TrailingMargin, 1.0f, 0);
var boxBottom = NSLayoutConstraint.Create(textBox, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.BottomMargin, 1.0f, 0);
var boxHeight = NSLayoutConstraint.Create(textBox, NSLayoutAttribute.Height, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1.0f, 36 * MultiHeight);
ContentView.AddConstraints(new NSLayoutConstraint[] boxLeading, boxTop, boxTrailing, boxBottom, boxHeight );
使用 AutoLayout 的另一个好处是:在将 TableView 的 RowHeight 设置为 UITableView.AutomaticDimension
和 EstimatedHeight 后,如果我们设置了正确的约束,单元格将根据其内容自动计算行高。
【讨论】:
感谢您为整理这些内容所做的努力。我们按照建议做了,它就像一个魅力。 很高兴它帮助了你。以上是关于如何为具有与内置单元格相同的布局指标的“UITableView”提供自定义“UITableCell”?的主要内容,如果未能解决你的问题,请参考以下文章
如何为具有 uilocalnotification 的单元格提供单独的颜色