[ios] NSAttributedString에서 클릭 가능한 링크를 만들려면 어떻게해야합니까?

에서 하이퍼 링크를 클릭 할 수있게 만드는 것은 쉽지 않습니다 UITextView. IB의보기에서 “링크 감지”확인란을 설정하면 HTTP 링크가 감지되어 하이퍼 링크로 바뀝니다.

그러나 이것은 여전히 ​​사용자가 보는 것이 “원시”링크라는 것을 의미합니다. RTF 파일과 HTML 모두 “뒤에”링크가있는 사용자가 읽을 수있는 문자열을 설정할 수 있습니다.

중요한 텍스트를 텍스트보기 (또는 a UILabel또는) 로 쉽게 설치할 수 있습니다 UITextField. 그러나 해당 텍스트에 링크가 포함되어 있으면 클릭 할 수 없습니다.

사용자가 읽을 수있는 텍스트 A의 클릭 할 수있는 방법이 있나요 UITextView, UILabel또는 UITextField?

마크 업은 SO와 다르지만 일반적인 아이디어는 다음과 같습니다. 내가 원하는 것은 다음과 같은 텍스트입니다.

이 모프는 Face Dancer 로 생성되었습니다 . 클릭하면 앱 스토어에서 볼 수 있습니다.

내가 얻을 수있는 유일한 것은 이것입니다.

이 모프는 Face Dancer로 생성되었습니다 . 앱 스토어에서 보려면 http://example.com/facedancer 를 클릭하십시오 .



답변

NSMutableAttributedString을 사용하십시오 .

NSMutableAttributedString * str = [[NSMutableAttributedString alloc] initWithString:@"Google"];
[str addAttribute: NSLinkAttributeName value: @"http://www.google.com" range: NSMakeRange(0, str.length)];
yourTextView.attributedText = str;

편집 :

이것은 질문에 대한 것이 아니라 명확하게하기위한 UITextField것이며 UILabelURL 열기를 지원하지 않습니다. UILabel링크와 함께 사용 하려면 TTTAttributedLabel 을 확인할 수 있습니다 .

또한 당신은 설정해야합니다 dataDetectorTypes당신의 가치 UITextViewUIDataDetectorTypeLink또는 UIDataDetectorTypeAll클릭하면 열려있는 URL로. 또는 의견에서 제안한대로 위임 방법을 사용할 수 있습니다.


답변

나는 이것이 실제로 유용하다는 것을 알았지 만 꽤 많은 곳에서 그것을해야했기 때문에 간단한 접근 방식으로 접근 방식을 마무리했습니다 NSMutableAttributedString.

스위프트 3

extension NSMutableAttributedString {

    public func setAsLink(textToFind:String, linkURL:String) -> Bool {

        let foundRange = self.mutableString.range(of: textToFind)
        if foundRange.location != NSNotFound {
            self.addAttribute(.link, value: linkURL, range: foundRange)
            return true
        }
        return false
    }
}

스위프트 2

import Foundation

extension NSMutableAttributedString {

   public func setAsLink(textToFind:String, linkURL:String) -> Bool {

       let foundRange = self.mutableString.rangeOfString(textToFind)
       if foundRange.location != NSNotFound {
           self.addAttribute(NSLinkAttributeName, value: linkURL, range: foundRange)
           return true
       }
       return false
   }
}

사용법 예 :

let attributedString = NSMutableAttributedString(string:"I love stackoverflow!")
let linkWasSet = attributedString.setAsLink("stackoverflow", linkURL: "http://stackoverflow.com")

if linkWasSet {
    // adjust more attributedString properties
}

목표 -C

순수한 Objective-C 프로젝트에서 동일한 작업을 수행하기위한 요구 사항에 부딪 쳤으므로 Objective-C 범주가 있습니다.

@interface NSMutableAttributedString (SetAsLinkSupport)

- (BOOL)setAsLink:(NSString*)textToFind linkURL:(NSString*)linkURL;

@end


@implementation NSMutableAttributedString (SetAsLinkSupport)

- (BOOL)setAsLink:(NSString*)textToFind linkURL:(NSString*)linkURL {

     NSRange foundRange = [self.mutableString rangeOfString:textToFind];
     if (foundRange.location != NSNotFound) {
         [self addAttribute:NSLinkAttributeName value:linkURL range:foundRange];
         return YES;
     }
     return NO;
}

