Я хотів би додати свої думки, оскільки у мене була точно така ж проблема.
Я використовував, UITextView
оскільки в ній було приємніше вирівнювання тексту (виправдати, яке на той момент було недоступне в UILabel
), але для того, щоб "імітувати" неінтерактивне-не прокручуване UILabel
, я б відключив повністю прокручування, підстрибування та взаємодію з користувачем .
Звичайно, проблема полягала в тому, що текст був динамічним, і хоча фіксується ширина, висоту слід перераховувати кожного разу, коли я встановлював би нове значення тексту.
boundingRectWithSize
Мені зовсім не вдалося, з того, що я міг бачити, UITextView
додав верхню частину поля, яка boundingRectWithSize
не піддавалася б підрахунку, отже, отримана висота boundingRectWithSize
була меншою, ніж повинна бути.
Оскільки текст не повинен був швидко оновлюватися, він використовується лише для деякої інформації, яка може оновлюватись кожні 2-3 секунди найбільше, я вирішив наступний підхід:
/* This f is nested in a custom UIView-inherited class that is built using xib file */
-(void) setTextAndAutoSize:(NSString*)text inTextView:(UITextView*)tv
{
CGFloat msgWidth = tv.frame.size.width; // get target's width
// Make "test" UITextView to calculate correct size
UITextView *temp = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, msgWidth, 300)]; // we set some height, really doesn't matter, just put some value like this one.
// Set all font and text related parameters to be exact as the ones in targeted text view
[temp setFont:tv.font];
[temp setTextAlignment:tv.textAlignment];
[temp setTextColor:tv.textColor];
[temp setText:text];
// Ask for size that fits :P
CGSize tv_size = [temp sizeThatFits:CGSizeMake(msgWidth, 300)];
// kill this "test" UITextView, it's purpose is over
[temp release];
temp = nil;
// apply calculated size. if calcualted width differs, I choose to ignore it anyway and use only height because I want to have width absolutely fixed to designed value
tv.frame = CGRectMake(tv.frame.origin.x, tv.frame.origin.y, msgWidth, tv_size.height );
}
* Наведений вище код не скопіюється безпосередньо з мого джерела, я мусив його відкоригувати / очистити від купки інших речей, не потрібних для цієї статті. Не приймайте його за код "копіювати-вставляй-і-працюй".
Очевидним недоліком є те, що він має розподіл та випуск для кожного дзвінка.
Але, перевага полягає в тому, що ви уникнете в залежності від сумісності між тим, як boundingRectWithSize малює текст і обчислив його розмір і реалізація тексту креслення в UITextView
(або UILabel
які також можна використовувати просто замінити UITextView
з UILabel
). Таким чином можна уникнути будь-яких «помилок» у Apple.
PS Здавалося б, вам не потрібна ця "темп", UITextView
а ви можете просто запитати sizeThatFits
безпосередньо у цілі, однак це не спрацювало для мене. Хоча логіка скаже, що вона повинна працювати, а розподіл / звільнення тимчасових UITextView
не потрібне, це не було. Але це рішення спрацювало бездоганно для будь-якого тексту, який я б задав.
lineBreakMode
?