2013-06-16 8 views
6

я не уверен, что мои варианты для выполнения следующих действий:Динамические приписывал текст

enter image description here

текста красного цвета будет на самом деле визуализации в красном цвете, а также динамический - длина будет меняться.

Должен ли я использовать NSAttributedString и выяснить динамические индексы и длину для применения этого атрибута?

Или можно сделать каждое слово перед тире собственной этикеткой? (Я не уверен, что можно разместить несколько ярлыков в строке и каждый из них подталкивает остальных вправо по мере увеличения размера, вроде того, как работает плавающий в HTML/CSS)

+0

В настоящее время я делаю именно это в своем приложении, и я использую один «NSMutableAttributedString» и добавляю к нему атрибуты выделения. Единственный недостаток, который я заметил при таком подходе, заключается в том, что досадно точно рассчитать диапазон для добавления атрибутов, поскольку текст ярлыка может быть локализован и т. Д. – Greg

ответ

21

Лучший вариант - это, безусловно, сделать это с одной NSAttributedString в одной этикетке, потому что ваши другие варианты:

  1. Используйте несколько меток, изменить их кадры каждый раз, когда что-то меняется, перемещать их, точно выяснить, насколько широко пространство должно быть, сделать убедитесь, что они не слишком широки для экрана или вида, в котором они должны быть, и т. д. и т. д. Как вы можете видеть, это очень быстро станет очень болезненным.

  2. Перейдите наверх и используйте UIWebView, что явно переполняет отображение отдельной метки, поскольку оно дает вам все эти удивительные вещи, которые вам не нужны, например, прокрутка и масштабирование, а также JavaScript и прочее, и все эти функции используют циклы CPU, независимо от того, используете вы их или нет, так что это определенно не очень хороший вариант с точки зрения производительности, особенно если у вас будет большое количество таких (например, в каждой ячейке таблицы вид)

Принимая во внимание, если вы используете одну строку, все, что вам нужно сделать, это правильно рассчитать диапазоны для атрибутов, присвоить строку атрибутов для UILabel's attributedText (примечание, только iOS 6+, но, судя по тегам на ваш вопрос, это не проблема для вас), и все готово. В настоящее время я использую этот подход довольно широко во всем приложении, и он работает хорошо какое-то время (I сделал, попробовав два других, прежде чем уладить это, и им было очень больно работать).

Вот очень простой пример делать это, используя приписываемую строку:

UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 50, 300, 50)]; 
label.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:16.0]; 
[self.view addSubview:label]; 

NSString *category = @"Socks"; 
NSString *store = @"Apple Store"; 

NSMutableAttributedString *string = [[NSMutableAttributedString alloc] 
             initWithString:[NSString stringWithFormat: 
             @"in %@ at %@ — 1 day ago", 
              category, store]]; 

[string addAttribute:NSForegroundColorAttributeName 
       value:[UIColor redColor] 
       range:[string.string rangeOfString:category]]; 
[string addAttribute:NSForegroundColorAttributeName 
       value:[UIColor redColor] 
       range:[string.string rangeOfString:store]]; 

label.attributedText = string; 

Обратите внимание, что это не будет работать, как ожидается, если, например, значение store и category являются тот же, поскольку rangeOfString: найдет первое вхождение данной строки, что означает, что строка категории может быть выделена дважды, а строка хранилища - совсем не.

Лучше пример: Вот несколько более сложный пример, который не сломается из-за одинаковых строк, хотя и с дополнительным раздражением, чтобы вручную вычислять диапазоны:

NSString *in = @"in "; 
NSString *category = @"in"; 
NSString *at = @" at "; 
NSString *store = @"in"; 

NSString *text = [NSString stringWithFormat:@"%@%@%@%@ — 1 day ago", 
              in, category, at, store]; 
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] 
             initWithString:text]; 

[string addAttribute:NSForegroundColorAttributeName 
       value:[UIColor redColor] 
       range:NSMakeRange(in.length, category.length)]; 
[string addAttribute:NSForegroundColorAttributeName 
       value:[UIColor redColor] 
       range:NSMakeRange(in.length + category.length + at.length, 
           store.length)]; 

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

UPDATE: Просто добавив простой пример использования жирного шрифта, так что вам не придется искать его:

[string addAttribute:NSFontAttributeName 
       value:[UIFont fontWithName:@"HelveticaNeue-Bold" size:16.0] 
       range:NSMakeRange(in.length, category.length)]; 
[string addAttribute:NSFontAttributeName 
       value:[UIFont fontWithName:@"HelveticaNeue-Bold" size:16.0] 
       range:NSMakeRange(in.length + category.length + at.length, 
           store.length)]; 

Посмотрите на NSAttributedStringUIKit Additions Reference для более атрибутов что вы можете добавить в строку для достижения желаемого эффекта.

+1

Большое спасибо за объяснение всех возможностей, даже если они weren ' лучшие решения. –

+0

+1 для приятного и подробного ответа! – Paaske

Смежные вопросы