向 UILabel 的一部分添加点击手势
Add a tap gesture to a part of a UILabel
我有一个像这样的 NSAttributedString:
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;
如何针对上面字符串中的单词“@clickhere”向另一个 viewcontroller 做出点击手势(或可点击的东西)?
谢谢!
只需先向您的标签添加一个手势
[label setUserInteractionEnabled:YES];
UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
[label addGestureRecognizer:gesture];
用下面的方法控制你的手势区域
- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer
{
static CGRect touchableRect = CGRectMake(100.0f, 0.0f, 100.0f, 50.0f); // Give your rect as you need.
CGPoint touchPoint = [gestureRecognizer locationInView:self.view];
if (CGRectContainsPoint(touchableRect, touchPoint))
{
//User has tap on where you want. Do your other stuff here
}
}
我认为,最好的方法是将 UIGestureRecognizer
添加到您的 UILabel
并验证您想要的框架。
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
[_yourLabel addGestureRecognizer:singleTap];
- (void)handleTap:(UITapGestureRecognizer *)tapRecognizer
{
CGPoint touchPoint = [tapRecognizer locationInView: _yourLabel];
//Modify the validFrame that you would like to enable the touch
//or get the frame from _yourLabel using the NSMutableAttributedString, if possible
CGRect validFrame = CGRectMake(0, 0, 300, 44);
if(YES == CGRectContainsPoint(validFrame, touchPoint)
{
//Handle here.
}
}
UITapGestureRecognizer *Tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapDetected)];
Tap.numberOfTapsRequired = 1;
// label Name Is your Label Name
[labelName addGestureRecognizer:Tap];
-(void)tapDetected
{
//your code
}
我想补充一下 Ramshad 的回答,关于如何处理有效框架。
为此,您可能要考虑使用 UITextView 而不是 UILabel,这不会让您访问它如何管理文本布局。通过禁用编辑、选择和滚动,UITextView 的行为与 UILabel 大致相同,除了您必须删除的一些填充。
为方便起见,您可能需要向 UITextView 添加一个小类别,在其中编写一个方法来测试某个点是否触及范围内的任何字符。
- (BOOL)point:(CGPoint)point touchesSomeCharacterInRange:(NSRange)range
{
NSRange glyphRange = [self.layoutManager glyphRangeForCharacterRange:range actualCharacterRange:NULL];
BOOL touches = NO;
for (NSUInteger index = glyphRange.location; index < glyphRange.location + glyphRange.length; index++) {
CGRect rectForGlyphInContainer = [self.layoutManager boundingRectForGlyphRange:NSMakeRange(index, 1) inTextContainer:self.textContainer];
CGRect rectForGlyphInTextView = CGRectOffset(rectForGlyphInContainer, self.textContainerInset.left, self.textContainerInset.top);
if (CGRectContainsPoint(rectForGlyphInTextView, point)) {
touches = YES;
break;
}
}
return touches;
}
这也适用于包含多个单词的文本片段,这些单词由于自动换行而分布在多行中。当我们处理打印的字形时,它也适用于本地化文本。
想法与接受的答案相同。这是 Swift.
中的方法
假设您已经设置好标签。
youLabel.text = "please tab me!"
将 tapGestuerRecognizer 添加到您的标签中
let tap = UITapGestureRecognizer(target: self, action: #selector(tapAction))
yourLabel.addGestureRecognizer(tap)
对String添加String
扩展方法计算字符串rect
extension String {
func rect(font: UIFont) -> CGRect {
let label = UILabel(frame: .zero)
label.font = font
label.text = self
label.sizeToFit()
return label.frame
}
}
计算点击手势的可用点击矩形。
let pleaseStringRect = "please".rect(font: yourFont)
let tapStringRect = "tap".rect(font: yourFont)
let tapAreaRect = CGRect(x: pleaseStringRect.width, y: tapStringRect.origin.y, width: tapStringRect.width, height: tapStringRect.height"
在行动中随心所欲
@objc private func tapAction(tap: UITapGestureRecognizer) {
let position = tap.location(in: content)
guard reporterFirstNameRect.contains(position) else {
return
}
// Do the tap action stuff
}
就是这样,编码愉快。
我有一个像这样的 NSAttributedString:
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;
如何针对上面字符串中的单词“@clickhere”向另一个 viewcontroller 做出点击手势(或可点击的东西)?
谢谢!
只需先向您的标签添加一个手势
[label setUserInteractionEnabled:YES];
UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
[label addGestureRecognizer:gesture];
用下面的方法控制你的手势区域
- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer
{
static CGRect touchableRect = CGRectMake(100.0f, 0.0f, 100.0f, 50.0f); // Give your rect as you need.
CGPoint touchPoint = [gestureRecognizer locationInView:self.view];
if (CGRectContainsPoint(touchableRect, touchPoint))
{
//User has tap on where you want. Do your other stuff here
}
}
我认为,最好的方法是将 UIGestureRecognizer
添加到您的 UILabel
并验证您想要的框架。
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
[_yourLabel addGestureRecognizer:singleTap];
- (void)handleTap:(UITapGestureRecognizer *)tapRecognizer
{
CGPoint touchPoint = [tapRecognizer locationInView: _yourLabel];
//Modify the validFrame that you would like to enable the touch
//or get the frame from _yourLabel using the NSMutableAttributedString, if possible
CGRect validFrame = CGRectMake(0, 0, 300, 44);
if(YES == CGRectContainsPoint(validFrame, touchPoint)
{
//Handle here.
}
}
UITapGestureRecognizer *Tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapDetected)];
Tap.numberOfTapsRequired = 1;
// label Name Is your Label Name
[labelName addGestureRecognizer:Tap];
-(void)tapDetected
{
//your code
}
我想补充一下 Ramshad 的回答,关于如何处理有效框架。
为此,您可能要考虑使用 UITextView 而不是 UILabel,这不会让您访问它如何管理文本布局。通过禁用编辑、选择和滚动,UITextView 的行为与 UILabel 大致相同,除了您必须删除的一些填充。
为方便起见,您可能需要向 UITextView 添加一个小类别,在其中编写一个方法来测试某个点是否触及范围内的任何字符。
- (BOOL)point:(CGPoint)point touchesSomeCharacterInRange:(NSRange)range
{
NSRange glyphRange = [self.layoutManager glyphRangeForCharacterRange:range actualCharacterRange:NULL];
BOOL touches = NO;
for (NSUInteger index = glyphRange.location; index < glyphRange.location + glyphRange.length; index++) {
CGRect rectForGlyphInContainer = [self.layoutManager boundingRectForGlyphRange:NSMakeRange(index, 1) inTextContainer:self.textContainer];
CGRect rectForGlyphInTextView = CGRectOffset(rectForGlyphInContainer, self.textContainerInset.left, self.textContainerInset.top);
if (CGRectContainsPoint(rectForGlyphInTextView, point)) {
touches = YES;
break;
}
}
return touches;
}
这也适用于包含多个单词的文本片段,这些单词由于自动换行而分布在多行中。当我们处理打印的字形时,它也适用于本地化文本。
想法与接受的答案相同。这是 Swift.
中的方法假设您已经设置好标签。
youLabel.text = "please tab me!"
将 tapGestuerRecognizer 添加到您的标签中
let tap = UITapGestureRecognizer(target: self, action: #selector(tapAction)) yourLabel.addGestureRecognizer(tap)
对String添加
String
扩展方法计算字符串rectextension String { func rect(font: UIFont) -> CGRect { let label = UILabel(frame: .zero) label.font = font label.text = self label.sizeToFit() return label.frame } }
计算点击手势的可用点击矩形。
let pleaseStringRect = "please".rect(font: yourFont) let tapStringRect = "tap".rect(font: yourFont) let tapAreaRect = CGRect(x: pleaseStringRect.width, y: tapStringRect.origin.y, width: tapStringRect.width, height: tapStringRect.height"
在行动中随心所欲
@objc private func tapAction(tap: UITapGestureRecognizer) { let position = tap.location(in: content) guard reporterFirstNameRect.contains(position) else { return } // Do the tap action stuff }
就是这样,编码愉快。