Вставка iOS 8 UITableView: если у вас есть ячейки с пользовательским макетом, у вас, вероятно, тоже будет эта проблема

В iOS 8 для более крупных устройств по умолчанию используется табличная панель по умолчанию. Если вы выставляете пользовательские ячейки и сопоставляете их ограничение на левое расположение с размером в 15 по умолчанию для ячейки, ваш макет будет отлично смотреться на небольших устройствах, но на более крупных устройствах, где изменяется вставка, вы получите нечто похожее на следующие



TableViewCell separator inset alignement



Как я могу это исправить?

Ответ 1

Удалось написать что-то, что работает хорошо. Если есть более красивое решение, разделите его.

@interface InsetRespectingTableViewCell()

@property (nonatomic) IBOutlet NSLayoutConstraint * leftContentInset;
@property (nonatomic) IBOutlet NSLayoutConstraint * rightContentInset;

@end

@implementation InsetRespectingTableViewCell


- (UITableView *)tableView {

    UIView *view;
    for (view = self.superview; ![view isKindOfClass:UITableView.class] && view; view = view.superview);
    return (UITableView *)view;

}

- (void)updateInset {

    CGFloat defaultInset = [self tableView].separatorInset.left;
    self.leftContentInset.constant = defaultInset;
    self.rightContentInset.constant = defaultInset;

}

- (void)didMoveToSuperview {

    [super didMoveToSuperview];
    [self updateInset];

}

Ответ 2

В Xcode6 нет опции/свойства для ее исправления. Существует один метод set SetSepratorInset, который устанавливает значение вставки. Но мы не можем передать значение (-ve) на <#CGFloat left#>, чтобы запустить его слева. Поскольку его минимальное значение всегда равно 0.

[tableView setSeparatorInset:UIEdgeInsetsMake(<#CGFloat top#T, <#CGFloat left#>, <#CGFloat bottom#>, <#CGFloat right#>)];

Если вы хотите его решить, скройте строку разделителя и добавьте imageView 1px с необходимой шириной, чтобы создать линию и добавить ее в ячейку, и она также будет выглядеть одинаково на каждом устройстве.

Ответ 3

Мне удалось использовать ограничения по размеру, чтобы соответствовать внешнему виду на всех, кроме iPhone 6+, до тех пор, пока я придерживался iOS 8. Фиксация внешнего вида на iOS 8 поменяла его на iOS 7. Основной подход, который я использовал, установить ограничения по-разному для "Regular Width | Any Height" и использовать вставки из 13 px вместо 7 px:

  • Разложите свой вид с помощью автоматического макета с пространством +/- 7 px для супер контейнера.
  • Выберите ограничение макета из списка слева
  • В редакторе свойств с правой стороны щелкните (+) рядом с константой и выберите "Regular Width | Any Height" из всплывающего окна. Это добавит новую строку под константой.
  • Измените значение с 7 на 13.

это не полное решение, но это начало.

Ответ 4

Примечание. Если вам нужно добавить строку true one pixel line, не обманывайте изображение, используйте это:

@interface UILine : UIView
@end

@implementation UILine

-(void)awakeFromNib
    {
    float sortaPixel = 1.0/[UIScreen mainScreen].scale;

    // float sortaPixel = 1.0/self.contentScaleFactor;
    // -- recall, that does NOT work when loading from storyboard!

    UIView *line = [[UIView alloc] initWithFrame:
    CGRectMake(0, 0, self.frame.size.width, sortaPixel)];

    line.userInteractionEnabled = NO;
    line.backgroundColor = self.backgroundColor;

    line.autoresizingMask = UIViewAutoresizingFlexibleWidth;

    [self addSubview:line];

    self.backgroundColor = [UIColor clearColor];
    self.userInteractionEnabled = NO;
    }

@end

Как использовать в раскадровке, просто сделайте UIView, который находится в точном месте, и точную ширину, которую вы хотите. (Естественно, сделайте его растянутым по ширине или любым другим, по мере необходимости.)

Просто сделайте представление - скажем - 5 pr 6 пикселей высоким - чисто, чтобы вы могли видеть его правильно. (Неважно, насколько высоко вы делаете это на раскадровке.)

(Сделайте вершину UIView именно там, где вы хотите использовать однопиксельную линию.)

Сделайте UIView любым желаемым цветом, возможно, черным.

Измените класс на UILine. Во время выполнения он будет рисовать идеальную однопиксельную линию в точном месте на всех устройствах.

Надеюсь, что это поможет с этим небольшим образом.

Ответ 5

Это очень интересно.

В проекте, созданном Xcode5, левая вставка разделителя - 15/15/16 (iPhone5s/iPhone6 ​​/iPhone6P).

И в проекте, создаваемом Xcode6, 16/16/20 (iPhone5s/iPhone6 ​​/iPhone6P).

В моем случае я отключу разделитель по умолчанию в tableView и сделал baseCell для перерисовки разделителя.

ссылка: https://github.com/jshl8612/UTableViewBaseCell

Надеет, что это немного помогает.

Ответ 6

Вот как это можно исправить.

@IBOutlet weak var leftViewLeadingConstraint: NSLayoutConstraint!

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    switch UIScreen.mainScreen().scale {
    case 2:
        leftViewLeadingConstraint.constant = 7.0
    case 3:
        leftViewLeadingConstraint.constant = 11.0
    default:
        assertionFailure("Error: wrong scale value")
    }
}

Ответ 7

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

От: https://developer.apple.com/library/IOs/documentation/UIKit/Reference/UIView_Class/index.html#//apple_ref/occ/instm/UIView/layoutSubviews

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