-1

I made a view and draw text on it and i want that if any text contains link(Hyperlink) or Phone Number It would be clickable (Same Behaviour As in Text View) So how to Achieve it ?

Code For View In which i am Drawing Text :-

class DrawRectCellView: UIView {

    var text: NSAttributedString?

    override init(frame: CGRect) {
        super.init(frame: frame)

    }

    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    // Only override drawRect: if you perform custom drawing.

    override func draw(_ rect: CGRect)
    {
        UIColor.white.setFill()
        UIGraphicsGetCurrentContext()?.fill(rect)

        // Drawing code

        if let attributedText = text {
            attributedText.draw(in: rect)
        }
    }

}

Code For TableCell :-

class DrawRectCell: UITableViewCell {

    var cellView: DrawRectCellView?

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        // Initialization code
        cellView = DrawRectCellView(frame: self.frame)

        if let cell = cellView {
            cell.autoresizingMask = UIViewAutoresizing(rawValue: UIViewAutoresizing.RawValue(UInt8(UIViewAutoresizing.flexibleWidth.rawValue) | UInt8(UIViewAutoresizing.flexibleHeight.rawValue)))
            cell.contentMode = UIViewContentMode.redraw
        }

        self.contentView.addSubview(cellView!)
    }

    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func setTextString(_ text: NSAttributedString) {
        if let view = cellView {
            view.text = text
        }
    }

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }
}

i am Setting Text like = www.google.com or any phone number its showing as normal text only (Not Showing Like In textview (it makes it clickable))

Amey
  • 795
  • 8
  • 31

3 Answers3

1

First you need to detect your text contain url or numbers like this way.

let input = "This is a test with the URL https://www.hackingwithswift.com to be detected."
let detector = try! NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
let matches = detector.matches(in: input, options: [], range: NSRange(location: 0, length: input.utf16.count))

for match in matches {
    guard let range = Range(match.range, in: input) else { continue }
    let url = input[range]
    print(url)
}

if you detect url after setting to the textview you need to add UITapGestureRecognizer on UITextView like this way.

let tapGesture = UITapGestureRecognizer(target: self, action: "handleTap")  

textview.addGestureRecognizer(tapGesture)

func handleTap(sender: UITapGestureRecognizer) {

    if sender.state == .began {
      //write your code here for url tap 
    }
}
Muhammad Shauket
  • 2,643
  • 19
  • 40
0

You can add UITapGestureRecognizer on DrawRectCellView and set the IndexPath as tag. In the selector method of UITapGestureRecognizer you can get the subviews info of the tapped contentView containing text.

Krishna
  • 31
  • 1
  • 3
0

To highlight certain text within the TextView:

Let's say you have your textView textView, then you can use this code to highlight URLs, phone numbers, etc.:

textView.dataDetectorTypes = [] // doesn't work if textfield isEditable is set to true
textView.linkTextAttributes = [NSForegroundColorAttributeName: UIColor.blue] // the default is blue anyway

If you want to only include some specific data types to be detected, add them to the array like so:

textView.dataDetectorTypes = [.link]

Here's a list of types:

https://developer.apple.com/documentation/uikit/uidatadetectortypes

To make an entire view tappable:

You can add a UITapGestureRecognizer to the view (or not if it does not contain a phone number or hyperlink) like so:

https://stackoverflow.com/a/28675664/7270113

This answer may not be using the Swift version you are using. If so the compiler will tell you how to change it, so it will work.

If you don't like using Selectors, I recommend using the library Closures https://github.com/vhesener/Closures, specifically with this https://vhesener.github.io/Closures/Extensions/UITapGestureRecognizer.html

erik_m_martens
  • 496
  • 3
  • 8
  • Its not about tapGesture How to make the text look like link (Phone number and hyper link). For ex we have a string "hello this is an example www.google.com end of example" and if we put it in text view it would make www.google.com highlighted and clickable and when we click it will redirect it to that website so how to achieve this thing in custom view where i am drawing text on the view . – Amey Nov 13 '17 at 09:12
  • i am not using a textview . i am using a view in which a draw the text so will following code work with view ? – Amey Nov 13 '17 at 09:44
  • You would save yourself a lot of time and headache if you would add a `UITextView` as a subview to your cells contentView. You can even use a `UIStackView` to balance everything inside your cell. Why are you drawing the text? It would certainly be easier to add an `NSAttributedString` to a `UITextView` directly and configure things like font and size that way. If you can you should use the native elements that already come with Xcode and Swift. – erik_m_martens Nov 13 '17 at 09:51
  • I am using this method because UITextView with NsAttributedString Slow Dows the scrolling behaviour and i wat a smooth scrolling so using this approach . – Amey Nov 13 '17 at 09:55
  • Then that is rather difficult to achieve. First you need to define some detection logic that goes over your String and transforms characters in range which are part of URLs etc. That should be the easy part and the answer of @Shauket Sheikh shows how to do that. Now you need to overlay gesture recognizers over these links, so they just cover the text. That's the only way I can think of. You basically have to draw them too in the right spots. Unless you only have a single link per drawn text. Then you could get away with making the entire view tappable, but that might not be a nice UX. – erik_m_martens Nov 13 '17 at 10:09
  • Also mind that that approach won't make the text change color when you tap it, like links usually do. – erik_m_martens Nov 13 '17 at 10:10