Стиль UITextView скидається після встановлення властивості тексту


145

Я шрифт властивості UITextView *_masterTextпісля методу виклику setTextскидає. Це відбувається після того, як я зміню sdk 7. _masterText є IBOutlet, глобальні та властивості встановлюються в раскадровці. Це лише я або це загальна помилка SDK?

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

@implementation myViewController

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

Відповіді:


450

Сидячи з цим годинами, я знайшов помилку. Якщо властивість "Selectable" = НІ, вона скине шрифт та кольоровість шрифту, коли використовується setText.

Тож увімкніть Selectable ON і помилка пішла.


15
Це трапляється зі мною також у Xcode 5. Моє вирішення питання полягає у тимчасовому встановленні вибору = ТАК перед викликом setText:
Rollin_s

8
Нічого собі, який смішний клоп. Дякуємо за розуміння!
Міхей

3
Дякую ДУЖЕ ДУЖЕ!
Маґуріціо

6
6.4 все ще має цю проблему
RndmTsk

4
Здається, це виправлено в iOS 10, якщо все ще націлений на iOS 9 або нижче, вам потрібно буде вирішити проблему.
користувач1184205

11

Я зіткнувся з тим же питанням (на Xcode 6.1), і поки відповідь Джона Когана працювала на мене, я виявив, що розширення класу UITextView категорією було кращим рішенням для мого конкретного проекту.

інтерфейс

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

реалізація

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

1
І швидко:extension UITextView { func setSafeText(text: String){ let originalSelectable = selectable selectable = true self.text = text selectable = originalSelectable } }
маленький

8

Якщо ви хочете, щоб ваше перегляд тексту було "лише для читання", ви можете встановити прапорець для редагування та вибору, і зніміть прапорець Увімкнено взаємодію користувачів, при цьому UITextView поводився так, як я хотів

введіть тут опис зображення

введіть тут опис зображення


3
Це виглядає на поверхні як життєздатне рішення, але в кінцевому рахунку не є вдалим варіантом для UITextView. Зазвичай ви вибираєте UITextView, тому що вам потрібно прокручувати текстову область. відключення взаємодії з користувачем також вимикає подання прокрутки. Для мене вибір використання UITextView стався тому, що у мене була область, в якій потрібно було вмістити більше тексту, ніж міг би вміститися в цій області, і мати можливість прокрутки.
jhelzer

6

Якщо ця проблема допомогла мені самій, і вищевказана відповідь допомогла, але я додав обгортку до свого коду ViewController наступним чином і просто передайте екземпляр і текст uiview для зміни, а функція обгортки вмикає вибране значення, змінює текст, а потім вимикає його знову. Корисно, коли вам потрібно, щоб стандартний перегляд uitext завжди був вимкнено.

/*
    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
Може бути краще підкласи UITextView і переосмислити setText і використовувати свій підклас у додатку
powerj1984,

2

Редагувати:

Налаштування шрифту для UITextView в iOS 7 працює для мене, якщо спочатку ви встановите текст, а потім встановите шрифт:

@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

}

Якщо у файлі XIB ви додали текст у свій UITextView і зміните шрифт або колір, він буде працювати.


Хм .. Я використовую властивість, але ніяких змін.
Błażej

забув [супер viewWillAppear: анімований];
Jordan Montel

Я забув про це, але це не вплинуло :(
Błażej

очистіть і перезапустіть свій XCode, тому що для мене це добре працює без рядка "_myTextView.font ...", навіть якщо я зміню шрифт з файлу XIB
Jordan Montel,

Чистий, перезавантажений та без ефекту. Проект> iOS Deployment Target 7.0, Base SDK 7.0 в цілях тих же налаштувань.
Błażej

2

Ось швидке рішення підкласу, яке я часто використовую для цієї проблеми.

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

Ця проблема з'явилася в Xcode 8. Ось як я її виправив:

Змінено розширення на:

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

і перевірив вибір у програмі Інтерфейс.

Не дуже елегантно мати цей параметр, що вибирається, але все одно.


1

В iOS 8.3, спосіб встановлення "вибір" YES перед setText, а НІ після, не зміг цього виправити.

Я також виявив, що мені потрібно встановити "вибір" ТАК ​​у дошці розкадрування, перш ніж це спрацює.


Ви врятували мені день, я вважаю, що це лише черговий смішний клоп у CocoaTouch
Кріс,


0

Для мене з атрибутивним текстом мені просто потрібно було встановити шрифт у словнику атрибутів, а не встановлювати його у власному полі.


0

Я маю цю проблему. Швидке дружнє рішення відповіді @Ken Steele. Я розширюю UITextView і додаю обчислюване властивість.

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;
        }
    }
}

сподіваюся, що це допомагає.


0

Минуло 3 роки, і помилка все ще існує в останній стабільній версії Xcode (7.3). Очевидно, що яблуко не зможе виправити це незабаром, залишивши розробників двома варіантами: залишити вибір і встановити UserInteractionEnabled на помилковий або метод перемикання.

Якщо у вас є кнопка на вашому textView, попередньої буде недостатньо.

Рішення, яке не потребує змін, швидко

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
        }
    }
}

Завдання-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

Використовуючи обхід, розглянутий у цьому випуску, це розширення на UITextView забезпечує setTextInCurrentStyle()функцію. На основі рішення Алессандро Ранальді, але не вимагає, щоб поточне значення вибору було передано функції.

extension UITextView{
    func setTextInCurrentStyle(_ newText: String) {
        let selectablePreviously = self.isSelectable
        isSelectable = true
        text = newText
        isSelectable = selectablePreviously
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.