I have this code to write a paragraph like book with numbering for each sentence , the problem I'm facing is i can't find how to color one sentence when the user clicks in any word from it
import UIKit
let descender: CGFloat = UIFont.systemFont(ofSize: 25).descender
class ViewController: UIViewController , UITextViewDelegate, UIGestureRecognizerDelegate {
var all = [NSMutableAttributedString]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let style = NSMutableParagraphStyle()
style.alignment = NSTextAlignment.justified
style.baseWritingDirection = .rightToLeft
style.lineBreakMode = .byWordWrapping
let myAttribute = [ NSAttributedString.Key.font: UIFont.systemFont(ofSize: 25)] // ,
// NSAttributedString.Key.paragraphStyle: style ,
// NSAttributedString.Key.baselineOffset: NSNumber(value: 0)]
let textView = UITextView(frame:CGRect(x: 20, y: 100, width: UIScreen.main.bounds.width - 40 , height: UIScreen.main.bounds.height))
let attributedString = NSMutableAttributedString()
Array(1..<50).forEach {
let small = $0 % 2 == 0 ? " long text part one long text part one long text part one long text part one long text part one long text part one long text part one long text part one long text part one " : "long text part two long text part twolong text part twolong text part twolong text part twolong text part twolong text part twolong text part two "
let attributedString2 = NSMutableAttributedString(string: small,attributes: myAttribute)
attributedString.append(attributedString2)
let textAttachment11 = SubTextAttachment()
textAttachment11.image = generateImageWithText(text: "\($0)")
let attrStringWithImage11 = NSAttributedString(attachment: textAttachment11)
attributedString.append(attrStringWithImage11)
}
textView.attributedText = attributedString;
self.view.addSubview(textView)
textView.isEditable = false
textView.isSelectable = true
textView.delegate = self
let tap = UITapGestureRecognizer(target: self, action: #selector(self.textTapped(_:)))
tap.delegate = self
textView.isUserInteractionEnabled = true
textView.addGestureRecognizer(tap)
}
func generateImageWithText(text: String) -> UIImage? {
let image = UIImage(named: "qqq")!
print(text," ",image.size)
let imageView = UIImageView(image: image)
imageView.backgroundColor = UIColor.clear
imageView.frame = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)
let label = UILabel(frame: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
label.font = UIFont.systemFont(ofSize: 50)
label.backgroundColor = UIColor.clear
label.textAlignment = .center
label.textColor = UIColor.black
label.text = text
UIGraphicsBeginImageContextWithOptions(label.bounds.size, false, 0)
imageView.layer.render(in: UIGraphicsGetCurrentContext()!)
label.layer.render(in: UIGraphicsGetCurrentContext()!)
let imageWithText = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return imageWithText
}
@objc func textTapped(_ sender:UITapGestureRecognizer) {
}
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {
return true
}
}
class SubTextAttachment:NSTextAttachment {
override func attachmentBounds(for textContainer: NSTextContainer?, proposedLineFragment lineFrag: CGRect, glyphPosition position: CGPoint, characterIndex charIndex: Int) -> CGRect {
let height = lineFrag.size.height
var scale: CGFloat = 1.0;
let imageSize = image!.size
if (height < imageSize.height) {
scale = height / imageSize.height
}
let value = CGRect(x: 0, y: descender, width: imageSize.width * scale, height: imageSize.height * scale)
return value
}
}
I know how to change the foreground color of any sub attributed string , but how i can know that the clicked part belong to the one to be colored ?
Also is there any better way to build this UI (in terms of performance ) as with tableView/CollectionView there is a dequeueing but here there isn't ?
So any hep is greatly appreciated