Почему я не могу изменить рамку своего UILabel?

Я два дня пытался изменить фрейм UILabel, что нелепо ... UILabel - это IBOutlet, но это не причина, по которой он не работает: я пытался создать UILabel программно, но он все равно не работал ' т работать. Вот как я это делаю:

self.descriptionLabel.text = description;
self.descriptionLabel.lineBreakMode = NSLineBreakByWordWrapping;

CGSize textSize = [self.descriptionLabel.text sizeWithFont:[UIFont systemFontOfSize:12.0]
                                         constrainedToSize:CGSizeMake(self.descriptionLabel.frame.size.width, FLT_MAX)
                                             lineBreakMode:self.descriptionLabel.lineBreakMode];
CGFloat frameHeight = textSize.height;
CGRect frame = self.descriptionLabel.frame;
frame.size.height = frameHeight;
self.descriptionLabel.frame = frame;

CGRect bounds = self.descriptionLabel.frame;
bounds.origin.x = self.descriptionLabel.frame.origin.x + 10.0;
bounds.size.width = self.descriptionLabel.frame.size.width - 20.0;
self.descriptionLabel.bounds = bounds;
self.descriptionLabel.numberOfLines = 0;

Я уже спрашивал в IRC, и мне сказали, что нет причин, по которым фрейм не будет изменен ...

Я также попытался создать фрейм с CGRectMake и присвоить ему произвольное значение, но это тоже не помогло ..

Кто-нибудь знает, в чем может быть проблема, пожалуйста?

Редактировать 1: я записал кадр до и после и получил странные результаты:

Before: 0.000000 0.000000 0.000000 0.000000
After: 0.000000 0.000000 0.000000 33525.000000

Высота после того, как я установил рамку, - единственное значение, которое имеет смысл (у меня специально много текста на этикетке).

Редактировать 2: Я изменил код следующим образом, в журнале написано, что фрейм изменился, но на симуляторе он не изменился; Я доказал это, добавив красные границы к слою UILabel.

self.descriptionLabel.text = description;
self.descriptionLabel.lineBreakMode = NSLineBreakByWordWrapping;

CGSize textSize = [self.descriptionLabel.text sizeWithFont:[UIFont systemFontOfSize:12.0]
                                         constrainedToSize:CGSizeMake(self.view.frame.size.width, FLT_MAX)
                                             lineBreakMode:self.descriptionLabel.lineBreakMode];
CGFloat frameHeight = textSize.height;
CGRect frame = CGRectMake(0.0, 300.0, self.view.frame.size.width, frameHeight);
self.descriptionLabel.frame = frame;

DDLogInfo(@"After: %f %f %f %f", self.descriptionLabel.frame.origin.x, self.descriptionLabel.frame.origin.y, self.descriptionLabel.frame.size.width, self.descriptionLabel.frame.size.height);
// After: 0.000000 300.000000 320.000000 585.000000

self.descriptionLabel.numberOfLines = 0;
self.descriptionLabel.layer.borderColor = [UIColor redColor].CGColor;
self.descriptionLabel.layer.borderWidth = 2;

Доказательство


person Robert Audi    schedule 06.07.2013    source источник
comment
Вы регистрировали фрейм до и после? И почему вы меняете границы (в частности, используя фрейм, который находится в другом координатном пространстве)?   -  person Wain    schedule 06.07.2013
comment
Я зарегистрировал фрейм до и после, как вы предложили, и получил странные результаты, которые я включил в вопрос, который я отредактировал.   -  person Robert Audi    schedule 06.07.2013
comment
Почему вы устанавливаете количество строк на 0 в конце?   -  person Abizern    schedule 06.07.2013
comment
@Abizern Из того, что я читал, он делает количество строк динамическим или как вы хотите это назвать. Я нашел это на SO. Но в любом случае раскомментирование строки не решает проблемы.   -  person Robert Audi    schedule 06.07.2013


Ответы (2)


Если вы используете автоматический макет, вам не следует делать никаких настроек рамок - либо отключите автоматический макет, либо используйте ограничения для изменения размера вашей метки. Самый простой способ сделать это - задать для вашей метки ограничение по высоте (и ширину, если вам нужна постоянная ширина) в IB и сделать для него IBOutlet. Затем в коде измените постоянное значение этого ограничения на основе значения, полученного от sizeWithFont: constrainedToSize: lineBreakMode :.

person rdelmar    schedule 06.07.2013
comment
Сработало отлично. Не очевидно, как обновить ограничение. Вот как вы это делаете: self.labelWidthContraint.constant = size.width; self.labelHeightContraint.constant = size.height; - person ddiego; 29.09.2013
comment
Не совсем интуитивно понятно, но это прекрасно сработало - спасибо, мистер Дельмар! - person BonanzaDriver; 15.07.2014
comment
@rizzes, да, это так. Теперь вы должны использовать вместо него boundingRectWithSize: options: attributes: context:. - person rdelmar; 17.10.2014

У вашей метки в начале нулевой фрейм, поэтому, когда вы это сделаете:

CGSize textSize = [self.descriptionLabel.text sizeWithFont:[UIFont systemFontOfSize:12.0]
                                         constrainedToSize:CGSizeMake(self.descriptionLabel.frame.size.width, FLT_MAX)
                                             lineBreakMode:self.descriptionLabel.lineBreakMode];

Вы просите метод sizeWithFont сделать что-то практически невозможное - указать высоту, которая требуется, когда ширина не разрешена. Ответ, который он предоставляет (33525.000000), вероятно, является высотой, если в каждой строке разрешен один символ или что-то в этом роде.

Итак, либо установите ширину метки перед началом, либо предоставьте разрешенную ширину методу sizeWithFont, а затем установите размер метки, используя ответ (а не только высоту).

Также подумайте, что вы пытаетесь сделать, изменяя границы. Прокомментируйте этот код, по крайней мере, до тех пор, пока кадр не будет получен правильно, затем вы можете добавить его обратно и проверить, действительно ли он делает то, что вы хотите.

person Wain    schedule 06.07.2013
comment
Пожалуйста, посмотрите мою последнюю правку. Я последовал вашим предложениям, и в журнале фрейм изменился, но в симуляторе ничего не изменилось ... - person Robert Audi; 06.07.2013
comment
И это единственный имеющийся у вас код, который что-то делает с этикеткой? Где этот код (в каком методе он находится и когда он вызывается)? Какие правила автоматического изменения размера / макета у него есть? - person Wain; 06.07.2013
comment
Я добавил UILabel из IB и не коснулся ограничений автоматического макета. Вот полный файл, в котором находится этот код: gist.github.com/AzizLight/40b66b2daa2917952d6f Как видите, UILabel настроен в viewDidLoad, и на этом все ... - person Robert Audi; 06.07.2013