Многострочные UILabels с автоматической компоновкой

Последние 2 дня я пытался заставить UITableViewCell выполнить следующий расчет вручную.

CGFloat availableWidthForValueLabel = availableWidth * 0.7f;
CGSize valueLabelFitSize = [_valueLabel sizeThatFits:CGSizeMake(availableWidthForValueLabel, MAXFLOAT)];
_valueLabel.frame = CGRectMake(availableWidth - valueLabelFitSize.width, 0, valueLabelFitSize.width, valueLabelFitSize.height);

CGFloat availableWidthForKeyLabel = availableWidth - CGRectGetWidth(_valueLabel.frame);
CGSize keyLabelFitSize = [_keyLabel sizeThatFits:CGSizeMake(availableWidthForKeyLabel, MAXFLOAT)];
CGFloat keyLabelX = CGRectGetMinX(_valueLabel.frame) - keyLabelFitSize.width;

У меня есть две многострочные метки (ключ, значение) в представлении.

Значение привязывается справа от представления, ключ привязывается слева от представления с текстом, выровненным по правому краю.

Я хочу сначала оценить ширину/высоту значений с максимальной шириной 0,7 * ширина представления, а затем хочу, чтобы ключ занимал оставшееся доступное пространство в представлении.

Это отлично работает для однострочных этикеток, но не для многострочных этикеток.

Я попытался установить предпочтительнуюMaxLayoutWidth метки значения как в updateConstraints, так и в layoutSubview в ячейке, но, похоже, происходит неправильное увеличение высоты ячейки, поэтому в ячейке появляются большие промежутки.

- (void)updateConstraints
{
    [super updateConstraints];

    // value width
    CGFloat width = ceil(self.keyValueSection.bounds.size.width * kValueMaxLenghtOfParentView);
    if (self.valueLabel.preferredMaxLayoutWidth != width )
    {
        self.valueLabel.preferredMaxLayoutWidth = width;
    }

    // dec width
    if (!self.decSection.hidden)
    {
        width = ceil(self.holderSection.bounds.size.width * kDecMaxLengthOfParentView);
        if (self.decLabel.preferredMaxLayoutWidth != width )
        {
            self.decLabel.preferredMaxLayoutWidth = width;
        }
    }

    // key width
    width = floor(self.keyValueSection.bounds.size.width - kKeyValueGap - self.valueLabel.bounds.size.width);

    if(self.keyLabel.preferredMaxLayoutWidth != width)
    {
        self.keyLabel.preferredMaxLayoutWidth = width;
    }
}

Я пробовал все, что мог найти в Интернете, и все это почти работает. Я попытался установить степень объятия и сжатия, но.


person Edys    schedule 14.08.2014    source источник


Ответы (1)


Хотя это может быть не самое элегантное решение, мне понравился способ делать то, что я хочу.

Я использую Autolayout для размещения меток, используя ограничения для вертикального интервала> = 0 сверху и снизу и выравнивания по центру Y. Затем я определяю ограничения для начала и конца между метками.

Затем я задаю каждой метке ограничение по высоте и ширине и использую метод sizeTofit для определения того, какими должны быть константы, и обновляю их, когда я устанавливаю свойства текста/атрибутированного текста меток.

self.keyLabel.text = model.lineKey;
if ([model.lineValue isKindOfClass:[NSString class]]) {
    self.valueLabel.text = model.lineValue;
}
else if ([model.lineValue isKindOfClass:[NSAttributedString class]])
{
    self.valueLabel.attributedText = model.lineValue;
}
else
{
    self.valueLabel.text = nil;
    self.valueLabel.attributedText = nil;
}

self.keyValueGap.constant = kKeyValueGap;
CGFloat availableWidth = CGRectGetWidth(self.keyValueSection.bounds);

CGFloat availableWidthForValueLabel = availableWidth * 0.5f;
CGSize valueLabelFitSize = [self.valueLabel sizeThatFits:CGSizeMake(availableWidthForValueLabel, MAXFLOAT)];

self.valueHeight.constant = valueLabelFitSize.height;
self.valueWidth.constant = valueLabelFitSize.width;

CGFloat availableWidthForkeyLabel = availableWidth - valueLabelFitSize.width - kKeyValueGap;


CGSize keyLabelFitSize = [self.keyLabel sizeThatFits:CGSizeMake(availableWidthForkeyLabel, MAXFLOAT)];

self.keyHeight.constant = keyLabelFitSize.height;
self.keyWidth.constant = availableWidthForkeyLabel;

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

person Edys    schedule 15.08.2014