将单击事件添加到ios NSString中的某些文本
我有以下代码,希望我的部分文本可以点击,并调用另一个UIViewController(而不是网站) NSMutableAttributeString设置为UILabel,如下所示:将单击事件添加到ios NSString中的某些文本,ios,iphone,uibutton,nsattributedstring,uitapgesturerecognizer,Ios,Iphone,Uibutton,Nsattributedstring,Uitapgesturerecognizer,我有以下代码,希望我的部分文本可以点击,并调用另一个UIViewController(而不是网站) NSMutableAttributeString设置为UILabel,如下所示: label.attributedText = str; 最好的方法是什么?我似乎找不到一个好答案 我想要的一个例子是假设我有一个这样的UILabel,带有以下文本: This is my label. Click here to go to UIViewController1 and then go to UIV
label.attributedText = str;
最好的方法是什么?我似乎找不到一个好答案
我想要的一个例子是假设我有一个这样的UILabel,带有以下文本:
This is my label. Click here to go to UIViewController1 and then go to UIViewController1 by this #tag.
我希望将文本“here”传递给第一个单击事件,并将单词“#tag”传递给同一个单击事件。如果使用值字段传递给目标,会怎么样
[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
(这要简单得多,我建议您改用它)
Swift
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!);
}
}
目标-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];
}
基本上,您需要添加一个手势识别器来获取文本视图中的点击点。然后,使用扩展区域中提供的category方法获取单词。之后,检查单词是什么(我们想要单词“here”的位置)。然后,我们收集您提供的hashtag
您只需添加一个performsguewithidentifier方法,并相应地传递它。Swift 3:
不要检查URL.scheme
属性。我的回答是零
这样做:
attributedString.addAttribute(NSLinkAttributeName,值:“openToViewController”,范围:范围)
然后使用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
}
除了@Nate Lee answer,还更新了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!)
}
}
看看这是否有帮助:还可以试试这个:为什么重复:?这里的重要部分是使用
UITextView
而不是UILabel
。。您可能需要调整textview的某些属性,使其更像一个普通标签,例如禁用编辑、选择和滚动。在.m文件中都可以,但请确保在.h文件中订阅UITextViewDelegate,以便首先调用该方法。如果我的viewcontroller中有手势,那么这是否有效?在属性文本中添加值时不要添加空格,否则shouldInteractWithURL将检测不到空格。如果你传递一个不包含任何URL的ant字符串值,然后比较URL.absoluteString而不是URL.schemeis有没有办法做到这一点,但是可以得到整行内容,而不仅仅是你点击的一个单词?我相信是这样,在let wordTarget=“here”中替换here
代码>改为一句话。我试了一下,但它不起作用。它只拾取一个单词,因此如果我必须在文本中输入相同的单词,它将无法分辨差异。textView.closestPositionToPoint(correctedPoint)始终返回零
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!)
}
}