Включить некоторые части UILabel, чтобы действовать как UIButton?

У меня есть атрибут строки UILabel, я смог покрасить некоторые части текста

let text = "Why did \(event) give \(event2) a 5 stars review? Details here. "
let linkTextWithColor = "Why did"
let range = (text as NSString).rangeOfString(linkTextWithColor)

let attributedString = NSMutableAttributedString(string:text)
attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.blackColor() , range: range)

labelEvent.attributedText = attributedString

Теперь я хочу сделать некоторые части текста tappable, как UIButton, как это сделать?

Пример 1

example 1

Пример 2.

example 2

Мне нужно, чтобы синий текст реагировал на прикосновение и выполнял определенную функцию, например, UIButton. помощь действительно ценится, спасибо.

Ответы

Ответ 1

Я рекомендую вам попробовать эту библиотеку

https://github.com/null09264/FRHyperLabel

Большая библиотека, проста в использовании и имеет мало встроенных примеров для вас, чтобы попробовать. Примерами являются как Objective-c, так и Swift

Пример в Swift

 let str = "This is a random bit of text"
        let attributes = [NSForegroundColorAttributeName: UIColor.blackColor(),
                          NSFontAttributeName: UIFont.systemFontOfSize(15)]
        confirmLabel.attributedText = NSAttributedString(string: str, attributes: attributes)

        let handler = {
            (hyperLabel: FRHyperLabel!, substring: String!) -> Void in

            //action here
        }
        //Step 3: Add link substrings
        confirmLabel.setLinksForSubstrings(["random"], withLinkHandler: handler)

Редактировать:

Если вы хотите избавиться от подчеркивания, лучший способ сделать это - следовать совету, который дал DeyaEldeen в комментарии.

Если вы перейдете в файл.m файла FRHyperLabel, перейдите к этому методу

- (void)checkInitialization {
    if (!self.handlerDictionary) {
        self.handlerDictionary = [NSMutableDictionary new];
    }

    if (!self.userInteractionEnabled) {
        self.userInteractionEnabled = YES;
    }

    if (!self.linkAttributeDefault) {
        self.linkAttributeDefault = @{NSForegroundColorAttributeName: FRHyperLabelLinkColorDefault,
                                      NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle)};
    }

    if (!self.linkAttributeHighlight) {
        self.linkAttributeHighlight = @{NSForegroundColorAttributeName: FRHyperLabelLinkColorHighlight,
                                        NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle)};
    }
}

И вы можете просто удалить это

NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle)

из атрибутов

Ответ 2

Скажем, у вас есть UILabel с текстом " abc 123", и вы хотите, чтобы " abc " функционировал как UIButton.

  • Вычислить и сохранить прямоугольник, содержащий "abc".
  • Добавьте UITapGestureRecognizer в UILabel.
  • Когда UILabel используется, проверьте, находится ли крана в прямоугольнике.

static func getRect(str: NSAttributedString, range: NSRange, maxWidth: CGFloat) -> CGRect {
    let textStorage = NSTextStorage(attributedString: str)
    let textContainer = NSTextContainer(size: CGSize(width: maxWidth, height: CGFloat.max))
    let layoutManager = NSLayoutManager()       
    layoutManager.addTextContainer(textContainer)
    textStorage.addLayoutManager(layoutManager)     
    textContainer.lineFragmentPadding = 0       
    let pointer = UnsafeMutablePointer<NSRange>.alloc(1)
    layoutManager.characterRangeForGlyphRange(range, actualGlyphRange: pointer)     
    return layoutManager.boundingRectForGlyphRange(pointer.move(), inTextContainer: textContainer)
}

let rect1 = getRect(label.attributedText!, range: NSMakeRange(0, 3), maxWidth: label.frame.width)

label.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(MyClass.tappedLabel(_:))))

func tappedLabel(sender: UITapGestureRecognizer) {
    if rect1.contains(sender.locationInView(sender.view)) {
        // ...
    }
}

Ответ 3

То, что вы хотите сделать, - использовать атрибутную строку с текстовым представлением, чтобы создать ссылку, которая будет действовать как кнопка.

let attributedString = NSMutableAttributedString(string: "Some string with link", attributes: [<attributes>])

Затем установите его часть как ссылку и настройте ее внешний вид, используя свойство linkAttributes в текстовом представлении. Поскольку это кнопка, а не фактическая ссылка, мы просто добавляем фиктивный url для ссылки, чтобы позже мы могли ее обработать в нашем делегате.

attributedString.setSubstringAsLink(substring: "link", linkURL: "CUSTOM://WHATEVER")
let linkAttributes: [String : AnyObject] = [NSForegroundColorAttributeName : .redColor(), NSUnderlineColorAttributeName : .redColor(), NSUnderlineStyleAttributeName : NSUnderlineStyle.StyleSingle.rawValue]
textView.linkTextAttributes = linkAttributes
textView.attributedText = attributedString
textView.selectable = true
textView.editable = false
textView.userInteractionEnabled = true

Наконец, в текстовом представлении делегата мы проверим схему и выполним некоторые действия.

func textView(textView: UITextView, shouldInteractWithURL URL: NSURL, inRange characterRange: NSRange) -> Bool {
    if URL.scheme = "CUSTOM" {
       // Do your button actions here
    }
    return true
}

Расширение для setSubstringAsLink:

extension NSMutableAttributedString {
    // Set part of string as URL
    public func setSubstringAsLink(substring substring: String, linkURL: String) -> Bool {
        let range = self.mutableString.rangeOfString(substring)
        if range.location != NSNotFound {
            self.addAttribute(NSLinkAttributeName, value: linkURL, range: range)
            return true
        }
        return false
    }
}

Ответ 4

Идея состоит в том, чтобы использовать библиотеку, такую как TTTAttributedLabel, и использовать ее следующим образом:

Рассмотрим следующую строку: "Я хочу быть здесь осязаемой", где здесь выступит прикосновение.

  • Создайте TTTAttributedLabel (подкласс UILabel) и поместите в него текстовое содержимое, как если бы это был UILabel. Установите свой делегат на себя. Затем добавьте ссылку на слово следующим образом:

Цель C

NSRange rangeWord = [attributedLabel.text rangeOfString:@"here"];
[attributedLabel addLinkToURL:[NSURL URLWithString:@"anActionOnClickHere"] withRange:rangeUser];

стриж

NSRange rangeWord = attributedLabel.text.rangeOfString("here")
attributedLabel.addLinkToURL(NSURL(string: "anActionOnClickHere"), withRange:rangeUser)
  • При щелчке по словам он вызовет этот метод, в котором вы можете обрабатывать щелчок:

Цель C

- (void)attributedLabel:(__unused TTTAttributedLabel *)label
   didSelectLinkWithURL:(NSURL *)url {
    NSString *urlToString = [url absoluteString];

    if ([urlToString containsString:@"anActionOnClickHere"]) { //perform segue for example
        [self performSegueWithIdentifier:@"hereSegue" sender:self];
    }
}

стриж

func attributedLabel(label: TTTAttributedLabel!, didSelectLinkWithURL url: NSURL!) {
    NSString *urlToString = url.absoluteString()
    if (urlToString.containsString("anActionOnClickHere")) { //perform segue for example 
        self.performSegueWithIdentifier("hereSegue",sender:self)
    } 
}

С помощью стиля ссылки по умолчанию вы получите синий цвет, который вы ищете.