создать атрибутную строку из простого (Android-форматированного) текста в swift для iOS

Я читаю строки из Localizable.strings, который содержит что-то вроде того, что в основном есть у вас в файле strings.xml приложения для Android

"testShort" = "A <b>short</b>\ntest with another<b>bold text</b>"; 

Жирный и строковый фид – это только два атрибута форматирования, которые у меня есть в моих текстах. Я пытаюсь разработать такой метод в течение нескольких дней без успеха:

 func ConvertText(inputText: String) -> NSAttributedString { // here comes the conversion to a representation with Helvetica 14pt and Helvetica-Bold 14pt including line feeds. } 

Моя конечная цель – отобразить текст в атрибуте UITextView.

Будучи совершенно новым для Swift и iOS, не зная Objective-C, мне было очень сложно делать манипуляции с String, поскольку они совершенно разные и сложные, и все примеры находятся в Objective-C. Что еще более усложняет, так это то, что большинство методов API недоступны или отличаются в Swift, чем в Objective-C …

Вот что я пробовал до сих пор для тела метода с помощью множества других сообщений здесь:

 var test = inputText.dataUsingEncoding(NSUnicodeStringEncoding, allowLossyConversion: true)! attrStr = NSAttributedString( data: test, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil, error: nil)! return attrStr 

Основные проблемы здесь в том, что \n не конвертируется, а шрифт очень мал и отличается.

Затем я попытался вручную выделить часть текста. Кажется, он работает так:

 var newText = NSMutableAttributedString(string: inputText) newText.addAttribute(NSFontAttributeName, value: UIFont(name: "Helvetica-Bold", size: 14.0)!, range: NSRange(location:2,length:4)) 

Теперь я попытался найти атрибуты в тексте, удалив их и используя addAttribute, вроде этого

 // Start of bold text var range = newText.rangeOfString("<b>")! // End of bold text var range2 = newText.rangeOfString("</b>")! // replacing attributes newText = newText.stringByReplacingCharactersInRange(range, withString: "") newText = newText.stringByReplacingCharactersInRange(range2, withString: "") // creating a range for bold => error "'String.Index' is not convertible to 'int'" // how to do such a thing var boldRange = NSMakeRange(range.startIndex, range2.endIndex -3) // setting bold newText.addAttribute(NSFontAttributeName, value: UIFont(name: "Helvetica-Bold", size: 14.0)!, range: boldRange) 

Весь этот диапазон – моя главная проблема на данный момент, поскольку она совершенно отличается от простой позиции в строке.

Эта проблема является отличным примером отсутствия (или хорошо скрытой) документации:

addAttribute хочет NSRange, rangeOfString кажется, доставляет общий Range в соответствии с сообщением об ошибке, которое я получаю, но информации об этом нет. Кнопка «Поиск документации» в Xcode на rangeOfString() приводит к NSString. Поиск там rangeOfString() говорит, что он возвращает NSRange . Нажатие на это приводит к информации о псевдониме типа для _NSRange который, в свою очередь, имеет два свойства NSUInteger с именем location и length . Где свойство startIndex и endIndex, которое я вижу в XCode? Очень смущает …

Было бы здорово, если бы вы могли дать мне некоторые фрагменты или подсказки, где я ошибаюсь здесь или даже тело метода, поскольку я все еще надеюсь, что это не слишком сложно, если вы хорошо знаете iOS и Swift. Я нацелен на поддержку iOS 7.1, но, если его проще с iOS 8, это тоже хорошо.

One Solution collect form web for “создать атрибутную строку из простого (Android-форматированного) текста в swift для iOS”

Что касается вашего первого метода с NSAttributedString :

  • Символом \n в HTML является просто обычное пустое пространство. Чтобы получить разрыв строки, вы должны сначала заменить его на <br /> .
  • Атрибуты шрифта можно контролировать с помощью HTML <span> , см. Раздел «Анализ HTML в NSAttributedText» – как установить шрифт? ,

Это дает (теперь обновляется для Swift 2):

 func convertText(inputText: String) -> NSAttributedString { var html = inputText // Replace newline character by HTML line break while let range = html.rangeOfString("\n") { html.replaceRange(range, with: "<br />") } // Embed in a <span> for font attributes: html = "<span style=\"font-family: Helvetica; font-size:14pt;\">" + html + "</span>" let data = html.dataUsingEncoding(NSUnicodeStringEncoding, allowLossyConversion: true)! let attrStr = try? NSAttributedString( data: data, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil) return attrStr! } 

Что касается вашего второго метода:

Существует два разных rangeOfString() , один для String (Swift) и один для (Foundation) NSString . Метод String возвращает Range<String.Index> а метод NSString возвращает NSRange .

Преобразование между этими двумя возможно, но сложное. Причина в том, что в String каждый «расширенный кластер grapheme» считается одним символом, тогда как в NSString подсчитывается каждый блок UTF-16. Расширенным кластером графем может быть один или несколько единиц UTF-16 («😄» – это два блока UTF-16, «🇩🇪» – четыре).

Метод addAttribute() принимает только NSRange . Самый простой способ решить эту проблему – преобразовать строку Swift в NSString и работать только с NSRange . Тогда ваш метод может выглядеть так:

 func convertText(inputText: String) -> NSAttributedString { let attrString = NSMutableAttributedString(string: inputText) let boldFont = UIFont(name: "Helvetica-Bold", size: 14.0)! var r1 = (attrString.string as NSString).rangeOfString("<b>") while r1.location != NSNotFound { let r2 = (attrString.string as NSString).rangeOfString("</b>") if r2.location != NSNotFound && r2.location > r1.location { let r3 = NSMakeRange(r1.location + r1.length, r2.location - r1.location - r1.length) attrString.addAttribute(NSFontAttributeName, value: boldFont, range: r3) attrString.replaceCharactersInRange(r2, withString: "") attrString.replaceCharactersInRange(r1, withString: "") } else { break } r1 = (attrString.string as NSString).rangeOfString("<b>") } return attrString } 
  • как заставить xcode запускать скрипт перед зависимостями?
  • Как сделать анимированную кнопку в Apple WatchKit?
  • Спиновая бутылка с UIGestureRecognizer
  • Xcode генерирует png форму pdf с разными цветами
  • Стиль стиля машины
  • Блокировка кода кода
  • Как использовать функцию выделения в Swift?
  • Принудительный просмотр камеры в ландшафте с блокировкой ориентации
  • Xcode 6 Beta 4: Использование неразрешенного идентификатора 'NSFetchedResultsChangeInsert'
  • Когда я загружаю новый вид в Cocoa Touch, он сдвигает все примерно на 20 пикселей
  • Раскадранты и наконечники совместимы?
  • Interesting Posts

    Обработка ошибок с помощью Alamofire в Swift 2

    Получите MAC-адрес периферийного устройства с низкой энергией bluetooth

    Как изменить текст в нескольких ярлыках при нажатии специальной ячейки представления таблицы?

    Как сделать видео с уменьшенным размером с помощью AVAssetWriter?

    Создать потокобезопасный массив в быстром

    Проекты не запускаются в iOS при добавлении XSuperObject

    Кнопки ввода стилей для iPad и iPhone

    Возврат из только пейзажного вида в портфолио

    Цвет фона и закругленные углы NSAttributedString

    Как iPhone узнает новые местоположения Wi-Fi с точки зрения их использования для оценки местоположения

    в моем контроллере view я добавляю subview, у которого есть xib, я устанавливаю автозапуск в xib, но когда я добавляю представление в контроллер представления, он не работает

    Утечка обнаруживается при представлении UIImagePickerController

    найти подходящую должность в iOS

    Как элементы UI в iOS обновляться из цикла без потоков?

    Медленная работа Scenekit

    PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.