2017-01-31 7 views
1

У меня есть контроллер просмотра, содержащий UITextView. Этот UITextView получает текст, обновляемый программно, в зависимости от модели данных, контролирующей его (около 30 различных текстовых опций). Содержимое в UITextView всегда будет довольно длинным, примерно по 450 слов каждый. Пункты будут варьироваться от 2 до 5.Добавление заголовков параграфов программно в UITextView

Все работает отлично. Мне просто нужен визуальный способ разбить абзацы. Прямо сейчас, я использую \ n \ n, чтобы создать пару разрывов строк между абзацами. Хотя это работает, мне в конечном итоге нужны заголовки.

В IB я изменил свойство text из Plain в Attributed. Это позволяет мне изменять текст в стиле WYSIWYG прямо в Xcode. Отлично работает, но я не использую IB для изменения текста.

Я попытался использовать WebView (код ниже). Я создал чрезвычайно простой HTML-файл с тегами H1 и P. Это, к сожалению, создаст 30+ HTML-файлов в моем проекте. Мне это не нравится с точки зрения управляемости. Текст также не может быть выбором, который он с WebView (я не хочу прибегать к CSS [-webkit-пользователю выберите], чтобы смягчить эту проблему.)

let path: String? = Bundle.main.path(forResource: "myHTML", ofType: "html") 
    let file = try? String(contentsOfFile: path!, encoding: String.Encoding.utf8) 
    let baseURL = URL(fileURLWithPath: Bundle.main.bundlePath) 
    self.myWebView.loadHTMLString(file!, baseURL: baseURL) 

Моего идеальным решением

Могу ли я придерживаться моей текущей настройки? Программное изменение текста UITextView с моей моделью данных, если вы можете изменить текстовые атрибуты в коде для создания заголовков абзацев?

This is my current UI without any attributed text This is my ultimate end-goal

Edit - Попытка заставить это работать с MVC

allFormattedDescriptions: [ 
Formatted(heading: "heading 1", descriptionText: "Lorem Ipsum Paragraph 1"), 
Formatted(heading: "heading 2", descriptionText: "Lorem Ipsum Paragraph 2"), 
Formatted(heading: "heading 3", descriptionText: "Lorem Ipsum Paragraph 3") 
] 
// Ideal formatting; every paragraph will have a heading. Can handle that with one object that requires both a heading and description text (paragraph). 

struct Formatted { 

var heading: String! 
var descriptionText: String! 

var bodyParagraphStyle: NSMutableParagraphStyle = { 
    let style = NSMutableParagraphStyle() 
    style.lineSpacing = 10 
    style.paragraphSpacingBefore = 6 
    style.paragraphSpacing = 6 
    return style 
}() 

var headerParagraphStyle: NSMutableParagraphStyle = { 
    let style = NSMutableParagraphStyle() 
    style.paragraphSpacingBefore = 24 
    return style 
}() 

var bodyAttributes: [String: AnyObject]! 
var headerAttributes: [String: AnyObject]! 

} 
+0

ли вид текста для редактирования? – AdamPro13

+0

Вы можете определенно сделать это в коде. 'NSMutableAttributedString' позволяет вам добавлять и удалять атрибуты по своему усмотрению. Вы также можете использовать его для отображения HTML. Если вам не нужно отображать HTML, вы можете вызвать 'enumerateAttributesInRange', чтобы получить все атрибуты и изменить их. Или вы можете просто называть' addAttributes' или 'setAttributes' для установки различных стилей. Это включает в себя стили и отступы абзаца, рамки строк, цвета, подчеркивание, зачеркивание, шрифт и т. Д. – Brandon

+0

Я не понимаю, чего вы хотите. Можете ли вы предоставить макет? –

ответ

3

Использование NS(Mutable)ParagraphStyle и NS(Mutable)AttributedString. Например:

class ViewController: UIViewController { 
    @IBOutlet weak var textView: UITextView! 

    var allFormattedDescriptions = [ 
     Formatted(heading: "Introduction to Bacon Ipsum", descriptionText: "Bacon ipsum dolor amet jerky pig pastrami capicola biltong turkey, ball tip fatback andouille porchetta flank swine brisket bacon pork loin. Tongue shank cupim, pastrami spare ribs meatball drumstick pork pork chop. Sirloin flank tenderloin bresaola doner, cupim ribeye drumstick ham hock t-bone pork short ribs shoulder. Fatback ribeye pastrami pancetta, chuck turkey andouille boudin burgdoggen shoulder tongue kielbasa doner shankle turducken. Rump strip steak drumstick, shankle cupim prosciutto jerky bacon doner. Pork chop jowl burgdoggen, cow turkey ball tip doner. Cow ham meatball chuck flank meatloaf prosciutto."), 
     Formatted(heading: "Kielbasa?", descriptionText: "Spare ribs boudin ham leberkas landjaeger filet mignon. Short loin fatback hamburger leberkas chicken. Frankfurter chuck short ribs ball tip, ground round cupim shank brisket venison turducken boudin. Pig sirloin pork loin meatloaf short loin turkey swine.") 
    ] 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     let textContent = NSMutableAttributedString() 
     for (index, desc) in allFormattedDescriptions.enumerated() { 
      let includeLinebreak = index < allFormattedDescriptions.count - 1 
      textContent.append(desc.attributeString(includeLineBreak: includeLinebreak)) 
     } 
     textView.attributedText = textContent 
    } 
} 

struct Formatted { 
    var heading: String 
    var descriptionText: String 

    var bodyParagraphStyle: NSMutableParagraphStyle = { 
     let style = NSMutableParagraphStyle() 
     style.lineSpacing = 10 
     style.paragraphSpacingBefore = 6 
     style.paragraphSpacing = 6 
     return style 
    }() 

    var headerParagraphStyle: NSMutableParagraphStyle = { 
     let style = NSMutableParagraphStyle() 
     style.paragraphSpacingBefore = 24 
     return style 
    }() 

    var bodyAttributes: [String: AnyObject] 
    var headerAttributes: [String: AnyObject] 

    func attributeString(includeLineBreak: Bool = true) -> NSAttributedString { 
     let result = NSMutableAttributedString() 
     result.append(NSAttributedString(string: self.heading + "\n", attributes: self.headerAttributes)) 
     result.append(NSAttributedString(string: self.descriptionText, attributes: self.bodyAttributes)) 
     if includeLineBreak { 
      result.append(NSAttributedString(string: "\n", attributes: self.bodyAttributes)) 
     } 

     return result as NSAttributedString 
    } 

    init(heading: String, descriptionText: String) { 
     self.heading = heading 
     self.descriptionText = descriptionText 
     self.bodyAttributes = [ 
      NSFontAttributeName: UIFont(name: "Hoefler Text", size: 14)!, 
      NSParagraphStyleAttributeName: bodyParagraphStyle 
     ] 
     self.headerAttributes = [ 
      NSFontAttributeName: UIFont(name: "Avenir", size: 22)!, 
      NSParagraphStyleAttributeName: headerParagraphStyle, 
      NSForegroundColorAttributeName: UIColor.red 
     ] 
    } 
} 

Результат:

Formatted text

+1

Это очень приятно. Мне нравится, как вы разделили атрибуты тела и абзаца. Я пытаюсь разделить это на MVC, но с трудным временем. Я просто хочу, чтобы модель обрабатывала ввод текста заголовка и абзаца. В моем исходном сообщении есть небольшое редактирование, чтобы показать путь, по которому я пытаюсь уйти. Любые дальнейшие рекомендации будут очень оценены. – Joe

+0

См. Мой отредактированный ответ –

+1

Mmmmmm, Kielbasa. – matt