如何确定分组UITableView的边距(或者更好,如何设置它)?

时间:2011-01-16 21:12:09

标签: uitableview

分组的UITableView在视图边缘和表格单元格之间放置一个边距。令人讨厌(对我而言)这个边距是视图宽度的一些函数。

在我的应用程序中,我有两个不同宽度的UITableView,我正在寻找对齐单元格的边缘。

是否可以获得此保证金?或者更好的是可以设置这个保证金吗?

欢呼声, --Ben

9 个答案:

答案 0 :(得分:53)

与Cell Margin相关的分组TableView宽度

TBWidth(0到20) 左边距= TBWidth - 10

TBWidth(20到400) 左边距= 10

TBWidth(401到546) 左边界= 31

TBWidth(547到716) 左边距= apx 6%of tableView

TBWidth(717到1024) 左边界= 45

- (float) groupedCellMarginWithTableWidth:(float)tableViewWidth
{
    float marginWidth;
    if(tableViewWidth > 20)
    {
        if(tableViewWidth < 400)
        {
            marginWidth = 10;
        }
        else
        {
            marginWidth = MAX(31, MIN(45, tableViewWidth*0.06));
        }
    }
    else
    {
        marginWidth = tableViewWidth - 10;
    }
    return marginWidth;
}

答案 1 :(得分:18)

通过创建(和使用!)UITableViewCell的子类,您可以实现您正在寻找的东西。只需在layoutsubviews中移动contentview和backgroundview,就像下面的代码示例一样,将单元格20pt的可见部分向右移动。

- (void) layoutSubviews
{
    NSLog (@"Cell/contentview/backgroundview before:\n%@\n%@\n%@", self, self.contentView, self.backgroundView);
    [super layoutSubviews];
    CGRect frame = self.backgroundView.frame;
    frame.origin.x += 20;
    frame.size.width -= 20;
    self.backgroundView.frame = frame;
    frame = self.contentView.frame;
    frame.origin.x += 20;
    frame.size.width -= 20;
    self.contentView.frame = frame;

    NSLog (@"Cell/contentview/backgroundview after:\n%@\n%@\n%@", self, self.contentView, self.backgroundView);
}

答案 2 :(得分:12)

我正在使用Matthew Thomas实现,但它不可靠(如果你在你的控制器中使用自动旋转它就坏了)并且有很多硬编码的代码......我意识到有一个非常简单的解决方案,我的实现是单行的代码:

- (float)cellMargins
{
    return self.backgroundView.frame.origin.x * 2;
}

这是更好的IMO:)

编辑:我的实现也不可靠(切换到编辑模式时无法正常工作),这是我的最终实现(我分别处理了左右边距):

- (float)leftMargin
{
    return self.contentView.frame.origin.x;
}

- (float)rightMargin
{
    CGRect frame = self.contentView.frame;
    float containerWidth = frame.size.width;
    float margin = self.frame.size.width - (containerWidth + frame.origin.x);
    return margin;
}

- (float)cellMargins
{
    return ([self leftMargin] + [self rightMargin]);
}

答案 3 :(得分:6)

更新了Matthew Thomas的细胞边缘计算代码。 通过UITableView的类别创建。 当您需要确定单元格中的文本高度时,这可能很有用,并且您不知道该单元格的宽度。

因此,可以像

那样计算实际单元格
cell.width = tableView.width - tableView.cellsMargin * 2;

这是代码

@implementation UITableView (CellsMargins)

// This is black magic
// from
// http://stackoverflow.com/questions/4708085/how-to-determine-margin-of-a-grouped-uitableview-or-better-how-to-set-it

- (CGFloat)cellsMargin {

   // No margins for plain table views
   if (self.style == UITableViewStylePlain) {
      return 0;
   }

   // iPhone always have 10 pixels margin
   if (! isIPad()) {
      return 10;
   }

   CGFloat tableWidth = self.frame.size.width;

   // Really small table
   if (tableWidth <= 20) {
      return tableWidth - 10;
   }

   // Average table size
   if (tableWidth < 400) {
      return 10;
   }

   // Big tables have complex margin's logic
   // Around 6% of table width,
   // 31 <= tableWidth * 0.06 <= 45

   CGFloat marginWidth  = tableWidth * 0.06;
   marginWidth = MAX(31, MIN(45, marginWidth));
   return marginWidth;
}

