Что не так с отображением символов валют в iOS

в 9:57, , рубрики: iOS, ios development, objective-c, Блог компании Лайв Тайпинг, разработка под iOS

В июне 2016 года в App Store появилось разработанное нами приложение ИЛЬ ДЕ БОТЭ. Клиент попросил нас использовать шрифт Carisma. К системным шрифтам платформы iOS он не относится, что можно понять после попытки найти его здесь. Работая над приложением, я отметил, что символы валют, попадающие в диапазон от U+20B6 (символ турского ливра) до U+20BE (символ грузинского лари) и набранные шрифтом, не входящим в число системных, снижают производительность приложения. Символ рубля — как раз из указанного диапазона.

Найдите отличия:

Что не так с отображением символов валют в iOS - 1

Капитан выходит на связь

Экран справа лагает. Это заметно по показателю загруженности CPU.

Давайте-ка это обсудим.

Разберёмся подробнее, в каких именно ситуациях всё тормозит снижается производительность. Для этого разобьём представление строки с символом валюты на составные части:

  1. Для отображения используются следующие сущности: UILabel, UITextView и UITextField
  2. В этих сущностях используются обычная строка NSString и атрибутированная NSAttributedString
  3. Для строки мы можем получить символ рубля одним из трёх способов:
    1. Используя HTML:
      NSString *htmlString = @"<p>500 ₽</p> ";
      self.string = [[NSAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
      

    2. Используя unicode:
      self.string = [[NSAttributedString alloc] initWithString: @"500 u20BD"];
      

    3. Используя number formatter:
      NSNumberFormatter * numberFormatter = [[NSNumberFormatter alloc] init];
      [numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
      [numberFormatter setCurrencyCode:@"RUB"];
      [numberFormatter setMaximumFractionDigits:0];
      self.string = [[NSAttributedString alloc] initWithString:[numberFormatter stringFromNumber:@500]];
      

Начав комбинировать сущности, я обнаружил, что производительность снижают следующие сочетания:

  1. UILabel, тип строки: attributed, методы получения символа: 2 или 3
  2. UITextView, тип строки: любой, методы получения символа: любой
  3. UITextField, тип строки: любой, методы получения символа: любой

Эксперимент заключался в измерении нагрузки на процессор при пролистывании списка, элементы которого содержали символ рубля. Средняя нагрузка на процессор для нормального состояния не превышала 10%, а если была проблема, нагрузка колебалась в районе 30-80%, что можно видеть на гифках.

Чтобы приложение вело себя нормально, нужно избегать тех сочетаний, что я выявил, или использовать для символов валют системный шрифт San Francisco, а также шрифты из семейства Helvetica Neue. Но это минимальные требования. Истинная же причина увеличения нагрузки для меня осталась загадкой, и если кто-то разбирается в сути вопроса — делитесь соображениями в комментариях.

Автор: Лайв Тайпинг

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js