遇到的坑坑坑
下面說下在使用UITextView設(shè)置超鏈接時(shí)遇到的坑。
UITextView可以通過設(shè)置富文本的方式進(jìn)行超鏈接的設(shè)置萄唇。但是,UITextView默認(rèn)有諸多手勢,在長按時(shí)會(huì)出現(xiàn)菜單姓赤,放大鏡,選中文本幾種狀態(tài)仲吏,但是并不想要這三種狀態(tài)啊不铆。
為了取消菜單狀態(tài)可以這么做:
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
return NO;
}
為了取消算中狀態(tài)可以通過textView的代理來實(shí)現(xiàn),一直將設(shè)置范圍重置為0裹唆,如下:
- (void)textViewDidChangeSelection:(UITextView *)textView
{
_textView.selectedRange = NSMakeRange(0, 0);
}
為了取消放大鏡狀態(tài)嘗試了各種方法誓斥,比如不同時(shí)機(jī)注銷第一響應(yīng)等,但是都沒用许帐。(如果有請(qǐng)麻煩告訴我劳坑,謝謝),但是這三種狀態(tài)肯定都是通過去手勢完成的成畦,所以想到了最終方法距芬,找到對(duì)應(yīng)手勢,將手勢刪除羡鸥。
大概可以這么做:
NSArray *textViewGestureRecognizers = self.textView.gestureRecognizers;
NSMutableArray *mutableArrayOfGestureRecognizers = [[NSMutableArray alloc] init];
for (UIGestureRecognizer *gestureRecognizer in textViewGestureRecognizers) {
if (![gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]]) {
[mutableArrayOfGestureRecognizers addObject:gestureRecognizer];
} else {
UILongPressGestureRecognizer *longPressGestureRecognizer = (UILongPressGestureRecognizer *)gestureRecognizer;
if (longPressGestureRecognizer.minimumPressDuration < 0.5) {
[mutableArrayOfGestureRecognizers addObject:gestureRecognizer];
}
}
}
self.textView.gestureRecognizers = mutableArrayOfGestureRecognizers;
但是手勢太多了蔑穴,可能會(huì)誤移除,將來誰知道蘋果會(huì)怎么變惧浴,所以哪天手勢稍有改動(dòng)萬一上線了出了問題存和,不得被老大罵死啊。
然后決定使用TTTAttributedLabel來做這個(gè)需求衷旅,但是TTTAttributedLabel這玩意在我這布局總不對(duì)捐腿,通過debug發(fā)現(xiàn)繪制也是從0,0開始繪制的柿顶,實(shí)際出來卻不是從0茄袖,0繪制,要偏上一些嘁锯,github主頁發(fā)現(xiàn)也有人碰到了類似問題宪祥,最后決定放棄使用TTTAttributedLabel了聂薪,還是使用UITextView自己通過計(jì)算鏈接區(qū)域來搞吧,也順便將來應(yīng)對(duì)圖文混排需求蝗羊;
解決方案
下面大概說下思路藏澳,具體可見demo;
- 首先需要設(shè)置下面兩個(gè)屬性為NO
textView.editable = NO;
textView.selectable = NO;
2.然后需要根據(jù)超鏈接的點(diǎn)擊范圍計(jì)算點(diǎn)擊矩形區(qū)域耀找,由于可能換行翔悠,所以返回?cái)?shù)組,假設(shè)點(diǎn)擊區(qū)域保存在self.respondRects
- (NSArray *)respondRectsFromRange:(NSRange)range
{
UITextPosition *beginning = _textView.beginningOfDocument;
UITextPosition *rangeStart = [_textView positionFromPosition:beginning offset:range.location];
UITextPosition *rangeEnd = [_textView positionFromPosition:rangeStart offset:range.length];
UITextRange *textRange = [_textView textRangeFromPosition:rangeStart toPosition:rangeEnd];
NSArray *ranges = [_textView selectionRectsForRange:textRange];
NSMutableArray *respondRects = [NSMutableArray array];
for (UITextSelectionRect *selectionRect in ranges) {
CGRect rect = selectionRect.rect;
if (rect.size.width > 0 && rect.size.height > 0) {
[respondRects addObject:NSStringFromCGRect([_textView convertRect:rect toView:_textView.superview])];
}
}
return respondRects;
}
- 添加longPress手勢野芒,并設(shè)置minimumPressDuration = 0.01f; 設(shè)置0.01s是為了在模擬tap手勢蓄愁,在快速點(diǎn)擊鏈接時(shí)也會(huì)做出響應(yīng);
- 在LongPress.state == UIGestureRecognizerStateEnded時(shí)判斷點(diǎn)擊的點(diǎn)是否在respondRects區(qū)域狞悲,是則進(jìn)行相應(yīng)撮抓;