Lo stile UITextView viene ripristinato dopo aver impostato la proprietà text


145

Ho UITextView *_masterTexte dopo il metodo di chiamata il setTextcarattere della proprietà viene ripristinato. Sta succedendo dopo che cambio sdk 7. _masterText è IBOutlet, globale e le proprietà sono impostate nello storyboard. Sono solo io o questo è un bug generale dell'SDK?

@interface myViewController : UIViewController
{
  IBOutlet UITextView *_masterText;
}

@implementation myViewController

-(void)viewWillAppear:(BOOL)animated
{
    [_masterText setText:@"New text"];
}

Risposte:


450

Seduto con questo per ore, ho trovato il bug. Se la proprietà "Selectable" = NO reimposterà font e fontcolor quando viene utilizzato setText.

Quindi attiva Selectable su ON e il bug è sparito.


15
Questo succede anche a me in Xcode 5. La mia soluzione alternativa è impostare temporaneamente selezionabile = SÌ prima di chiamare setText:
Rollin_s

8
Wow, che insetto ridicolo. Grazie per la comprensione!
Michea il

3
Grazie mille !
Magurizio,

6
6.4 ha ancora questo problema
RndmTsk

4
Questo sembra essere risolto in iOS 10, se stai ancora prendendo di mira iOS 9 o versioni precedenti dovrai fare la soluzione.
user1184205

11

Ho riscontrato lo stesso problema (su Xcode 6.1) e mentre la risposta di John Cogan ha funzionato per me, ho scoperto che l'estensione della classe UITextView con una categoria era una soluzione migliore per il mio progetto specifico.

interfaccia

@interface UITextView (XcodeSetTextFormattingBugWorkaround)
    - (void)setSafeText:(NSString *)textValue;
@end

implementazione

@implementation UITextView (XcodeSetTextFormattingBugWorkaround)
- (void)setSafeText:(NSString *)textValue
{
    BOOL selectable = [self isSelectable];
    [self setSelectable:YES];
    [self setText:textValue];
    [self setSelectable:selectable];
}
@end

1
E in fretta:extension UITextView { func setSafeText(text: String){ let originalSelectable = selectable selectable = true self.text = text selectable = originalSelectable } }
piccolo

8

Se vuoi che la visualizzazione del testo sia "sola lettura" puoi selezionare Modificabile e Selezionabile e deselezionare Interazione utente abilitata, con questo UITextView si stava comportando come volevo

inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine


3
In apparenza questa sembra essere una soluzione praticabile, ma alla fine non è una buona opzione per un UITextView. Normalmente si sceglie un UITextView perché è necessaria un'area di testo scorrevole. la disabilitazione dell'interazione utente disabilita anche la vista di scorrimento. Per me la scelta di usare un UITextView è stata perché avevo un'area che doveva contenere più testo di quanto potesse adattarsi a quell'area ed essere in grado di scorrere.
Jhelzer,

6

Ho risolto questo problema da solo e la risposta di cui sopra mi ha aiutato, ma ho aggiunto un wrapper al mio codice ViewController come segue e ho semplicemente passato l'istanza uiview e il testo da modificare e la funzione wrapper attiva il valore Selezionabile, cambia il testo e poi lo spegne di nuovo. Utile quando hai bisogno che uitextview sia sempre spento per impostazione predefinita.

/*
    We set the text views Selectable value to YES temporarily, change text and turn it off again.
    This is a known bug that if the selectable value = NO the view loses its formatting.
 */
-(void)changeTextOfUiTextViewAndKeepFormatting:(UITextView*)viewToUpdate withText:(NSString*)textValue
{
    if(![viewToUpdate isSelectable]){
        [viewToUpdate setSelectable:YES];
        [viewToUpdate setText:textValue];
        [viewToUpdate setSelectable:NO];
    }else{
        [viewToUpdate setText:textValue];
        [viewToUpdate setSelectable:NO];
    }
}

1
Potrebbe essere meglio sottoclassare UITextView e sovrascrivere setText e utilizzare la sottoclasse nell'app
powerj1984

2

MODIFICARE :

L'impostazione del carattere per UITextView in iOS 7 funziona per me se prima imposti il ​​testo e successivamente imposti il ​​carattere:

@property (nonatomic, weak) IBOutlet UITextView *masterText;

@implementation myViewController

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    _myTextView.text = @"My Text";

    _myTextView.font = [UIFont fontWithName:@"Helvetica.ttf" size:16]; // Set Font

}

Su un file XIB, se aggiungi del testo in UITextView e cambi il carattere o il colore, funzionerà.


