Откъде идва това вертикално разстояние в UILabelView?

Създавам изглед на iOS, който показва различни статични текстови елементи. Xib изглежда така:

въведете описание на изображението тук

Той използва четири етикета за заглавие, клеймо за време, основен текст и долен колонтитул. Всеки изглед е закотвен към родствения изглед над него вертикално и е закотвен отляво/вдясно на родителския изглед. Всички етикети имат фиксирана височина, с изключение на тялото, което има >= височина и броя на редовете, зададен на 0 с "пренасяне на думи" като стил на пренасяне на редове. Родителският изглед е UIScrollView.

На iPhone изглежда добре:

iPhone начало на превъртанекрай на превъртане на iPhone

На iPad обаче изглежда така:

iPad начало на превъртанекрай на превъртане на iPad

а? Откъде идва цялото това допълнително вертикално пространство в етикета на тялото? Xib и неговият контролер за изглед са идентични между iPhone и iPad (в момента няма персонализиран код за iPad). Открих, че вертикалното пространство е пряко свързано с това колко обвивания на редове изобразява етикетът. Ако няма обвиващи линии, няма допълнително вертикално пространство. Ако само няколко реда се обвиват, има малко допълнително вертикално пространство. Ако почти всеки ред се увива, добре, така изглежда.

Първо, някакви идеи защо UILabel се държи по този начин?

Второ, ако не мога да го накарам да спре да прави това, как мога да го заобиколя?

Вече пробвах няколко неща. Ако извикам [bodyLabel sizeToFit] в рамките на -viewDidLayoutSubViews, тогава той коригира етикета, но не коригира оформлението на нито един от родствените изгледи (напр. етикетът на долния колонтитул е заседнал в долната част на екрана, вместо да бъде изтеглен точно под тяло). Всички опити да накарате целия изглед да преоформи дъщерните си елементи след извикване на sizeToFit се игнорират. Също така се опитах да оразмеря UILabel чрез изчисляване на височина въз основа на шрифта, което води до същото поведение като -sizeToFit (макар и с повече код).

Замяната на Body UILabel с UITextView вместо това не ми създава странните проблеми с вертикалното разстояние, но трябва да изчисля височината на UITextView ръчно (използвайки изчисления на шрифтове) и нещо относно преоразмеряването на UITextView в рамките на родителския UIScrollView го прави така, че UIScrollView просто отказва да превърта (сякаш не знае, че съдържанието му е твърде голямо за неговите граници).

Така че в момента съм заседнал. Дори само обяснение защо UILabel се държи по този начин в оформлението на iPad би било полезно.


person Brandon    schedule 03.09.2013    source източник
comment
Използвате ли Autolayout или Springs and Struts?   -  person CoderPug    schedule 04.09.2013
comment
Използвам Autolayout. Мога да публикувам ограниченията, ако желаете. Опитах се да обясня съответните ограничения в първия параграф.   -  person Brandon    schedule 04.09.2013
comment
Виж ми, че проблемите са ограниченията, ако използването на [bodyLabel sizeToFit] провокира, че долният колонтитул заседна в долната част, тогава трябва да провериш ограниченията си, вероятно има едно, което да постави долния колонтитул в долната част и други, които карат етикета на тялото ти да се разтяга вертикално .   -  person CoderPug    schedule 04.09.2013
comment
В момента изглежда, че IB прекомерно ограничава долния колонтитул. Имам ляво и дясно ограничение за родителския изглед, горно ограничение между основния етикет и долния колонтитул и ограничение с фиксирана височина. Това трябва да е достатъчно за долния колонтитул, нали? Ляво, дясно, горе, височина. Въпреки това IB настоява да има долно ограничение между долния колонтитул и родителския изглед. В момента е зададено на Автоматично вместо на фиксирана стойност, но въпросът е, че не би трябвало да имам нужда от това ограничение. Въпреки това остава неотстраним. Някакви идеи?   -  person Brandon    schedule 04.09.2013
comment
Мисля, че проблемът с белите интервали също е нещо повече. Ако заменя текста lorum ipsum с, да речем, поредица от отделни изречения, които не се обвиват, проблемът с белите интервали изчезва. UILabel изглежда добавя празно пространство в пряка пропорция на това колко често обвива текстов ред. Без обвит текст, без допълнително пространство (дори ако текстът все още е висок стотици редове). Това поведение не се влияе от промяната на поведението на пренасяне на линия.   -  person Brandon    schedule 04.09.2013
comment
долно ограничение между долния колонтитул и родителския изглед Мисля, че ограниченията са проблемът, опитайте се да поставите второстепенен приоритет на този, също така, ако имате зададена връзка на „Равно“, променете я на „ Вместо това „По-голямо или равно“. Надявам се това да помогне   -  person CoderPug    schedule 04.09.2013
comment
За съжаление всяка промяна на това ограничение принуждава IB да добави отново и първоначалното статично ограничение. Така че сега имам две долни ограничения на долния колонтитул, едното от които не мога да променя. IB смята, че този етикет е недостатъчно ограничен по някаква причина, но не мога да си представя защо. Посочвам горе, ляво, дясно и височина! Няма нищо неуточнено! Очевидно autolayout вярва в противен случай, но не мога да разбера как да го заобиколя.   -  person Brandon    schedule 05.09.2013


Отговори (2)


Основният проблем е, че методът за автоматично преоразмеряване на текста във вашия етикет е неуспешен, защото в iPad вашият етикет няма зададена ширина от самото начало, тя се изчислява по време на изпълнение и това е източникът на тази бъркотия. На iPhone, тъй като вашият етикет има зададена ширина (на IB), няма проблеми.

Има два начина за решаване на проблема:

  1. Имате два сценария: един за iPhone и един за iPad

    Правейки това, вашият етикет ще знае ширината си от самото начало и просто ще работи като на iPhone. въведете описание на изображението тук

  2. Имате само една Storyboard за iPhone и iPad

    Можете да заобиколите проблема, като изчислите размера, който най-добре пасва на неговия текст и с този резултат добавите ограничение на височината чрез код към етикета. За да изчислите желания размер, можете да изчислите ширината с тази формула: Current View's width - (Leading space + Trailing Space). Ето моят код

CGSize desiredSize = [_bodyLabel sizeThatFits:CGSizeMake(self.view.frame.size.width-40, 10)];
NSString *visualContraint = [NSString stringWithFormat:@"V:[_bodyLabel(%.0f)]",desiredSize.height];
[_bodyLabel addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:visualContraint
                                                                   options:NSLayoutFormatDirectionLeadingToTrailing
                                                                   metrics:nil
                                                                     views:NSDictionaryOfVariableBindings(_bodyLabel)]];

въведете описание на изображението тук

objective-c

person CoderPug    schedule 05.09.2013

В случай, че някой друг се сблъска със същия проблем, използвайки автоматично оформление... Може би съм успял да разреша същия проблем, като създам ограничение, както предлага Coche, но разбрах, че имам preferredMaxLayoutWidth, който е твърде малък, зададен в uilabel. След като зададох точно preferredMaxLayoutWidth (действителната ширина на етикета), разстоянието отгоре и отдолу изчезна.

person ccwasden    schedule 03.04.2014
comment
Това е правилният/предпочитан отговор IMHO. Не изисква заобиколен код (колкото по-малко UI код, толкова по-добре при преминаване към Auto-Layout + IB маршрут). Това реши проблема ми. - person Form; 10.11.2015