将click事件添加到ios NSString中的某些文本

我有以下代码,并希望使我的文本的一部分可以点击并调用另一个UIViewController(而不是一个网站)。

NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:@"testing it out @clickhere"]; NSInteger length = str.length; [str addAttribute:NSForegroundColorAttributeName value:[UIColor bestTextColor] range:NSMakeRange(0,length)]; 

NSMutableAttributedString被设置为UILabel,如下所示:

 label.attributedText = str; 

什么是最好的方法呢? 我似乎无法找到一个好的答案。

我想要的一个例子是假设我有一个UILabel,如下所示:

 This is my label. Click here to go to UIViewController1 and then go to UIViewController1 by this #tag. 

我希望第一次单击事件传递“here”文本,并将“#tag”一词传递给同一个click事件。

如果您使用值字段传入目的地该怎么办?

 [attributedString addAttribute:NSLinkAttributeName value:[@"destinationController1" stringByAppendingString:username] range:range]; 

然后覆盖委托方法:

 - (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange { if ([URL.scheme isEqualToString:@"destinationController1"]) { // Launch View controller return NO; } return YES; } 

我的解决方案需要使用UITextView (这非常简单,我敦促您使用它)。

迅速

 class ViewController: UIViewController { @IBOutlet weak var textView:UITextView!; override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let gestureRecognizer = UITapGestureRecognizer(target: self, action: "textViewTapped:"); gestureRecognizer.numberOfTapsRequired = 1; gestureRecognizer.numberOfTouchesRequired = 1; self.textView.addGestureRecognizer(gestureRecognizer); } func textViewTapped(sender: UITapGestureRecognizer) { let wordTarget = "here"; let word = UITextView.getWordAtPosition(sender.locationInView(self.textView), textView: self.textView); if word == wordTarget { let plainString = self.textView.attributedText.string; let substrings = NSMutableArray(); let scanner = NSScanner(string: plainString); scanner.scanUpToString("#", intoString: nil); while !scanner.atEnd { var substring:NSString? = nil; scanner.scanString("#", intoString: nil); let space = " "; if scanner.scanUpToString(space, intoString: &substring) { // If the space immediately followed the #, this will be skipped substrings.addObject(substring!); } scanner.scanUpToString("#", intoString: nil); //Scan all characters before next # } println(substrings.description); //Now you got your substrings in an array, so use those for your data passing (in a segue maybe?) ... } } } extension UITextView { class func getWordAtPosition(position: CGPoint!, textView: UITextView!) -> String? { //Remove scrolloffset let correctedPoint = CGPointMake(position.x, textView.contentOffset.y + position.y); //Get location in text from uitextposition at a certian point let tapPosition = textView.closestPositionToPoint(correctedPoint); //Get word at the position, will return nil if its empty. let wordRange = textView.tokenizer.rangeEnclosingPosition(tapPosition, withGranularity: UITextGranularity.Word, inDirection: UITextLayoutDirection.Right.rawValue); return textView.textInRange(wordRange!); } } 

Objective-C的

 - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(textViewTapped:)]; gestureRecognizer.numberOfTouchesRequired = 1; gestureRecognizer.numberOfTapsRequired = 1; [self.textView addGestureRecognizer:gestureRecognizer]; } - (void)textViewTapped:(UITapGestureRecognizer *)sender { NSString *wordTarget = @"here"; NSString* word = [self getWordAtPosition:[sender locationInView:self.textView] textView:self.textView]; if ([word isEqualToString:wordTarget]) { NSString *plainString = self.textView.attributedText.string; NSMutableArray* substrings = [[NSMutableArray alloc]init]; NSScanner *scanner = [[NSScanner alloc]initWithString:plainString]; [scanner scanUpToString:@"#" intoString:nil]; while (![scanner isAtEnd]) { NSString* substring = nil; [scanner scanString:@"#" intoString:nil]; NSString* space = @" "; if ([scanner scanUpToString:space intoString:&substring]) { [substrings addObject:substring]; } [scanner scanUpToString:@"#" intoString:nil]; } //Now you got your substrings in an array, so use those for your data passing (in a segue maybe?) ... } } - (NSString*)getWordAtPosition:(CGPoint)position textView:(UITextView *)textView { //remove scrollOffset CGPoint correctedPoint = CGPointMake(position.x, textView.contentOffset.y + position.y); UITextPosition *tapPosition = [textView closestPositionToPoint:correctedPoint]; UITextRange *wordRange = [textView.tokenizer rangeEnclosingPosition:tapPosition withGranularity:UITextGranularityWord inDirection:UITextLayoutDirectionRight]; return [textView textInRange:wordRange]; } 

基本上,您需要添加手势识别器才能获得textview中的分接点。 然后,您可以使用扩展区域中提供的类别方法获取单词。 之后,你检查这个词是什么(我们想要“这里”这个词)。 然后,我们收集您提供的主题标签。

您所要做的就是添加performSegueWithIdentifier方法,并相应地传递它。

除了@Nate Lee的回答,更新了Swift 4.0版本的扩展:

 extension UITextView { class func getWordAtPosition(position: CGPoint!, textView: UITextView!) -> String? { //Remove scrolloffset let correctedPoint = CGPoint(x: position.x, y: (textView.contentOffset.y + position.y)) //Get location in text from uitextposition at a certian point let tapPosition = textView.closestPosition(to: correctedPoint) //Get word at the position, will return nil if its empty. let wordRange = textView.tokenizer.rangeEnclosingPosition(tapPosition!, with: .word, inDirection: UITextLayoutDirection.right.rawValue) return textView.text(in: wordRange!) } } 

斯威夫特3:

不要检查URL.scheme属性。 我没有回来。

做这个:

attributedString.addAttribute(NSLinkAttributeName, value: "openToViewController", range: range)

然后使用URL上的absoluteString属性将该值检查到您选择的视图:

  func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool{ if (URL.absoluteString == "openToViewController") { let viewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewController") as! UIViewController self.present(viewController, animated: true, completion: nil) return false } return true }