我的应用程序有一个UITableView,其中包含具有透明背景的可变高度单元格。在针对iOS 7 SDK构建时,行删除动画存在问题:
注意一些细胞的闪烁,例如第15,17,21和23行。在iOS< = 6上未观察到此行为。
如果我做了这些事情中的任何一个问题就会消失(我还没准备好这样做):
我尝试过的其他任何帮助。 iOS 7上是否需要一些秘密酱才能获得平滑的行删除动画?
这是我可以将问题提炼到[C#/ Xamarin]的最小测试用例:
public class MainViewController : UITableViewController {
public MainViewController() {
this.TableView.Source = new TableSource(this.TableView, 50);
}
public override void ViewDidAppear(bool animated) {
base.ViewDidAppear(animated);
NSTimer.CreateRepeatingScheduledTimer(0.5f, ((TableSource) this.TableView.Source).DeleteFirstRow);
}
}
public class TableSource : UITableViewSource {
private UITableView tableView;
private List<RowInfo> activeRows;
public TableSource(UITableView tableView, int numRows) {
this.tableView = tableView;
this.activeRows = new List<RowInfo>();
for (int i=1; i<=numRows; i++) {
this.activeRows.Add(new RowInfo(i));
}
}
public void DeleteFirstRow() {
if (this.activeRows.Count == 0) return;
this.activeRows.RemoveAt(0);
this.tableView.BeginUpdates();
this.tableView.DeleteRows(new NSIndexPath[] { NSIndexPath.FromRowSection(0, 0) }, UITableViewRowAnimation.Right);
this.tableView.EndUpdates();
}
public override int RowsInSection(UITableView tableview, int section) {
return this.activeRows.Count;
}
public override float GetHeightForRow(UITableView tableView, NSIndexPath indexPath) {
return this.activeRows[indexPath.Row].Height;
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath) {
const string CellID = "Cell";
UITableViewCell cell = tableView.DequeueReusableCell(CellID);
if (cell == null) {
cell = new UITableViewCell(UITableViewCellStyle.Default, CellID);
}
cell.TextLabel.Text = this.activeRows[indexPath.Row].Text;
return cell;
}
public override void WillDisplay(UITableView tableView, UITableViewCell cell, NSIndexPath indexPath) {
cell.BackgroundColor = UIColor.Clear;
}
private class RowInfo {
public RowInfo(int index) {
Random random = new Random(index);
this.Height = random.Next(20, 80);
this.Text = "Row " + index + " has height " + this.Height;
}
public float Height;
public string Text;
}
}
答案 0 :(得分:3)
TLDR:cell.clipsToBounds = YES;
====
这是我发现的:
' | | | | <UITableViewCell: 0x79e81910; frame = (0 232; 320 32); text = 'row 27'; clipsToBounds = YES; autoresize = W; animations = { position=<CABasicAnimation: 0x79e8f020>; }; layer = <CALayer: 0x79e81aa0>>
| | | | | <UITableViewCellScrollView: 0x79e81ad0; frame = (0 0; 320 32); autoresize = W+H; gestureRecognizers = <NSArray: 0x79e81d60>; layer = <CALayer: 0x79e81ca0>; contentOffset: {0, 0}>
| | | | | | <UIView: 0x79e8b7d0; frame = (0 0; 320 51); clipsToBounds = YES; layer = <CALayer: 0x79e8b830>>
| | | | | | <UITableViewCellContentView: 0x79e81f50; frame = (0 0; 320 31.5); gestureRecognizers = <NSArray: 0x79e82160>; layer = <CALayer: 0x79e81fc0>>
| | | | | | | <UILabel: 0x79e821b0; frame = (15 0; 290 31.5); text = 'row 27'; userInteractionEnabled = NO; layer = <CALayer: 0x79e82260>>
| | | | | | <_UITableViewCellSeparatorView: 0x79e824d0; frame = (15 31.5; 305 0.5); layer = <CALayer: 0x79e82540>>
如果你仔细观察第27行,你会注意到单元格的高度是32px。单元格的子视图是一个scrollView(我读过的地方是你向左滑动以显示iOS7中的行动作的滚动视图)。正如我们所看到的,contentView具有32px的正确高度,但是,这里是有趣部分开始的地方:在contentView后面有一个视图,其高度为51像素。我相信这是罪魁祸首。
不幸的是,我无法找到哪个视图(它不是backgroundView,它不是selectedBackgroundView等,简而言之:它不是UITableViewCell类的公共属性中的任何视图)。 / p>
另外,在事物的可怕方面,该视图的backgroundColor是clearColor。理论上它甚至不应该是可见的!我相信,我们在这里处理的是一些CoreAnimation优化,它不会渲染这个神秘视图背后的区域。
那么,会发生什么:1)细胞被创建2)细胞被调整大小并准备呈现3)细胞获得正确大小的神秘视图4)细胞被重复使用5)细胞被调整为新的动态高度6)scrollView&amp; contentView也会调整大小,但神秘视图不是(请注意它没有设置任何调整大小的掩码)。
这解释了为什么您能够以上述三种方式解决此问题。
解决方法是在创建时设置单元格cell.clipsToBounds = YES;
。
我还建议不要设置cell.backgroundColor。 IIRC,您应该使用cell.backgroundView(将其设置为新创建的视图并将其设置为backgroundColor)。然而,单元格的默认bacgroundColor无论如何都是清晰的,所以在这种情况下这并不重要。
我很高兴听到某人的私人观点是什么。