背景
绑定手机号登录页面中,点击微信登录。未绑定手机号的情况下,会跳转到绑定手机号页面。在这个页面中的协议说明部分 中使用的是YYLabel,然后使用
- (void)yy_setTextHighlightRange:color: backgroundColor:tapAction:
实现事件的传递。
//创建协议视图
_protocolL = [[YYLabel alloc] init];
_protocolL.textColor = [RdAppSkinColor sharedInstance].secondaryTextColor;
[self addSubview:_protocolL];
NSString *protocolStr = [NSString stringWithFormat:@"登录后即同意《用户注册协议》与《隐私保护条款》"];
NSMutableAttributedString *attrbutedprotocalBtn = [[NSMutableAttributedString alloc]initWithString:protocolStr];
attrbutedprotocalBtn.yy_font = [UIFont systemFontOfSize:12];
attrbutedprotocalBtn.yy_alignment = NSTextAlignmentCenter;
NSRange rang = [protocolStr rangeOfString:@"《用户注册协议》"];
NSRange rang2 = [protocolStr rangeOfString:@"《隐私保护条款》"];
[attrbutedprotocalBtn yy_setTextHighlightRange:rang color:[RdAppSkinColor sharedInstance].mainColor backgroundColor:nil tapAction:^(UIView * _Nonnull containerView, NSAttributedString * _Nonnull text, NSRange range, CGRect rect) {
//使用block向controller传递事件
if (self.clickAction) {
self.clickAction(@"用户注册协议");
}
}];
[attrbutedprotocalBtn yy_setTextHighlightRange:rang2 color:[RdAppSkinColor sharedInstance].mainColor backgroundColor:nil tapAction:^(UIView * _Nonnull containerView, NSAttributedString * _Nonnull text, NSRange range, CGRect rect) {
if (self.clickAction) {
self.clickAction(@"隐私保护条款");
}
}];
_protocolL.attributedText = attrbutedprotocalBtn;
这段代码在我测试机iPhone6p 12.1.2 16G 以及 iPhone8 12.0 64G上面表现正常。在测试同事那边的iPhone6p 11.1.2 16G手机上为,反复点击协议跳转协议h5后返回,协议文案消失不见。
思路
1、文案消失,可能是我约束的时候没有给定这段文案的高度。于是给了这个文案20像素的高度
[_protocolL mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self).offset(0);
make.top.equalTo(_loginButton.mas_bottom).offset(10);
make.height.equalTo(@(20));
}];
于是接着build,刚进入这个页面就闪退。。也没有进全局断点。
2、思考了一下,登录页面也使用了这个视图,但是没有出现闪退或者消失不见的问题。是在调用微信登录之后进入这个页面后才出现问题的。于是继续跑了一下,结果提示 Lost connection 。搜了一下出现这个提示的原因,意思大概是:应用程序很快分配了大量内存,操作系统终止了该应用程序。那是哪一个对象或者方法消耗了这么多的资源呢。我把目标瞄准了这个协议的文案使用的控件。
解决
1、使用UITextView替代YYLabel。使用textView的 链接的属性实现文字效果和点击事件
NSMutableAttributedString *protocolAttributedString = [[NSMutableAttributedString alloc] initWithString:@"登录后即同意《用户注册协议》与《隐私保护条款》"];
[protocolAttributedString addAttribute:NSLinkAttributeName
value:@"userRegisterProtocol://"
range:[[protocolAttributedString string] rangeOfString:@"《用户注册协议》"]];
[protocolAttributedString addAttribute:NSLinkAttributeName
value:@"PrivacyProtection://"
range:[[protocolAttributedString string] rangeOfString:@"《隐私保护条款》"]];
NSDictionary *linkAttributes = @{NSForegroundColorAttributeName: [RdAppSkinColor sharedInstance].mainColor,
NSUnderlineColorAttributeName:[RDAppskinColor sharedInstance].emphasisSubTextColor,
NSUnderlineStyleAttributeName: @(NSUnderlinePatternSolid)};
textView.linkTextAttributes = linkAttributes;
textView.attributedText = attributedString;
textView.delegate = self;
textView.editable = NO;
然后实现代理方法
- (BOOL)textView: shouldInteractWithURL: inRange:
但是这样有两点不好:
-
长按会出现 控件自带的复制剪切,且禁用不掉(文案能够消掉,但是那个白板始终还在);
-
点击链接文案跳转不够灵敏,长按下,链接文案会有放大效果。
2、最终方案。使用UILabel,结合UITapGestureRecognizer,实现点击事件。
这里着重说一下点击事件的实现。让这个视图成为tap的UIGestureRecognizerDelegate委托者。
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapSelectProtocol:)];
tap.delegate = self;
[_protocolL addGestureRecognizer:tap];
实现
- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer {
return YES;
}
这样就可以实现让tap的事件方法传递,根据点击位置实现不同事件的传递了。
- (void)tapSelectProtocol:(UITapGestureRecognizer*)tap {
CGPointpoint = [taplocationInView:tap.view];
NSString*title ;
if(point.x>75&& point.x<160) {
title =@"用户注册协议";
}
if(point.x>190&& point.x<282) {
title =@"隐私保护条款";
}
if(title.length) {
self.clickAction(title);
}
//找到两个协议的大概位置。(这个位置相对于当前控件的)
// NSLog(@"handleSingleTap!pointx:%f,y:%f",point.x,point.y);
}
build一下,重复 点击协议跳去协议详情web然后返回。没有异常。
反思
找到问题根源的方法具备偶然性。应该学会使用专门的检测工具Instruments来定位问题的所在。
网友评论