我使用Monotouch.Dialog框架为用户输入我的应用程序构建表单。当我继承UITableViewCell时,我遇到了一个奇怪的问题,即屏幕显示重叠文本。当我说文本重叠时,我的意思是看起来好像一个整个单元格放在另一个上面,而不仅仅是标签被拼在一起或放错位置。
我在Xamarin网站here上关注了这个例子。
基本上我有这个UITableViewCell类
public class SAFutureAdCell : UITableViewCell
{
private UILabel issueAndSizeLabel, mailDateLabel, orderDateLabel, miscLabel, totalLabel;
private UIImage monthlyImage, ccoImage;
public SAFutureAdCell(IntPtr p) : base(p)
{
init ();
}
public SAFutureAdCell(string resuseIdentifier) : base(UITableViewCellStyle.Default, resuseIdentifier)
{
init ();
}
public SAFutureAdCell(NSString cellKey): base(UITableViewCellStyle.Default, cellKey)
{
init ();
}
private void init()
{
issueAndSizeLabel = new UILabel() {
TextColor = UIColor.Black,
Font = UIFont.BoldSystemFontOfSize(15),
BackgroundColor = UIColor.Clear,
ShadowColor = UIColor.Clear,
TextAlignment = UITextAlignment.Left,
ClipsToBounds = true
};
mailDateLabel = new UILabel() {
TextColor = UIColor.Black,
Font = UIFont.BoldSystemFontOfSize(15),
BackgroundColor = UIColor.Clear,
ShadowColor = UIColor.Clear,
TextAlignment = UITextAlignment.Left,
ClipsToBounds = true
};
orderDateLabel = new UILabel() {
TextColor = UIColor.Gray,
Font = UIFont.SystemFontOfSize(13),
BackgroundColor = UIColor.Clear,
ShadowColor = UIColor.Clear,
TextAlignment = UITextAlignment.Left,
ClipsToBounds = true
};
miscLabel = new UILabel() {
TextColor = UIColor.Gray,
Font = UIFont.SystemFontOfSize(13),
BackgroundColor = UIColor.Clear,
ShadowColor = UIColor.Clear,
TextAlignment = UITextAlignment.Right,
ClipsToBounds = true
};
totalLabel = new UILabel() {
TextColor = UIColor.Black,
Font = UIFont.BoldSystemFontOfSize(15),
BackgroundColor = UIColor.Clear,
ShadowColor = UIColor.Clear,
TextAlignment = UITextAlignment.Right,
ClipsToBounds = true
};
monthlyImage = AppearanceManager.MonthlyIndicator; // small blue circle
ccoImage = AppearanceManager.CcoIndicator; // small red circle
ImageView.Image = monthlyImage;
ImageView.ContentMode = UIViewContentMode.ScaleAspectFit;
ContentView.AddSubviews(issueAndSizeLabel, mailDateLabel, orderDateLabel, miscLabel, totalLabel);
}
public override void LayoutSubviews()
{
base.LayoutSubviews();
Accessory = UITableViewCellAccessory.DisclosureIndicator;
var b = ContentView.Bounds;
b.Width -= 30;
var x = 24;
issueAndSizeLabel.Frame = new RectangleF(x, 5, b.Width / 2, b.Height / 2 - 5).RoundFloats();
mailDateLabel.Frame = new RectangleF(issueAndSizeLabel.Frame.Right, 5, b.Width / 4, b.Height / 2 - 5).RoundFloats();
totalLabel.Frame = new RectangleF(mailDateLabel.Frame.Right, 5, b.Width / 4, b.Height / 2 - 5).RoundFloats();
orderDateLabel.Frame = new RectangleF(x, b.Height / 2 + 5, b.Width / 3, b.Height / 2 - 10).RoundFloats();
miscLabel.Frame = new RectangleF(totalLabel.Frame.Left, b.Height / 2 + 5, b.Width / 4, b.Height / 2 - 10).RoundFloats();
ImageView.Frame = new RectangleF(5, 0, AppearanceManager.MonthlyIndicator.Size.Width, ContentView.Frame.Height);
}
public void Update(Ad ad)
{
issueAndSizeLabel.Text = string.Format("{0} - {1}", ad.IssueCode, ad.AdvertSize);
mailDateLabel.Text = string.Format("Mail: {0}", ad.MailDate.ToShortDateString());
orderDateLabel.Text = string.Format("Order: {0}", ad.OrderDate.ToShortDateString());
miscLabel.Text = string.Format("Misc: {0}", ad.Misc.ToCurrency());
totalLabel.Text = string.Format("Total: {0}", ad.Total.ToCurrency());
if (ad.IsCCOPackage)
ImageView.Image = ccoImage;
else
ImageView.Image = monthlyImage;
ImageView.Alpha = (ad.IsMonthlyBilling || ad.IsCCOPackage) ? 1f : 0f;
}
}
此单元格将从此元素中使用。
public class SAFutureAdDetailElement : Element, IElementSizing
{
public SAFutureAdDetailElement(Ad ad, NSAction tapped) : base("FutureAdDetail")
{
this.ad = ad;
Tapped += tapped;
}
public SAFutureAdDetailElement(Ad ad) : base("FutureAdDetail")
{
this.ad = ad;
}
private static NSString cellKey = new NSString("SAFutureAdDetailElement");
protected override NSString CellKey
{
get
{
return cellKey;
}
}
public override UITableViewCell GetCell(UITableView tv)
{
var cell = tv.DequeueReusableCell (cellKey) as SAFutureAdCell;
if (cell == null) {
cell = new SAFutureAdCell(cellKey);
}
cell.Update (ad);
return cell;
}
public override void Selected(DialogViewController dvc, UITableView tableView, NSIndexPath path)
{
if (Tapped != null)
Tapped ();
tableView.DeselectRow (path, true);
}
public float GetHeight(UITableView tableView, NSIndexPath indexPath)
{
return cellHeight;
}
private Ad ad;
public event NSAction Tapped;
private int cellHeight = 60;
}
这些元素的集合被添加到MTD部分,如此
Section CreateOnPageSection()
{
var onPageSection = new Section ("Future On Page Ads");
onPageSection.AddAll (
from ad in orderInfo.AdsFuture
where !Settings.offPageAdSizes.Contains (ad.AdvertSizeID)
select new SAFutureAdDetailElement (
ad,
() => {
NavigationController.PushViewController (new FutureAdDetailController (customer.CustID, ad, this), true);
}
)
);
return onPageSection;
}
然后将其作为DialogViewController的一部分添加到RootElement中。根元素还添加了3个其他部分,所有部分都有自定义元素,它们都有自己的自定义UITableViewCells,它们都非常相似。它们在标签的位置和进入标签的数据方面基本不同。
在滚动发生之前或直到您将视图推送到NavigationController然后弹回到此视图之前,文本不会重叠。通常很难在较新的iPad上重现(此应用仅限iPad)。在较旧的iPad 2上,此问题的发生频率更高。有时我可以让它在我的Air上发生,但要在那台机器上实现它会更加困难。
以下是重叠文字的屏幕截图。
答案 0 :(得分:0)
必须是细胞无法正常重复使用的情况。所以我的直觉是GetCell方法的改变将起到作用。
public override UITableViewCell GetCell(UITableView tv)
{
var cell = tv.DequeueReusableCell (cellKey);// as SAFutureAdCell;
if (cell == null) {
cell = new SAFutureAdCell(cellKey);
}
else
{
cell.Element = this;
}
cell.Update (ad);
return cell;
}
您可以尝试更改这样的GetCell方法吗?它可能会修复它......
答案 1 :(得分:0)
好的,所以我找到了回答我自己的问题。看起来LayoutSubviews如何与细胞回收一起使用存在问题。基本上我做的是我摆脱了自定义单元格并将所有显示loginc移动到自定义元素中的GetCell方法中。元素类看起来像这样。
public class SAFutureAdDetailElement : Element, IElementSizing
{
public SAFutureAdDetailElement(Ad ad, NSAction tapped) : base("FutureAdDetail")
{
this.ad = ad;
Tapped += tapped;
}
public SAFutureAdDetailElement(Ad ad) : base("FutureAdDetail")
{
this.ad = ad;
}
private static NSString cellKey = new NSString("SAFutureAdDetailElement");
protected override NSString CellKey
{
get
{
return cellKey;
}
}
public override UITableViewCell GetCell(UITableView tv)
{
var cell = tv.DequeueReusableCell (cellKey);
if (cell == null) {
cell = new UITableViewCell (UITableViewCellStyle.Default, cellKey);
cell.IndentationLevel = 0;
var x = 24;
var contentWidth = tv.Bounds.Width - 30 - x;
var issueAndSizeLabel = new UILabel (new RectangleF (x, 5, contentWidth / 2, cellHeight / 2 - 5).RoundFloats ()) {
TextColor = UIColor.Black,
Font = UIFont.BoldSystemFontOfSize (15),
BackgroundColor = UIColor.Clear,
ShadowColor = UIColor.Clear,
TextAlignment = UITextAlignment.Left,
ClipsToBounds = true,
Text = string.Format ("{0} - {1}", ad.IssueCode, ad.AdvertSize)
};
var mailDateLabel = new UILabel (new RectangleF (issueAndSizeLabel.Frame.Right, 5, contentWidth / 4, cellHeight / 2 - 5).RoundFloats ()) {
TextColor = UIColor.Black,
Font = UIFont.BoldSystemFontOfSize (15),
BackgroundColor = UIColor.Clear,
ShadowColor = UIColor.Clear,
TextAlignment = UITextAlignment.Left,
ClipsToBounds = true,
Text = string.Format ("Mail: {0}", ad.MailDate.ToShortDateString ())
};
var orderDateLabel = new UILabel (new RectangleF (x, cellHeight / 2 + 5, contentWidth / 3, cellHeight / 2 - 10).RoundFloats ()) {
TextColor = UIColor.Gray,
Font = UIFont.SystemFontOfSize (13),
BackgroundColor = UIColor.Clear,
ShadowColor = UIColor.Clear,
TextAlignment = UITextAlignment.Left,
ClipsToBounds = true,
Text = string.Format ("Order: {0}", ad.OrderDate.ToShortDateString ())
};
var totalLabel = new UILabel (new RectangleF (mailDateLabel.Frame.Right, 5, contentWidth / 4, cellHeight / 2 - 5).RoundFloats ()) {
TextColor = UIColor.Black,
Font = UIFont.BoldSystemFontOfSize (15),
BackgroundColor = UIColor.Clear,
ShadowColor = UIColor.Clear,
TextAlignment = UITextAlignment.Right,
ClipsToBounds = true,
Text = string.Format ("Total: {0}", ad.Total.ToCurrency ())
};
var miscLabel = new UILabel (new RectangleF (totalLabel.Frame.Left, cellHeight / 2 + 5, contentWidth / 4, cellHeight / 2 - 10).RoundFloats ()) {
TextColor = UIColor.Gray,
Font = UIFont.SystemFontOfSize (13),
BackgroundColor = UIColor.Clear,
ShadowColor = UIColor.Clear,
TextAlignment = UITextAlignment.Right,
ClipsToBounds = true,
Text = string.Format ("Misc: {0}", ad.Misc.ToCurrency ())
};
var indicator = new UIImageView (new RectangleF (5, 0, AppearanceManager.MonthlyIndicator.Size.Width, cellHeight));
indicator.ContentMode = UIViewContentMode.ScaleAspectFit;
if (ad.IsCCOPackage) {
indicator.Image = AppearanceManager.CcoIndicator;
} else if (ad.IsMonthlyBilling) {
indicator.Image = AppearanceManager.MonthlyIndicator;
}
cell.Accessory = UITableViewCellAccessory.DisclosureIndicator;
cell.ContentView.AddSubviews (indicator, issueAndSizeLabel, mailDateLabel, orderDateLabel, miscLabel, totalLabel);
}
((UILabel)cell.ContentView.Subviews[1]).Text = string.Format("{0} - {1}", ad.IssueCode, ad.AdvertSize);
((UILabel)cell.ContentView.Subviews[2]).Text = string.Format("Mail: {0}", ad.MailDate.ToShortDateString());
((UILabel)cell.ContentView.Subviews[3]).Text = string.Format("Order: {0}", ad.OrderDate.ToShortDateString());
((UILabel)cell.ContentView.Subviews[4]).Text = string.Format("Misc: {0}", ad.Misc.ToCurrency());
((UILabel)cell.ContentView.Subviews[5]).Text = string.Format("Total: {0}", ad.Total.ToCurrency());
if (ad.IsCCOPackage) {
((UIImageView)cell.ContentView.Subviews [0]).Image = AppearanceManager.CcoIndicator;
} else if (ad.IsMonthlyBilling) {
((UIImageView)cell.ContentView.Subviews [0]).Image = AppearanceManager.MonthlyIndicator;
} else {
((UIImageView)cell.ContentView.Subviews [0]).Image = null;
}
return cell;
}
public override void Selected(DialogViewController dvc, UITableView tableView, NSIndexPath path)
{
if (Tapped != null)
Tapped ();
tableView.DeselectRow (path, true);
}
public float GetHeight(UITableView tableView, NSIndexPath indexPath)
{
return cellHeight;
}
private Ad ad;
public event NSAction Tapped;
private int cellHeight = 60;
}
我唯一不喜欢的是更新单元格值是一种痛苦,因为我必须从UILabel
的数组中抓取UIView
并像这样抛出它们这个((UILabel)cell.ContentView.Subviews[1])
,祝你好运跟踪哪个UILabel
,因为你现在不能使用变量名来引用UILabel
。是的,我确实尝试将标签作为元素的私有成员,并尝试以不起作用的方式更新它们。