2015-11-16 43 views
2

這是一個有趣的場景。我有以下的文本從服務器發送:是否有可能在UILabel/UITextView中添加一個UIButton?

我去上學#選項#

在iOS應用中,我必須把它轉換成:

我去上學[UIButton]

挑戰是測量以前的文字(「我去上學」)的長度,以設置位置(origin)的UIButton。這個問題將產生更多的問題,當UILabel有多條線路,以及UIButton多個外觀,如:

我去上學#選項#。 Lorem ipsum dolor坐在amet,consectetur adipiscing elit。 Phase f f,,mass mass mass mass,,,,el el el el el el el el el el el el el el cus cus cus cus cus cus cus cus cus cus主演mi tellus,在主播中擔任主持人,auctor laoreet愛神。 #選項# Quisque rhoncus ac mauris ac interdum。 Etiam aodio augue。 Mauris porttitor purus ac maximus faucibus。 Suspendisse velit felis,varius lobortis turpis venenatis,tempor placerat magna。在semper justo,ut pretium nunc中的整數。 Aliquam laoreet vehicula finibus。 #選項#

下面是我的一些解決方案,我能想到的:

方法1

NSString * testText = @"demo title"; 
CGSize stringSize = [testText sizeWithAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:17.0f]}]; 

這種方法可以測量單個文本行的大小,但對於多行文本,CGSize將不正確。

方法2

NSTextStorage *textStorage = [[NSTextStorage alloc] initWithString:@"hello"]; 
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init]; 
NSTextContainer *textContainer = [[NSTextContainer alloc] init]; 

[layoutManager addTextContainer:textContainer]; 
[textStorage addLayoutManager:layoutManager]; 

//Figure out the bounding rectangle 
NSRect stringRect = [layoutManager boundingRectForGlyphRange:NSMakeRange(0, [layoutManager numberOfGlyphs]) inTextContainer:textContainer]; 

這要複雜得多。 (仍然搞清楚如何建立佈局)

我的問題是:任何更簡單的方法來實現我的目標?

+2

請參閱http://stackoverflow.com/questions/21629784/make-a-clickable-link-in-an-nsattributedstring-for-a-uitextfield-or-uilabel瞭解一些想法。 – rmaddy

+0

很多想法都很好。謝謝。 – Raptor

+0

你真的需要在那裏放置一個UIButton嗎?如果您需要執行任何自定義操作,則可以使用屬性字符串打開具有自定義URL方案的URL,然後讓您的應用程序處理它。這會不會更順暢,更高效? –

回答

2

對於UITextView的:

NSMutableAttributedString * fullStringValue = [[NSMutableAttributedString alloc] initWithString:@"I go to school by option"]; 
NSRange range = [[fullStringValue string] rangeOfString:@"option"]; 

[fullStringValue addAttribute: NSLinkAttributeName value: @"http://www.EnterUrlHere.com" range: NSMakeRange(range.location, range.length)]; 
yourTextView.attributedText = fullStringValue; 

通過這種方式,你可以找到多個範圍和添加屬性。將UITextView的dataDetectorTypes值設置爲UIDataDetectorTypeLink或UIDataDetectorTypeAll以在單擊時打開URL。

爲的UILabel:

使用TTTAttributedLabel

用法明確解釋爲here

演示項目可用here

+0

謝謝。 'UITextView'演示有一些問題。 1.'NSMutableAttributedString'沒有'rangeOfString'; 2.最後一行的'str'沒有定義(可能它應該是'fullStringValue'); 3.它不能替換內容到'UIButton' – Raptor

+0

第二行應該是'[[fullStringValue string] rangeOfString:@「option」];' – Raptor

+1

感謝@Raptor讓我的答案無錯而且更有用。 – pkc456

0

@ vienvu的刪除答案是最接近通過利用YYText庫解決問題。

