9
votes

UITEXTVIEW NSATRIBUTED TAILLE

Je travaille sur une application qui utilise un UITEXTVIEW.

L'UITEXTVIEW devrait se développer ou rétrécir pour s'adapter à son texte, à la fois verticalement et horizontalement. Pour ce faire, je remplace sizetofit dans une sous-classe et je réglais les limites comme: xxx

Le problème est que cette taille ne reflète pas la bonne taille. de la chaîne, comme l'UitextView clips le texte. Je fixe les bords d'embargons à zéro, de sorte que cela ne devrait pas être un problème droit?

À ce stade, je pense que c'est un bug avec la propriété de taille de Nsattributedstring, mais la même chose se produit si j'utilise limitringrectwithsize : Options: contexte: xxx

Alors, peut-être que quel que soit le code effectue des calculs de mise en page pour Nsattributedstring ne joue pas bien aux calculs de mise en page UITEXTVIEW.

Voici exemple projet qui démontre le problème .

Toutes les idées sont les bienvenues!

Edit: Je dois également souligner que ce qui suit ne fonctionne pas non plus: xxx


1 commentaires

Pour une chaîne de texte régulière, j'ai eu recours à une étiquette factice, rétrécissant l'étiquette pour s'adapter, puis prendre ses dimensions.


3 Réponses :


1
votes

Je pense que vous avez raison - je ne pouvais pas obtenir - [NsattributedinglingRectWithSize: Options: Context:] Code> Pour renvoyer une valeur qui fonctionnait correctement pour toutes les tailles de police ...

J'ai obtenu un Uilabel pour former et dessiner correctement des cordes attribuées cependant: p>

  • Modifiez votre classe de visualisation de texte sur Uilabel Code> Li>
  • Utilisez -SetAttributedText: code> sur l'étiquette li>
  • SET label.numberoflines = 0 code> (multiligne) li>
  • dans -Layoutsubviews code> de l'appel de votre étiquette de l'étiquette - [étiquette Sizétethfits:] Pour obtenir la taille correcte pour l'étiquette .... Li> ul>

    a travaillé pour moi ... p>

    Edit: Voici mon fichier ViewController.m Fichier: P>

    @interface View : UIView
    @property ( nonatomic, strong ) UITextView * textView ;
    @property ( nonatomic, strong ) UISlider * fontSizeSlider ;
    @end
    
    @implementation View
    
    -(void)layoutSubviews
    {
        CGRect bounds = self.bounds ;
    
        self.textView.layer.anchorPoint = (CGPoint){ 0.0f, 0.5f } ;
        self.textView.layer.position = (CGPoint){ CGRectGetMinX( bounds ), CGRectGetMidY( bounds ) } ;
        self.textView.bounds = (CGRect){ .size = [ self.textView sizeThatFits:bounds.size ] } ;
    
        self.fontSizeSlider.frame = CGRectMake(5, CGRectGetMaxY(bounds) - 30, bounds.size.width - 10, 25) ;
    }
    
    @end
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    -(void)loadView
    {
        self.view = [[ View alloc ] initWithFrame:CGRectZero ] ;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        NSMutableAttributedString * aString = [[ NSMutableAttributedString alloc ] initWithString:@"Some test text in a scaling text view" ] ;
        NSDictionary * attributes = @{ NSForegroundColorAttributeName : [ UIColor redColor ] } ;
        [ aString setAttributes:attributes range:(NSRange){ 5, 4 } ] ;
    
        textView = [[UITextView alloc] initWithFrame:CGRectZero];
        [textView setAttributedText:aString ];
        [textView setFont:[UIFont systemFontOfSize:18]];
        [textView setCenter:CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds))];
    
        ((View*)self.view).textView = textView ;
        [self.view addSubview:textView];
        [textView release];
    
        UISlider * fontSizeSlider = [[UISlider alloc] initWithFrame:CGRectMake(5, CGRectGetMaxY(self.view.bounds) - 30, self.view.bounds.size.width - 10, 25)];
        [fontSizeSlider addTarget:self action:@selector(fontSizeSliderDidChange:) forControlEvents:UIControlEventValueChanged];
        [fontSizeSlider setMinimumValue:5];
        [fontSizeSlider setMaximumValue:100];
        [fontSizeSlider setValue:textView.font.pointSize];
        ((View*)self.view).fontSizeSlider = fontSizeSlider ;
        [self.view addSubview:fontSizeSlider];
        [fontSizeSlider release];
    }
    
    - (void)fontSizeSliderDidChange:(UISlider *)sender {
        [ textView setFont:[textView.font fontWithSize:sender.value]];
        [ self.view setNeedsLayout ] ;
    }
    
    @end
    