@end

答案 4 :(得分:2)

现在可以通过UITableViewCell的属性访问它:

@property(nonatomic) UIEdgeInsets separatorInset

Apple Docs - UITableViewCell - seperatorInset

答案 5 :(得分:1)

我想用一个设置固定保证金的代码来补充马修的答案。

  1. 子类UITableViewCell。
  2. 实施setFrame:
  3. - (void)setFrame:(CGRect)frame
    {
        CGFloat inset = 15.0;
        CGFloat tableWidth = 400.0;
        frame.origin.x -= [self groupedCellMarginWithTableWidth:tableWidth] - inset;
        frame.size.width = frame.size.width + 2 * ([self groupedCellMarginWithTableWidth:tableWidth] - inset);
        [super setFrame:frame];
    }
    

    这将设置左边距和右边距为15.0,而表格宽度可能会有所不同。

答案 6 :(得分:1)

“弹性”区域的左边距更准确,而不是'apx。 6%计算'

旁注:除了左边距填充外,iPad还实现了额外的部分顶部和底部填充,低于400.0f表宽度10.0f,否则为31.0f。

-(CGFloat)leftMarginForTableView:(UITableView*)tableView
{
    if (tableView.style != UITableViewStyleGrouped) return 0;
    CGFloat widthTable = tableView.bounds.size.width;
    if (isPhone)              return (10.0f);
    if (widthTable <= 400.0f) return (10.0f);
    if (widthTable <= 546.0f) return (31.0f);
    if (widthTable >= 720.0f) return (45.0f);
    return (31.0f + ceilf((widthTable - 547.0f)/13.0f));
}

答案 7 :(得分:0)

如果有人需要这个,从tableView:titleForHeaderInSection:获得的部分标题左边距的功能似乎是:

- (float)marginForSectionTitleOnGroupedTableView {
   float width = self.width;

   if (width <= 400) return 19;
   else if (width >= 401 && width < 547) return 40;
   else if (width >= 547 && width < 560) return 41;
   else if (width >= 560 && width < 573) return 42;
   else if (width >= 573 && width < 586) return 43;
   else if (width >= 586 && width < 599) return 44;
   else if (width >= 599 && width < 612) return 45;
   else if (width >= 612 && width < 625) return 46;
   else if (width >= 625 && width < 639) return 47;
   else if (width >= 639 && width < 652) return 48;
   else if (width >= 652 && width < 665) return 49;
   else if (width >= 665 && width < 678) return 50;
   else if (width >= 678 && width < 691) return 51;
   else if (width >= 691 && width < 704) return 52;
   else if (width >= 704 && width < 717) return 53;

   // if (width >= 717) 
   return 54;
}

对于宽度大于401,边距似乎约为表格视图宽度的7.5%;但是当尝试将其他视图与节标题对齐时,对齐方式无法按预期工作;所以冗长的方法似乎更好。

答案 8 :(得分:0)

我尝试过不同的方法。但不确定它是否始终有效。我有一个分组的UITableView,需要自定义标题视图。但是如您所知,在实现viewForHeader inSection方法时,我们无法确定创建的视图的边距。 所以,我所做的是首先将一个CGRect属性添加到ViewController .m文件:

@property(nonatomic)CGRect groupedCellRectangle;

并在UITableViewDelegate中:

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
    static BOOL groupFrameInitialized = NO;
    if(!groupFrameInitialized){
        groupFrameInitialized = YES;
        self.groupedCellRectangle = cell.contentView.frame;
    }
}

之后,在我的viewForHeader inSection方法中:

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
  UIView *v = [[UIView alloc] initWithFrame:CGRectMake(self.groupedCellRectangle.origin.x, 0, self.groupedCellRectangle.size.width, 28)];
  [v setBackgroundColor:[UIColor clearColor]];
  UILabel *label = [[UILabel alloc] initWithFrame:v.frame];
  label.text = @"KAF";
  [v addSubview:label];
  return v;
}

结果就像我假设的那样。 groupedCellRectangle已成功存储带有边距的CGRect值。

这种方法背后的想法是UITableView在willDisplay调用之后总是调用viewForHeader方法。

希望有帮助...