UITextView上的NSMutableAttributedString不可点击

时间:2016-03-09 12:49:05

标签: ios hyperlink uitextview uigesturerecognizer nsmutableattributedstring

我有一个UITextView和String设置了一个属性文本,上面写着"查看更多"。我还为UITextView添加了手势。当点击在任何其他地方执行时,手势会起作用,但在点击时不会,#34;查看更多"。

我需要点击回复"查看更多"点击。

以下是我的实施方式:

//link text
 NSDictionary *linkAttributes = @{ NSForegroundColorAttributeName : [UIColor colorWithRed:0.05 green:0.4 blue:0.65 alpha:1.0],
                                                  NSFontAttributeName : [UIFont fontWithName:@"Roboto-Regular" size:10.0],
                                                  NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle) };

[attributedString setAttributes:linkAttributes range:linkRange];

self.classDesc.userInteractionEnabled = YES;
[self.classDesc addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleExpand:)]];
self.classDesc.selectable = YES;
 // Assign attributedText to UILabel
 self.classDesc.attributedText = attributedString;

以下是手势监听器:

- (void)handleExpand:(UITapGestureRecognizer *)tapGesture
{
    self.classDesc.text = selectedClasses.classDescription;
    [self textViewDidChange:self.classDesc];

       CGSize sizeThatFitsTextView = [self.classDesc sizeThatFits:CGSizeMake(self.classDesc.frame.size.width, MAXFLOAT)];
    self.descHeight.constant = sizeThatFitsTextView.height ;


}

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:1)

您可以使用UILabel来完成此操作,

首先为UITapGestureRecognizer创建一个类别类,然后添加以下方法

/**
 Returns YES if the tap gesture was within the specified range of the attributed text of the label.
 */
- (BOOL)didTapAttributedTextInLabel:(UILabel *)label inRange:(NSRange)targetRange {
    NSParameterAssert(label != nil);

    CGSize labelSize = label.bounds.size;
    // create instances of NSLayoutManager, NSTextContainer and NSTextStorage
    NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
    NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:CGSizeZero];
    NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:label.attributedText];

    // configure layoutManager and textStorage
    [layoutManager addTextContainer:textContainer];
    [textStorage addLayoutManager:layoutManager];

    // configure textContainer for the label
    textContainer.lineFragmentPadding = 0.0;
    textContainer.lineBreakMode = label.lineBreakMode;
    textContainer.maximumNumberOfLines = label.numberOfLines;
    textContainer.size = labelSize;

    // find the tapped character location and compare it to the specified range
    CGPoint locationOfTouchInLabel = [self locationInView:label];
    CGRect textBoundingBox = [layoutManager usedRectForTextContainer:textContainer];
    CGPoint textContainerOffset = CGPointMake((labelSize.width - textBoundingBox.size.width) * 0.5 - textBoundingBox.origin.x,
                                              (labelSize.height - textBoundingBox.size.height) * 0.5 - textBoundingBox.origin.y);
    CGPoint locationOfTouchInTextContainer = CGPointMake(locationOfTouchInLabel.x - textContainerOffset.x,
                                                         locationOfTouchInLabel.y - textContainerOffset.y);
    NSInteger indexOfCharacter = [layoutManager characterIndexForPoint:locationOfTouchInTextContainer
                                                       inTextContainer:textContainer
                              fractionOfDistanceBetweenInsertionPoints:nil];
    if (NSLocationInRange(indexOfCharacter, targetRange)) {
        return YES;
    } else {
        return NO;
    }
}

实施

//Global variables
NSString *longString = @"very very long string";
NSRange moreRange;
NSRange lessRange;

-(void)setReadLessDescriptionText{
    self.lblDescription.userInteractionEnabled = YES;
    [self.lblDescription addGestureRecognizer:
     [[UITapGestureRecognizer alloc] initWithTarget:self
                                             action:@selector(handleTapMore:)]];

    // create your attributed text and keep an variable of your "link" text range
    NSAttributedString *plainText;
    NSAttributedString *linkText;
    plainText = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@ ...", [longString substringWithRange:NSMakeRange(0, 200)]] attributes:nil];//here 200 is  your character limit, it can be any value depending your requirement
    linkText = [[NSMutableAttributedString alloc] initWithString:@"more"
                                                      attributes:@{
                                                                   NSForegroundColorAttributeName:[UIColor blueColor]
                                                                   }];
    NSMutableAttributedString *attrText = [[NSMutableAttributedString alloc] init];
    [attrText appendAttributedString:plainText];
    [attrText appendAttributedString:linkText];

    // Variable -- keep track of the target range so you can compare in the callback
        moreRange = NSMakeRange(plainText.length, linkText.length);

    self.lblDescription.attributedText = attrText;

}

-(void)setReadMoreDescriptionText{
    self.lblDescription.userInteractionEnabled = YES;
    [self.lblDescription addGestureRecognizer:
     [[UITapGestureRecognizer alloc] initWithTarget:self
                                             action:@selector(handleTapLess:)]];

    // create your attributed text and keep an variable of your "link" text range
    NSAttributedString *plainText;
    NSAttributedString *linkText;
    plainText = [[NSMutableAttributedString alloc] initWithString:longString attributes:nil];
    linkText = [[NSMutableAttributedString alloc] initWithString:@" less"
                                                      attributes:@{
                                                                   NSForegroundColorAttributeName:[UIColor blueColor]
                                                                   }];
    NSMutableAttributedString *attrText = [[NSMutableAttributedString alloc] init];
    [attrText appendAttributedString:plainText];
    [attrText appendAttributedString:linkText];

    // Variable -- keep track of the target range so you can compare in the callback
    lessRange = NSMakeRange(plainText.length, linkText.length);

    self.lblDescription.attributedText = attrText;
}

手势方法

- (void)handleTapMore:(UITapGestureRecognizer *)tapGesture {
    BOOL didTapLink = [tapGesture didTapAttributedTextInLabel:self.lblDescription
                                                      inRange:moreRange];

    if (didTapLink) {
        [self setReadMoreDescriptionText];
    }
}

- (void)handleTapLess:(UITapGestureRecognizer *)tapGesture {
    BOOL didTapLink = [tapGesture didTapAttributedTextInLabel:self.lblDescription
                                                      inRange:lessRange];

    if (didTapLink) {
        [self setReadLessDescriptionText];
    }
}

答案 1 :(得分:0)

试试这个

实施UITextFieldDelegate协议在视图控制器中添加文本

@interface YourViewController () <UITextViewDelegate>
In viewDidLoad set yourself as a delegate:

yourUITextView.delegate = self;

//实现下面的委托方法:

- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
{ 
   return NO; 
}

答案 2 :(得分:0)

下面两行代码进行了评论,然后触摸&#34;查看更多&#34;开始工作了:

self.classDesc.textContainer.lineFragmentPadding = 0;
self.classDesc.textContainerInset = UIEdgeInsetsZero;