Swift로 속성 텍스트에 대한 탭 감지
때때로 초보자에게는 설정을하는 방법을 알기가 조금 어렵습니다 (어쨌든 저를위한 것이 었습니다). 그래서이 예제는 조금 더 꽉 차 있습니다.
UITextView
프로젝트에를 추가 하십시오.
콘센트
연결 UITextView
받는 사람을 ViewController
라는 콘센트 textView
.
맞춤 속성
Extension 을 만들어 사용자 지정 속성을 만들 것 입니다.
참고 : 이 단계는 기술적으로 선택 사항이지만 그렇게하지 않으면 다음 부분에서 코드를 편집하여와 같은 표준 속성을 사용해야합니다 NSAttributedString.Key.foregroundColor
. 사용자 지정 특성 사용의 장점은 특성이있는 텍스트 범위에 저장할 값을 정의 할 수 있다는 것입니다.
다음을 사용하여 새 신속한 파일 추가 File> New> File ...> iOS> Source> Swift File . 원하는대로 부를 수 있습니다. 내 NSAttributedStringKey + CustomAttribute.swift를 호출하고 있습니다. 있습니다.
다음 코드를 붙여 넣으십시오.
import Foundation
extension NSAttributedString.Key {
static let myAttributeName = NSAttributedString.Key(rawValue: "MyCustomAttribute")
}
암호
ViewController.swift의 코드를 다음으로 바꿉니다. 를 참고 UIGestureRecognizerDelegate
.
import UIKit
class ViewController: UIViewController, UIGestureRecognizerDelegate {
@IBOutlet weak var textView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
// Create an attributed string
let myString = NSMutableAttributedString(string: "Swift attributed text")
// Set an attribute on part of the string
let myRange = NSRange(location: 0, length: 5) // range of "Swift"
let myCustomAttribute = [ NSAttributedString.Key.myAttributeName: "some value"]
myString.addAttributes(myCustomAttribute, range: myRange)
textView.attributedText = myString
// Add tap gesture recognizer to Text View
let tap = UITapGestureRecognizer(target: self, action: #selector(myMethodToHandleTap(_:)))
tap.delegate = self
textView.addGestureRecognizer(tap)
}
@objc func myMethodToHandleTap(_ sender: UITapGestureRecognizer) {
let myTextView = sender.view as! UITextView
let layoutManager = myTextView.layoutManager
// location of tap in myTextView coordinates and taking the inset into account
var location = sender.location(in: myTextView)
location.x -= myTextView.textContainerInset.left;
location.y -= myTextView.textContainerInset.top;
// character index at tap location
let characterIndex = layoutManager.characterIndex(for: location, in: myTextView.textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
// if index is valid then do something.
if characterIndex < myTextView.textStorage.length {
// print the character index
print("character index: \(characterIndex)")
// print the character at the index
let myRange = NSRange(location: characterIndex, length: 1)
let substring = (myTextView.attributedText.string as NSString).substring(with: myRange)
print("character at index: \(substring)")
// check if the tap location has a certain attribute
let attributeName = NSAttributedString.Key.myAttributeName
let attributeValue = myTextView.attributedText?.attribute(attributeName, at: characterIndex, effectiveRange: nil)
if let value = attributeValue {
print("You tapped on \(attributeName.rawValue) and the value is: \(value)")
}
}
}
}
이제 "Swift"의 "w"를 탭하면 다음 결과가 표시됩니다.
character index: 1
character at index: w
You tapped on MyCustomAttribute and the value is: some value
노트
- 여기에서는 사용자 지정 속성을 사용했지만
NSAttributedString.Key.foregroundColor
값이 UIColor.green
.
- 이전에는 텍스트보기를 편집하거나 선택할 수 없었지만 Swift 4.2에 대한 업데이트 된 답변에서는 선택 여부에 관계없이 잘 작동하는 것 같습니다.
추가 연구
이 답변은이 질문에 대한 몇 가지 다른 답변을 기반으로합니다. 이 외에도 참조