Ответ 1
Сидя с этим в течение нескольких часов, я нашел ошибку. Если свойство "Selectable" = NO, оно будет reset шрифтом и fontcolor при использовании setText.
Итак, включите Selectable ON, и ошибка исчезла.
У меня есть UITextView *_masterText
, а после метода вызова setText
шрифт свойства reset.
Это происходит после изменения sdk 7.
_masterText IBOutlet
, глобальный и свойства задаются в раскадровке. Это только я или это общая ошибка SDK?
@interface myViewController : UIViewController
{
IBOutlet UITextView *_masterText;
}
@implementation myViewController
-(void)viewWillAppear:(BOOL)animated
{
[_masterText setText:@"New text"];
}
Сидя с этим в течение нескольких часов, я нашел ошибку. Если свойство "Selectable" = NO, оно будет reset шрифтом и fontcolor при использовании setText.
Итак, включите Selectable ON, и ошибка исчезла.
Я столкнулся с той же проблемой (на 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
Если вы хотите, чтобы ваше текстовое представление было "только для чтения", вы можете проверить Editable и Selectable и снять флажок User Interaction Enabled, при этом UITextView вел себя так, как я хотел
Если бы эта проблема была сама, и приведенный выше ответ помог, но я добавил обертку к моему коду ViewController следующим образом и просто передаю экземпляр uiview и текст для изменения, а функция-обертка переключает значение Selectable, меняет текст, а затем отключает его еще раз. Полезно, когда вам нужно, чтобы uitextview всегда отключался по умолчанию.
/*
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];
}
}
EDIT:
Настройка шрифта для 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 и измените шрифт или цвет, он будет работать.
Здесь быстрое решение подкласса, которое я часто использую для этой проблемы.
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
}
}
}
Эта проблема появилась в Xcode 8. Вот как я ее исправил:
Изменено расширение:
extension UITextView{
func setTextAvoidXcodeIssue(newText : String, selectable: Bool){
isSelectable = true
text = newText
isSelectable = selectable
}
}
и проверил параметр "Выбор" в построителе интерфейса.
Не очень элегантно иметь этот параметр "selectable", но он будет делать.
В iOS 8.3 обходной путь установки "selectable" к YES перед setText и NO после не исправил его для меня.
Я обнаружил, что мне нужно было установить "selectable" в YES в раскадровке, прежде чем это сработает.
Это сработало для меня:
let font = textView.font
textView.attributedText = attributedString
textView.font = font
У меня возникает эта проблема. Ответ на ответное решение @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;
}
}
}
надеюсь, что это поможет.
Для меня с атрибутом текста мне просто нужно было установить шрифт в словаре атрибутов, а не устанавливать его в его собственное поле.
Его было 3 года, и ошибка все еще существует в последней стабильной версии Xcode (7.3). Очевидно, что яблоко не будет исправлять его в ближайшее время, оставляя разработчиков с двумя вариантами: оставляя возможность выбора и устанавливая UserInteractionEnabled на false или метод swizzling.
Если у вас есть кнопка на вашем текстовом элементе, первого будет недостаточно.
Решение без изменения кода в быстром режиме:
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
Используя обход, обсуждаемый в этой проблеме, это расширение для UITextView предоставляет функцию setTextInCurrentStyle()
. На основе решения Алессандро Раналди, но не требует, чтобы текущее значение выбираемого значения передавалось функции.
extension UITextView{
func setTextInCurrentStyle(_ newText: String) {
let selectablePreviously = self.isSelectable
isSelectable = true
text = newText
isSelectable = selectablePreviously
}
}