Я искал весь день, но не смог заставить его работать.Как программно добавить UILabel с переменной высотой и макетом ios
У меня есть UIView
с двумя надписями над другой, с левой стороны и с одной кнопкой справа. Я добавил ограничения, чтобы autolayout
соответственно изменил размер. Все отлично работало, когда я установил одно ограничение для высоты UIView
(и ни одно ограничение для высоты двух UILabel
), но поскольку содержимое нижнего UILabel
будет меняться, я удалил это ограничение и установил два ограничения для UILabel
, один фиксированный для верхнего UILabel
и один с отношением «больше или равно» для нижнего UILabel
, а другой - для фиксации расстояния между нижними UILabel
и UIView
.
Похоже Автокомпоновка не способен рассчитать intrinsicContentSize
низшего UILabel
, потому что она никогда не увеличивает его высоту над 10px, несмотря на содержание нижней UILabel
.
UIView *miView = [[UIView alloc] init];
UILabel *miLabel = [[UILabel alloc] init];
[miLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[miDetailsLabel setNumberOfLines:1];
[miDetailsLabel setText:@"Just one line."];
[miView addSubview:miLabel];
UILabel *miDetailsLabel = [[UILabel alloc] init];
[miDetailsLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[miDetailsLabel setNumberOfLines:0];
[miDetailsLabel setText:@"Enough text to show 3 lines on an IP4, except first of three UILabels on my test code, with no content"];
[miView addSubview:miDetailsLabel];
UIButton *miButton = [[UIButton alloc] init];
[miButton setTranslatesAutoresizingMaskIntoConstraints:NO];
[miView addSubview:miButton];
NSArray *constraint_inner_h = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(0)-[label]-(10)-[button(52)]-(0)-|" options:0 metrics:nil views:@{@"label":miLabel, @"button":miButton}];
NSArray *constraint_inner2_h = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(0)-[details]-(10)-[button]-(0)-|" options:0 metrics:nil views:@{@"details":miDetailsLabel, @"button":miButton}];
NSArray *constraint_label_v = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(0)-[label(18)]-(2)-[details(>=10)]-(0)-|" options:0 metrics:nil views:@{@"label":miLabel, @"details":miDetailsLabel}];
NSArray *constraint_button_v = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[button(22)]" options:0 metrics:nil views:@{@"button":miButton}];
[miView addConstraint:[NSLayoutConstraint constraintWithItem:miButton attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:miView attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]];
[miView addConstraints:constraint_inner_h];
[miView addConstraints:constraint_inner2_h];
[miView addConstraints:constraint_label_v];
[miView addConstraints:constraint_button_v];
Я поместил сокращенную версию кода.
любые идеи о том, чего я не хватает?
Благодаря
UPDATE: Спасибо Мэтту советы, я попытался это решение, чтобы установить правильное значение для preferredMawLayoutWidth:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
NSArray *allKeys = [dictOpcionesTickets allKeys];
for (NSString *key in allKeys) {
NSArray *tmpArray = [dictOpcionesTickets objectForKey:key];
if (![[tmpArray objectAtIndex:0] isEqual:@""]) {
UILabel *tmpLabel = [tmpArray objectAtIndex:3];
tmpLabel.preferredMaxLayoutWidth = tmpLabel.frame.size.width;
NSLog(@"width: %f",tmpLabel.frame.size.width);
}
}
[self.view layoutIfNeeded];
}
Чтобы объяснить код, как я уже сказал, я это делаю динамически, поэтому я создал словарь с массивом со ссылками на мой UILabel
(среди прочих интересных сведений). Когда я запускаю код, я получаю следующий журнал (с кодом разбора 3 UILabel
, первый ярлыка без содержания):
2014-12-28 20:40:42.898 myapp[5419:60b] width: 0.000000
2014-12-28 20:40:42.912 myapp[5419:60b] width: 0.000000
2014-12-28 20:40:43.078 myapp[5419:60b] width: 229.000000
2014-12-28 20:40:43.080 myapp[5419:60b] width: 229.000000
2014-12-28 20:40:43.326 myapp[5419:60b] width: 229.000000
2014-12-28 20:40:43.327 myapp[5419:60b] width: 229.000000
Но я все еще получаю тот же результат ... UIView все еще показывают высота равна минимальной высоте, заданной ограничениями, не отображая содержание UILabel
.
ОБНОВЛЕНИЕ 2 Все еще обманывается.
Я проверил мой исходный код, но упрощена на свежий проект в Xcode 6, работает на реальном iPhone 4 с iOS7, и она работала отлично без установки preferredMaxLayoutWidth
или подклассов UILabel
, и даже без вызова layoutIfNeeded
на родительское представление. Но когда дело доходит до реального проекта (я думаю, что он был первоначально построен в Xcode 4 или 5) не работает:
- (void)addLabelsDinamically {
self.labelFixed.text = @"Below this IB label goes others added dinamically...";
UIButton *miBoton = [[UIButton alloc] init];
miBoton.translatesAutoresizingMaskIntoConstraints = NO;
[miBoton setTitle:@"Hola" forState:UIControlStateNormal];
[self.viewLabels addSubview:miBoton];
[self.viewLabels addConstraint:[NSLayoutConstraint constraintWithItem:miBoton attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.viewLabels attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]];
[self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[boton(22)]" options:0 metrics:nil views:@{@"boton":miBoton}]];
[self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[boton(40)]" options:0 metrics:nil views:@{@"boton":miBoton}]];
UILabel *miLabel = [[UILabel alloc] init];
miLabel.translatesAutoresizingMaskIntoConstraints = NO;
miLabel.backgroundColor = [UIColor redColor];
miLabel.numberOfLines = 0;
miLabel.text = @"ñkhnaermgñlkafmbñlkadnlñejtnhalrmvlkamnñnañorenoetñnngñsdbmnñgwn";
[self.viewLabels addSubview:miLabel];
[self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(8)-[label]-(10)-[boton]-(8)-|" options:0 metrics:nil views:@{@"label":miLabel,@"boton":miBoton}]];
[self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[previous]-(8)-[label]" options:0 metrics:nil views:@{@"label":miLabel,@"previous":self.labelFixed}]];
UIView *pre = miLabel;
miLabel = [[UILabel alloc] init];
miLabel.translatesAutoresizingMaskIntoConstraints = NO;
miLabel.backgroundColor = [UIColor greenColor];
miLabel.numberOfLines = 0;
miLabel.text = @"ñkhnaermgñlkafmbñlkadnlñejtnhalrmvlkamnñnañorenoetñnngñsdbmnñgwn";
[self.viewLabels addSubview:miLabel];
[self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(8)-[label]-(10)-[boton]-(8)-|" options:0 metrics:nil views:@{@"label":miLabel,@"boton":miBoton}]];
[self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[previous]-(8)-[label]" options:0 metrics:nil views:@{@"label":miLabel,@"previous":pre}]];
}
Ах, на одном экране я один UILabel
добавлен IB, с numberOfLines
набором до '0', вертикальное ограничение «больше или равно» и горизонтальное ограничение, установленное аналогичным образом (но оба ограничения, установленные на IB) ... и он отлично работает ... это заставляет меня гать !! любая помощь???
Я не пробовал ваш код, но прежде чем мы будем более глубоко вовлечены в это, попробуйте установить «preferredMaxLayoutWidth» обеих меток на их фактическую ширину и посмотреть, помогает ли это. Это параметр, который указывает этикетке, как расти вертикально. – matt
Хорошо, я видел это свойство в своих исследованиях, но не использовал его, потому что ширина моих меток также зависит от ширины супервизора. Что я должен надеть «preferredMaxLayoutWidth»? – raululm
Ну, прежде чем мы начнем с этого, давайте начнем с кода, который действительно работает. Код, который вы указали, совершенно бессмысленен, потому что вы не присвоили своим меткам значение 'numberOfLines'. Без этого они вообще не будут переворачиваться. Итак, позвольте мне дать вам возможность пересмотреть код кода, пока на самом деле не будет что-то, что можно было бы обернуть/расти, а затем мы сможем поговорить больше. И, пожалуйста, также дайте вашим ярлыкам какой-нибудь текст, чтобы мы могли увидеть, что-то действительно происходит. – matt