54 votes

Créer UITextRange à partir de NSRange

J'ai besoin de trouver la trame de pixels pour différentes plages dans une vue de texte. J'utilise la fonction - (CGRect)firstRectForRange:(UITextRange *)range; pour le faire. Cependant, je n'arrive pas à trouver comment créer réellement un UITextRange .

Voici en gros ce que je recherche :

- (CGRect)frameOfTextRange:(NSRange)range inTextView:(UITextView *)textView {

    UITextRange*range2 = [UITextRange rangeWithNSRange:range]; //DOES NOT EXIST 
    CGRect rect = [textView firstRectForRange:range2];
    return rect;
}

Apple dit qu'il faut sous-classer UITextRange y UITextPosition afin d'adopter le UITextInput protocole. Je ne fais pas cela, mais j'ai quand même essayé, en suivant le code d'exemple de la doc et en passant la sous-classe à firstRectForRange ce qui a entraîné un crash.

S'il existe un moyen plus simple d'ajouter des couleurs différentes UILables à une vue de texte, s'il vous plaît dites-moi. J'ai essayé d'utiliser UIWebView avec content editable mis à TRUE, mais je n'aime pas communiquer avec JS, et la coloration est la seule chose dont j'ai besoin.

Merci d'avance.

0voto

VictorN Points 11

Swift 4 de la réponse de Nicolas Bachschmidt comme une UITextView extension utilisant swifty Range<String.Index> au lieu de NSRange :

extension UITextView {
    func frame(ofTextRange range: Range<String.Index>?) -> CGRect? {
        guard let range = range else { return nil }
        let length = range.upperBound.encodedOffset-range.lowerBound.encodedOffset
        guard
            let start = position(from: beginningOfDocument, offset: range.lowerBound.encodedOffset),
            let end = position(from: start, offset: length),
            let txtRange = textRange(from: start, to: end)
            else { return nil }
        let rect = self.firstRect(for: txtRange)
        return self.convert(rect, to: textInputView)
    }
}

Utilisation possible :

guard let rect = textView.frame(ofTextRange: text.range(of: "awesome")) else { return }
let awesomeView = UIView()
awesomeView.frame = rect.insetBy(dx: -3.0, dy: 0)
awesomeView.layer.borderColor = UIColor.black.cgColor
awesomeView.layer.borderWidth = 1.0
awesomeView.layer.cornerRadius = 3
self.view.insertSubview(awesomeView, belowSubview: textView)

-1voto

SAKrisT Points 2229

Voici l'explication.

Un objet UITextRange représente une plage de caractères dans un conteneur de texte. en d'autres termes, il identifie un index de début et un index de fin dans la chaîne de caractères qui soutient une entrée de texte. un index de début et un index de fin dans la chaîne de caractères qui soutient un objet d'entrée de texte.

Les classes qui adoptent le protocole UITextInput doivent créer des fichiers UITextRange pour représenter les plages de texte gérées par la classe. la classe. Les indices de début et de fin de la plage sont représentés par des objets UITextPosition. Le système de texte utilise les deux objets UITextRange et UITextPosition pour communiquer des informations sur la mise en page du texte. de texte. Il y a deux raisons d'utiliser des objets pour les plages de texte plutôt que des types primitifs tels que NSRange :

Certains documents contiennent des éléments imbriqués (par exemple, des balises HTML et des éléments de type objets incorporés) et vous devez suivre à la fois la position absolue et la la position dans le texte visible.

Le framework WebKit, sur lequel est basé le système de texte de l'iPhone, exige que les index et les décalages de texte soient représentés par des objets.

Si vous adoptez le protocole UITextInput, vous devez créer un fichier UITextRange personnalisée ainsi qu'une sous-classe UITextPosition personnalisée.

Par exemple, comme dans ces sources

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X