NSString *text = @"Test adding UIButton #option# inline"; 
NSMutableAttributedString *method2text = [[NSMutableAttributedString alloc] initWithString:text]; 
UIFont *font = [UIFont systemFontOfSize:20]; 
NSMutableAttributedString *attachment = nil; 

NSRange range = [[method2text string] rangeOfString:@"#option#"]; 
if(range.location != NSNotFound) { 
    UITextField *tf = [[UITextField alloc]initWithFrame:CGRectMake(0, 0, 100, 30)]; 
    tf.borderStyle = UITextBorderStyleRoundedRect; 
    attachment = [NSMutableAttributedString yy_attachmentStringWithContent:tf contentMode:UIViewContentModeBottom attachmentSize:tf.frame.size alignToFont:font alignment:YYTextVerticalAlignmentCenter]; 
    [method2text replaceCharactersInRange:range withString:@""]; 
    [method2text insertAttributedString:attachment atIndex:range.location]; 

} 

theLabel = [YYLabel new]; 
theLabel.userInteractionEnabled = YES; 
theLabel.numberOfLines = 0; 
theLabel.frame = CGRectMake(0, 100, 320, 320); 
theLabel.center = self.view.center; 
theLabel.attributedText = method2text; 
[self.view addSubview:theLabel]; 

其中theLabelYYLabel。我發現YYTextView無法選擇UI元素。類似的代碼也適用於UIButton

1

使用UITextView就可以解決你的問題,只需添加以下方法

-(void)addButtons{ 
    NSRange searchRange = NSMakeRange(0, [self.localTextView.text length]); 
    NSLog(@"%d", self.localTextView.text.length); 
    while(searchRange.location != NSNotFound){ 
     searchRange = [self.localTextView.text rangeOfString:@"#option#" options:NSCaseInsensitiveSearch range:searchRange]; 
     if (searchRange.location != NSNotFound) 
     { 
      NSLog(@"%d", searchRange.location); 
      UITextPosition *beginning = self.localTextView.beginningOfDocument; 
      UITextPosition *start = [self.localTextView positionFromPosition:beginning offset:searchRange.location]; 
      UITextPosition *end = [self.localTextView positionFromPosition:start offset:searchRange.length]; 
      UITextRange *range = [self.localTextView textRangeFromPosition:start toPosition:end]; 
      CGRect result1 = [self.localTextView firstRectForRange:range]; 
      NSLog(@"%f, %f", result1.origin.x, result1.origin.y); 

      UIButton* btn = [UIButton buttonWithType:UIButtonTypeCustom]; 
      [btn addTarget:self action:@selector(doAction:) forControlEvents:UIControlEventTouchUpInside]; 
      [btn setTitle:@"Click" forState:UIControlStateNormal]; 
      [btn setBackgroundColor:[UIColor blackColor]]; 
      [btn setFrame:result1]; 
      [self.localTextView addSubview:btn]; 

      searchRange = NSMakeRange(searchRange.location + searchRange.length, self.localTextView.text.length - (searchRange.location + searchRange.length)); 
     } 
    } 
} 

localTextView從分鏡取IBOutlet,最後乾脆叫[self addButtons];viewDidAppear

-(void)viewDidAppear:(BOOL)animated{ 
    [super viewDidAppear:animated]; 
    [self addButtons]; 
} 

設置按鈕的外觀和操作方法如你所願,我只是用一個標題做了一個黑色的背景。下面是我得到

enter image description here

0

使用的UIButton非常cumbersom輸出。我建議你檢查出UITextViewDelegate的兩種方法:

- textView:shouldInteractWithTextAttachment:inRange: 

- textView:shouldInteractWithURL:inRange: 

通過使用這兩個,你可以輕鬆地跟蹤這些用戶已經選定和基於文本/ URL竊聽你可以採取適當的行動。這具有允許您改變文本的字體/大小而不必擔心按鈕的定位的優點。

+0

我知道使用'UIButton'是很麻煩的。但設計師想要這樣做。感謝您的輸入 – Raptor

相關問題