8 commentaires

Bien que l'Uilabel tailles correctement, ce n'est pas éditable. Évidemment, je pourrais éteindre l'étiquette pour une vue UitextView sur Touch Down, mais si elle est possible, j'aimerais éviter cet itinéraire sauf absolument nécessaire.


Bien sûr, mais cela nécessite d'utiliser à la fois un Uilabel et UitextView, qui, comme je l'ai dit, cela ne me dérange pas, mais s'il y a une solution qui utilise simplement une vue UitextView, ce serait génial.


De vos modifications, je pense que nous sommes sur la différence pages ici. Je ne veux pas que le TextView soit la taille de la vue, il devrait s'agir de la taille qu'il a besoin d'adapter le texte, pas plus grand et non plus petit.


C'est exactement ce que ça fait. Il convient à la largeur, mais pousse / rétrécit en hauteur. Essayez mon code.


Droite, votre code s'adapte à la largeur de la vue, qui n'est pas le comportement souhaité, il ne doit être que suffisamment large (la largeur et la hauteur) pour s'adapter au texte, pas plus et pas moins.


Mais c'est le point, ça ne marche pas. Voir le projet exemple, essayez de réduire la taille de la police.


Je suppose continuer à la réduire jusqu'à ce qu'il pousse de hauteur ... j'ai mis à jour mon code.


Sinon, vous devrez utiliser CareText. -BoundRecTwithSize: Options: Contexte: semble être brisé.



4
votes

Bien que non parfait, j'ai fini par utiliser:

- (void)sizeToFit {

    CGSize textSize = self.attributedText.size;
    CGSize viewSize = CGSizeMake(textSize.width + self.firstCharacterOrigin.x * 2,
                                 textSize.height + self.firstCharacterOrigin.y * 2);

    [self setBounds:(CGRect){.size = [self sizeThatFits:viewSize]}];
}

- (CGPoint)firstCharacterOrigin {

    if (!self.text.length) return CGPointZero;

    UITextRange * range = [self textRangeFromPosition:[self positionFromPosition:self.beginningOfDocument offset:0]
                                           toPosition:[self positionFromPosition:self.beginningOfDocument offset:1]];
    return [self firstRectForRange:range].origin;
}


1 commentaires

Veuillez ajouter un chèque si auto a un texte non vide et utilisez uniquement la mise en œuvre de votre FirstCharacterorigin et ajoutez un retour cgpointzero si ne pas. Voir cette Stackoverflow.com/a/18548958/598057 .



0
votes

STROIFT 3 solution pour la solution Tom Irvings ci-dessus:

extension UITextView {
    func sizeToFitAttributedString() {
        let textSize = self.attributedText.size()
        let viewSize = CGSize(width: textSize.width + self.firstCharacterOrigin.x * 2, height: textSize.height + self.firstCharacterOrigin.y * 2)
        self.bounds.size = self.sizeThatFits(viewSize)
    }

    private var firstCharacterOrigin: CGPoint {
        if self.text.lengthOfBytes(using: .utf8) == 0 {
            return .zero
        }
        let range = self.textRange(from: self.position(from: self.beginningOfDocument, offset: 0)!,
                                     to: self.position(from: self.beginningOfDocument, offset: 1)!)
        return self.firstRect(for: range!).origin

    }
}


0 commentaires