hmm .. Uso la proprietà ma nessuna modifica.
Błażej,

dimenticato [super viewWillAppear: animato];
Jordan Montel,

Me ne sono dimenticato, ma ciò non ha influito :(
Błażej,

pulisci e riavvia il tuo XCode perché funziona bene per me senza la riga "_myTextView.font ..." anche se cambio il carattere dal file XIB
Jordan Montel,

Pulito, riavvio e nessun effetto. Progetto> iOS Deployment Target 7.0, Base SDK 7.0 in target le stesse impostazioni.
Błażej,

2

Ecco una rapida soluzione di sottoclasse che utilizzo spesso per questo problema.

class WorkaroundTextView: UITextView {
    override var text: String! {
        get {
            return super.text
        }
        set {
            let originalSelectableValue = self.selectable
            self.selectable = true
            super.text = newValue
            self.selectable = originalSelectableValue
        }
    }
}

2

Questo problema è riemerso in Xcode 8. Ecco come l'ho risolto:

Modificata l'estensione in:

extension UITextView{
    func setTextAvoidXcodeIssue(newText : String, selectable: Bool){
        isSelectable = true
        text = newText
        isSelectable = selectable
    }
}

e ho selezionato l'opzione Selezionabile in Interface Builder.

Non è molto elegante avere quel parametro 'selezionabile' ma lo farà.


1

In iOS 8.3, la soluzione alternativa di impostare "selezionabile" su SÌ prima del setText e NO dopo, non ha risolto il problema per me.

Ho scoperto che dovevo impostare "selezionabile" su YES anche nello storyboard, prima che funzionasse.


Mi hai salvato la giornata, credo che questo sia solo un altro ridicolo bug in CocoaTouch
Chris

1

Questo ha funzionato per me:

let font = textView.font
textView.attributedText = attributedString
textView.font  = font

0

Per me con il testo attribuito, avevo solo bisogno di impostare il carattere nel dizionario degli attributi piuttosto che impostarlo nel suo campo.


0

Sto riscontrando questo problema. Una soluzione semplice per la risposta alla risposta di @Ken Steele. Estendo UITextView e aggiungo una proprietà calcolata.

extension UITextView {
    // For older Swift version output should be NSString!
    public var safeText:String!
        {
        set {
            let selectable = self.selectable;
            self.selectable = true;
            self.text = newValue;
            self.selectable = selectable;
        }
        get {
            return self.text;
        }
    }
}

spero che sia d'aiuto.


0

Sono passati 3 anni e il bug esiste ancora nell'ultima versione stabile di Xcode (7.3). Chiaramente Apple non lo risolverà presto, lasciando presto agli sviluppatori due opzioni: lasciare selezionabile attivo e impostare UserInteractionEnabled su false o Method swizzling.

Se hai un pulsante sul tuo textView, il primo non sarà sufficiente.

Soluzione rapida per la modifica senza codice:

import UIKit

extension UITextView {
    @nonobjc var text: String! {
        get {
            return performSelector(Selector("text")).takeUnretainedValue() as? String ?? ""
        } set {
            let originalSelectableValue = selectable
            selectable = true
            performSelector(Selector("setText:"), withObject: newValue)
            selectable = originalSelectableValue
        }
    }
}

Objective-C:

#import <objc/runtime.h>
#import <UIKit/UIKit.h>

@implementation UITextView (SetTextFix)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = [self class];

        SEL originalSelector = @selector(setText:);
        SEL swizzledSelector = @selector(xxx_setText:);

        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);

        BOOL didAddMethod =
        class_addMethod(class,
                    originalSelector,
                    method_getImplementation(swizzledMethod),
                    method_getTypeEncoding(swizzledMethod));

        if (didAddMethod) {
            class_replaceMethod(class,
                            swizzledSelector,
                            method_getImplementation(originalMethod),
                            method_getTypeEncoding(originalMethod));
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
       }
   });
}

- (void)xxx_setText:(NSString *)text {
    BOOL originalSelectableValue = self.selectable;
    self.selectable = YES;
    [self xxx_setText:text];
    self.selectable = originalSelectableValue;
}

@end

0

Utilizzando la soluzione alternativa discussa in questo numero, questa estensione a UITextView fornisce una setTextInCurrentStyle()funzione. Basato sulla soluzione di Alessandro Ranaldi ma non richiede che l'attuale valore isSelezionabile sia passato alla funzione.

extension UITextView{
    func setTextInCurrentStyle(_ newText: String) {
        let selectablePreviously = self.isSelectable
        isSelectable = true
        text = newText
        isSelectable = selectablePreviously
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.