@end

사용법 예 :

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:"I love stackoverflow!"];

BOOL linkWasSet = [attributedString setAsLink:@"stackoverflow" linkURL:@"http://stackoverflow.com"];

if (linkWasSet) {
    // adjust more attributedString properties
}

NSTextField의 Behavior 속성이 Selectable로 설정되어 있는지 확인하십시오.
Xcode NSTextField 동작 속성


답변

방금 그러한 사용 사례를 다루기 위해 UILabel의 하위 클래스를 만들었습니다. 여러 개의 링크를 쉽게 추가하고 다른 처리기를 정의 할 수 있습니다. 터치 피드백을 위해 아래로 터치 할 때 누른 링크를 강조 표시하는 기능도 지원합니다. https://github.com/null09264/FRHyperLabel참조하십시오 .

귀하의 경우 코드는 다음과 같습니다.

FRHyperLabel *label = [FRHyperLabel new];

NSString *string = @"This morph was generated with Face Dancer, Click to view in the app store.";
NSDictionary *attributes = @{NSFontAttributeName: [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline]};

label.attributedText = [[NSAttributedString alloc]initWithString:string attributes:attributes];

[label setLinkForSubstring:@"Face Dancer" withLinkHandler:^(FRHyperLabel *label, NSString *substring){
    [[UIApplication sharedApplication] openURL:aURL];
}];

샘플 스크린 샷 (이 경우 처리기는 URL을 여는 대신 경고를 표시하도록 설정되어 있음)

안무가


답변

ujell 솔루션의 사소한 개선 : NSString 대신 NSURL을 사용하는 경우 모든 URL (예 : 사용자 정의 URL)을 사용할 수 있습니다.

NSURL *URL = [NSURL URLWithString: @"whatsapp://app"];
NSMutableAttributedString * str = [[NSMutableAttributedString alloc] initWithString:@"start Whatsapp"];
[str addAttribute: NSLinkAttributeName value:URL range: NSMakeRange(0, str.length)];
yourTextField.attributedText = str;

즐기세요!


답변

스위프트 4 :

var string = "Google"
var attributedString = NSMutableAttributedString(string: string, attributes:[NSAttributedStringKey.link: URL(string: "http://www.google.com")!])

yourTextView.attributedText = attributedString

스위프트 3.1 :

var string = "Google"
var attributedString = NSMutableAttributedString(string: string, attributes:[NSLinkAttributeName: URL(string: "http://www.google.com")!])

yourTextView.attributedText = attributedString


답변

나도 비슷한 요구 사항을 가지고 있었고 처음에는 UILabel을 사용했으며 UITextView가 더 낫다는 것을 깨달았습니다. 상호 작용 및 스크롤을 비활성화하여 UITextView를 UILabel처럼 작동하게 만들고 NSMutableAttributedStringKarl이 수행 한 것과 동일한 텍스트로 링크를 설정 하는 범주 메서드를 만들었 습니다 (+1). 이것은 내 obj c 버전입니다.

-(void)setTextAsLink:(NSString*) textToFind withLinkURL:(NSString*) url
{
    NSRange range = [self.mutableString rangeOfString:textToFind options:NSCaseInsensitiveSearch];

    if (range.location != NSNotFound) {

        [self addAttribute:NSLinkAttributeName value:url range:range];
        [self addAttribute:NSForegroundColorAttributeName value:[UIColor URLColor] range:range];
    }
}

아래 대리인을 사용하여 작업을 처리 할 수 ​​있습니다

- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)url inRange:(NSRange)characterRange
{
    // do the task
    return YES;
}


답변

UITextView를 사용하면 클릭 가능한 링크를 지원합니다. 다음 코드를 사용하여 속성 문자열 만들기

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:strSomeTextWithLinks];

그런 다음 UITextView 텍스트를 다음과 같이 설정하십시오.

NSDictionary *linkAttributes = @{NSForegroundColorAttributeName: [UIColor redColor],

                                 NSUnderlineColorAttributeName: [UIColor blueColor],

                                 NSUnderlineStyleAttributeName: @(NSUnderlinePatternSolid)};

customTextView.linkTextAttributes = linkAttributes; // customizes the appearance of links
textView.attributedText = attributedString;

XIB에서 UITextView의 “선택 가능”동작을 사용 가능하게하십시오.