2016-03-11 50 views
7

我想畫一個UITextView包括一些文本的內部可定製線(使用NSAttributedString繪製一個UITextView內的線路 - NSAttributedString

這裏就是我試圖

NSString *unicodeStr = [NSString stringWithFormat:@"%C%C%C", 0x00A0, 0x0009, 0x00A0]; //nbsp, tab, nbsp 
NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:unicodeStr]; 
NSRange strRange = NSMakeRange(0, str.length); 

NSMutableParagraphStyle *const tabStyle = [[NSMutableParagraphStyle alloc] init]; 
tabStyle.headIndent = 16; //padding on left and right edges 
tabStyle.firstLineHeadIndent = 16; 
tabStyle.tailIndent = -16; 
NSTextTab *listTab = [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentCenter location:40 options:@{}]; //this is how long I want the line to be 
tabStyle.tabStops = @[listTab]; 
[str addAttribute:NSParagraphStyleAttributeName value:tabStyle range:strRange]; 
[str addAttribute:NSStrikethroughStyleAttributeName value:[NSNumber numberWithInt:2] range:strRange]; 

但無論什麼樣的價值我提供製表位位置(在這種情況下爲40)和tailIndent(這裏爲-16),該行僅尊重headIndent並跨越整個UITextView寬度(當然不包括headIndent)。

編輯 - 我很確定這個問題是因爲我沒有使用正確的Unicode字符(雖然他們似乎是合乎邏輯的選擇)。如果這給了某人一個提示,如果我在第二個nbsp之後添加一個空格,即結束,則該選項卡被限制爲單個標籤長度

+0

你能提供一個你想讓文字看起來像什麼的例子嗎? –

+0

我試圖實施hr標籤(水平線)。從html轉換時,它們不受NSAttributedString支持 – lostInTransit

回答

2

它是您的預期結果嗎?

enter image description here enter image description here

你可以試試這個:

NSTextTab *listTab = [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentCenter location:self.textView.frame.size.width - tabStyle.firstLineHeadIndent + tabStyle.tailIndent options:@{}]; 

這是全碼:

- (void) viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 
    NSString *unicodeStr = @"\n\u00a0\t\t\n"; 
    NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:unicodeStr]; 
    NSRange strRange = NSMakeRange(0, str.length); 

    NSMutableParagraphStyle *const tabStyle = [[NSMutableParagraphStyle alloc] init]; 
    tabStyle.headIndent = 16; //padding on left and right edges 
    tabStyle.firstLineHeadIndent = 16; 
    tabStyle.tailIndent = -70; 
    NSTextTab *listTab = [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentCenter location:self.textView.frame.size.width - tabStyle.headIndent + tabStyle.tailIndent options:@{}]; //this is how long I want the line to be 
    tabStyle.tabStops = @[listTab]; 
    [str addAttribute:NSParagraphStyleAttributeName value:tabStyle range:strRange]; 
    [str addAttribute:NSStrikethroughStyleAttributeName value:[NSNumber numberWithInt:2] range:strRange]; 

    NSAttributedString *htmlStr = [[NSAttributedString alloc] initWithData:[@"<h1>Lorem ipsum dolor sit er elit lamet</h1>" dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil]; 

    [str insertAttributedString:htmlStr atIndex:0]; 
    [str appendAttributedString:htmlStr]; 

    self.textView.attributedText = str; 
} 
+0

已經完成,沒有工作。我很確定它與選項卡兩側的nbsp有關,但我不明白爲什麼 – lostInTransit

+0

這是我想要的 - 是的。但我有一些前後文本(html),似乎搞亂了橫向規則(我猜?)。代碼似乎與我所擁有的不一樣。不知道爲什麼它不適合我。 – lostInTransit

+0

,似乎工作!謝謝 – lostInTransit

0

這裏就是我所做的解決同樣的問題。它採用的NSTextTab一個子類:

import UIKit 

class RightAnchoredTextTab : NSTextTab { 
    weak var textContainer : NSTextContainer! 

    required init(textAlignment alignment: NSTextAlignment, location loc: CGFloat, options: [String : AnyObject], textContainer aTextContainer : NSTextContainer) { 
     super.init(textAlignment: alignment, location: loc, options: options) 
     textContainer = aTextContainer 
    } 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
    } 

    override var location: CGFloat { 
     get { 
      return textContainer.size.width-textContainer.lineFragmentPadding*2-super.location 
     } 
    } 
} 

與同類位相似的其他解決方案:

func horizontalLine(indent : CGFloat = 30, width : CGFloat = 1) -> NSAttributedString 
{ 
    let paragraphStyle = NSMutableParagraphStyle() 

    paragraphStyle.tabStops = [] 
    paragraphStyle.addTabStop(NSTextTab(textAlignment: .Left, location: indent, options: [:])) 
    paragraphStyle.addTabStop(RightAnchoredTextTab(textAlignment: .Right, location: indent, options: [:], textContainer : textView.textContainer)) 
    paragraphStyle.alignment = .Left 

    let attributes = [NSParagraphStyleAttributeName : paragraphStyle, NSStrikethroughStyleAttributeName : width] 

    textView.backgroundColor = UIColor.yellowColor() 
    let ZeroWidthNonBreakingSpace = "\u{FEFF}" 
    return NSAttributedString(string: "\t\(ZeroWidthNonBreakingSpace)\t\(ZeroWidthNonBreakingSpace)\n", attributes: attributes) 
} 

的幾個注意事項:

  • 它可能只用一個方形文字容器中工作。
  • NSTextContainer有一個lineFragmentPadding。如果您想知道爲什麼您必須將右對齊選項卡縮進10,則默認值爲5.
  • 在文本前加上\n表示不存在刪除線。不知道爲什麼。
  • 該解決方案適用於旋轉等,當UITextView再次調用NSTextTab.location時,邊界被改變。