将 UITapGestureRecognizer 添加到 UILabel 的特定部分的最佳方法是啥?
Posted
技术标签:
【中文标题】将 UITapGestureRecognizer 添加到 UILabel 的特定部分的最佳方法是啥?【英文标题】:What is the best way to add UITapGestureRecognizer to a specific part of UILabel?将 UITapGestureRecognizer 添加到 UILabel 的特定部分的最佳方法是什么? 【发布时间】:2016-06-24 06:49:25 【问题描述】:这个问题可能已经问过几次了,但我仍在努力寻找最佳解决方案。带有 NSMutableAttributedString 的 addAttributes 将不起作用,因为我只能提供指向字符串一部分的链接。
我有一个带有字符串“已经注册?在此处登录”的标签。我可以得到文本“登录”的 NSRange,但我怎样才能给它 UITapGesture?我不想在这里使用 3rd 方库。请给我一些想法。谢谢
【问题讨论】:
你为什么不使用UITextView
?它可以自定义为看起来像“正常”UILabel
。
【参考方案1】:
您不能将手势识别器添加到“UILabel 的一部分”。对于您的情况,我将只使用两种不同的 UILabel:一种是不可点击的,表示“已经注册?”,另一种是可点击的,表示“在此处登录”。老实说,我会将可点击部分放入 UIButton 中以使其清楚。另一种选择是将空的 UIView 作为 UILabel 的子视图,使其成为您要点击的文本的大小。然后将手势识别器添加到那个子视图。
(在我看来,开发人员在使用 ios 时遇到的最大陷阱之一是试图强迫它以不同于设计的方式运行;比如模仿网络链接或其他东西。它总是效果最好,并且代码最少, 在编写时利用其设计模式)
所有点击位置的废话都可以忽略,因为那是识别器的重点。识别器会为您处理所有这些,并会在点击 UIView 时使用您设置的操作调用您的目标。
所以基本上是这样的:
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:someObject action:@selector(someMethod:)];
[loginLabel addGestureRecognizer:tapRecognizer];
就是这样。其余的将由系统为您处理。点击标签时将调用您的目标对象。至少,从原始帖子中描述的问题来看,这似乎很简单。如果还有其他并发症,请在您的问题中包含这些要点。
【讨论】:
【参考方案2】:手势识别器不能添加到 UI 组件的特定部分。 但是,在点击处理程序操作中,您可能需要检查
CGPoint tapLocation = [tapRecognizer locationInView:tapRecognizer.view];
你可以检查点是否在你的targetRect
if(CGRectContainsPoint(myTargetRect, tapLocation))
// Do your action here
希望对你有帮助。
更新:
这是您需要的 @Code 答案中 getRect() 的 Objective-C 版本。
-(CGRect)getRectForString:(NSAttributedString*)str withRange:(NSRange)textRange usingMaxWidth:(CGFloat)maxWidth
// Create a layoutManager
NSLayoutManager* layoutManager = [[NSLayoutManager alloc] init];
// Create a textContainer with maxWidth size and add it to layoutManager
NSTextContainer* textContainer = [[NSTextContainer alloc] initWithSize:CGSizeMake(maxWidth, CGFLOAT_MAX)];
[layoutManager addTextContainer:textContainer];
textContainer.lineFragmentPadding = 0;
// Create a textStorage with 'str' variable and add the layoutManager to this textStorage
NSTextStorage* textStorage = [[NSTextStorage alloc] initWithAttributedString:str];
[textStorage addLayoutManager:layoutManager];
// Query the actualGlyphRange from layoutManager for specified textRange
NSRange actualGlyphRange;
[layoutManager characterRangeForGlyphRange:textRange actualGlyphRange:&actualGlyphRange];
// Find out the boundingRect for actualGlyphRange
return [layoutManager boundingRectForGlyphRange:actualGlyphRange inTextContainer:textContainer];
【讨论】:
是的,它有帮助,但我怎样才能得到“myTargetRect”,这是这里的主要问题。 查看这个答案 ***.com/a/38007419/6458001 getRect() 就是你要找的。span> 目标 c 是我正在寻找的。 Swift 尚待学习。如果您可以将其转换为目标 c,将不胜感激 更新了答案。 @HirenPrajapati 如果该解决方案适合您,您应该将其标记为答案。它将帮助其他开发人员在搜索与您遇到的相同问题时做出选择。【参考方案3】:您无法将轻击手势添加到 UILabel 的特定部分,或者如果您尝试这样做,您将停留在寻找可能在这一点上帮助您的框架和标签的一部分,但如果这样做会更成问题在 UITableViewCell 等其他视图中。它可能需要一些计算相对于父/子视图的点转换。
为简单起见,我的建议是创建一个UIView
,其中嵌入了UILabel
和UIButton
,并将按钮设置在UILabel 旁边。
一个例子:
- (void)viewDidLoad
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// Create label
UILabel *lbl = [[UILabel alloc] init];
[lbl setText:@"Already Sign up ? "];
[lbl sizeToFit];
// Create button
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setTitle:@"Login Here" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(didTapLink:) forControlEvents:UIControlEventTouchUpInside];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn sizeToFit];
[btn setFrame:CGRectMake(lbl.frame.size.width, lbl.frame.origin.y, btn.frame.size.width, lbl.frame.size.height)];
// Create container that embeds the label and button
UIView *customLabel = [[UIView alloc] initWithFrame:CGRectMake(0, 50, lbl.frame.size.width + btn.frame.size.width, lbl.frame.size.height)];
[customLabel addSubview:lbl];
[customLabel addSubview:btn];
// Add this custom label to UI
[self.view addSubview:customLabel];
-(void)didTapLink:(id)sender
NSLog(@"Button tapped");
截图:
希望有帮助!
【讨论】:
以上是关于将 UITapGestureRecognizer 添加到 UILabel 的特定部分的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
将 NSDictionary 作为参数传递给 UITapGestureRecognizer
将 UITapGestureRecognizer 添加到 UIControl
将 UITapGestureRecognizer 连接到 UIView
将 UITapGestureRecognizer 触摸传递到底层 UITableViewCell