作为一个小背景,我构建了一个旋转的UITableView,作为一种横向的"picker"视图。要做到这一点,我需要一个UITableView,对其应用旋转变换,然后在表视图中再次旋转UITableViewCells。
问题是,一些表格单元格变得"错位"——它们的边框与其他表格单元格相距一定距离(在x和y维度上)。
我已经缩小了这个错误发生在[tableView reloadData]
调用后完全不在可见tableview rect中的第一个表单元格上的范围。(即,如果我有4个表单元格,A是完全可见和绘制的,B是半开/半关视图的,C和D是完全不在屏幕上且尚未渲染的,当我滚动到C时,它会被窃听,但当我滚动至D时,它不会被窃听)。
现在为一些代码-
包含视图的init
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
...
self.tableView = [[UITableView alloc] init];
[self addSubview:_tableView];
[_tableView setDelegate:self];
[_tableView setShowsVerticalScrollIndicator:NO];
[_tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
CGAffineTransform transform = CGAffineTransformMakeRotation(-1.5707963);
_tableView.transform = transform;
_tableView.frame = self.bounds;
...
}
return self;
}
相关委托方法
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [tableView.dataSource tableView:tableView cellForRowAtIndexPath:indexPath].frame.size.height;
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
CGAffineTransform transform = CGAffineTransformMakeRotation(1.5707963);
cell.transform = transform;
}
表格单元格的布局子视图
编辑:我根据单元格内容的长度手动设置单元格的大小(主要是宽度)
- (void)layoutSubviews {
[super layoutSubviews];
// some calculations and sizing of subviews
// height and width are swapped here, because the table cell will be rotated.
self.frame = (CGRect){self.frame.origin.x,self.frame.origin.y,calculatedHeight,calculatedWidth};
}
当出现问题的表单元格到达布局子视图时,它的frame.origin
似乎设置不正确。将帧的origin.x
值设置为0可以解决x维度偏移问题,但显然我不能对y维度执行同样的操作,因为该值决定了单元格在表视图中的位置。
如果有一些关键信息我可能会遗漏,请告诉我。谢谢
您是否尝试设置单元层的锚点,即层旋转(转换)的点。它默认为.5,.5,这是图层的中心,它可能需要设置为0,0(或1,1-我不记得图层坐标是否从我的头顶反转)
或者尝试在应用转换后立即在willDisplayCell中设置帧,而不是在布局子视图中进行设置
好消息-在花了很多小时试图弄清楚这一点之后,我偶然发现了解决方案。
该代码被多次调用,用于"被窃听"的单元格,显然由于CALayer和CGAffineTransform的一些复杂性,分配transform具有附加影响。
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
CGAffineTransform transform = CGAffineTransformMakeRotation(1.5707963);
cell.transform = transform;
}
解决方案是将转换移到单元格的init方法中,这样就可以保证每个单元格只设置一次。
// ... init stuff
self.transform = CGAffineTranformMakeRotation(1.5707963);
// ... more init stuff
创建UITableViewCell的子类及其布局子视图覆盖确保在那里设置转换:
class InvertedTableViewCell: UITableViewCell {
override func layoutSubviews() {
self.transform = CGAffineTranformMakeRotation(1.5707963)
}
}