Как определить маржу сгруппированного UITableView (или лучше, как его установить)? - PullRequest
32 голосов
/ 17 января 2011

Сгруппированный UITableView размещает поле между краем представления и ячейками таблицы. Досадно (для меня), это поле является некоторой функцией ширины вида.

В моем приложении у меня есть два UITableView различной ширины, которые я хочу выровнять по краям ячейки

Возможно ли получить эту маржу? Или лучше можно установить этот запас?

веселит, --Ben

Ответы [ 9 ]

53 голосов
/ 02 февраля 2011

Ширина сгруппированного TableView относительно поля ячейки

TBWidth (от 0 до 20) Левое поле = TBWidth - 10

TBWidth (от 20 до 400) Левая маржа = 10

TBWidth (от 401 до 546) Левая маржа = 31

TBWidth (от 547 до 716) Левое поле = apx 6% от 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;
}
18 голосов
/ 25 января 2011

Создав (и используя!) Подкласс UITableViewCell, вы можете достичь того, что ищете. Просто переместите contentview и backgroundview в layoutsubviews, как в примере кода ниже, который смещает видимые части ячейки на 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);
}
12 голосов
/ 08 декабря 2011

Я использовал реализацию Мэтью Томаса, но она ненадежна (она ломается, если вы используете автоповорот в ваших контроллерах) и содержит много жесткого кода ... Я понял, что есть очень простое решение, моя реализация - это одна строка код:

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

Это намного лучше, ИМО:)

РЕДАКТИРОВАТЬ: моя реализация тоже была ненадежной (она не работает должным образом при переключении в / из режима редактирования), это моя последняя реализация (я обрабатывал поля справа и слева отдельно):

- (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]);
}
6 голосов
/ 30 марта 2012

Обновлен код Мэтью Томаса для расчета полей. Создано с помощью категории UITableView. Это может быть полезно, когда вам нужно определить высоту текста в ячейке, и вы не знаете ширину этой ячейки.

Итак, фактическая ячейка может быть вычислена как

cell.width = tableView.width - tableView.cellsMargin * 2;

Вот код

@implementation UITableView (CellsMargins)

// This is black magic
// from
// /2443768/kak-opredelit-marzhu-sgruppirovannogo-uitableview-ili-luchshe-kak-ego-ustanovit

- (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
2 голосов
/ 12 октября 2014

Теперь это доступно через свойство UITableViewCell:

@property(nonatomic) UIEdgeInsets separatorInset

Apple Docs - UITableViewCell - seperatorInset

1 голос
/ 08 февраля 2013

Более точный левый край для «растянутой» зоны вместо «apx». 6% расчет. '

Примечание: в iPad реализованы дополнительные верхние и нижние отступы раздела в дополнение к отступу левого поля, на 10,0f меньше ширины таблицы 400,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));
}
1 голос
/ 01 марта 2012

Я хотел бы дополнить ответ Мэтью кодом для установки фиксированного поля.

  1. Подкласс UITableViewCell.
  2. Реализация setFrame:
- (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, в то время как ширина таблицы может варьироваться.

0 голосов
/ 09 ноября 2012

Я пробовал другой подход.Но не уверен, всегда ли это работает.У меня был сгруппированный UITableView и мне нужно было сделать настроенный вид заголовка.Но, как вы знаете, при реализации метода inForce viewForHeader мы не можем определить поля для нашего созданного представления.Итак, сначала я добавил свойство 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 всегда вызывает метод viewForHeader после вызова willDisplay.

Надеюсь, это поможет ...

0 голосов
/ 30 ноября 2011

На всякий случай, если кому-то это нужно, функция левого поля заголовка раздела, полученная из 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% от ширины табличного представления; но при попытке выровнять другой вид с заголовком раздела, выравнивание не сработало так, как ожидалось; так что многословный подход, кажется, работает лучше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...