设置文本属性后正在重置 UITextView 样式

我有 UITextView *_masterText和后调用方法 setText属性字体正在被重置。 这是在我改变了第七阶段之后发生的。 _ master Text 是 IBOutlet,全局和属性是在故事板中设置的。这只是我还是一般的 SDK 错误?

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


@implementation myViewController


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

编辑:

在 iOS7中为 UITextView 设置字体对我来说很有用,如果你先设置文本,然后再设置字体:

@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 中添加一些文本并更改字体或颜色,那么它将正常工作。

拿着这个坐了几个小时,我发现了窃听器。 如果属性“ Selectable”= NO,它将在使用 setText 时重置字体和字体颜色。

所以打开 Selectable ON,bug 就消失了。

如果这个问题我自己和上面的答案有帮助的话,我会像下面这样在 ViewController 代码中添加一个包装器,只需要传递 uiview 实例和文本进行修改,然后包装函式就会打开选择器的值,修改文本,然后再次关闭它。当您需要 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];
}
}

我遇到了同样的问题(在 Xcode 6.1上) ,当 John Cogan 的回答适合我的时候,我发现用类别扩展 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

我有这个问题。 一个快速友好的解决方案@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;
}
}
}

希望能有所帮助。

在 iOS 8.3中,在 setText 之前设置“可选”为 YES,之后设置“ NO”的解决方案并没有为我解决这个问题。

我发现我需要在故事板中设置“可选”为 YES,在此之前,这将工作。

如果您希望您的文本视图是“只读”,您可以选择可编辑和可选择,并取消选中用户交互启用,与此 UITextView 的行为是我想要的

enter image description here

enter image description here

对于具有属性化文本的我来说,我只需要在属性字典中设置字体,而不是在它自己的字段中设置字体。

下面是我经常用来解决这个问题的一个快速子类解决方案。

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

已经过去3年了,这个 bug 仍然存在于最新的稳定版 Xcode (7.3)中。显然,苹果不会很快修复它,这给开发人员留下了两个选择: 保持可选,并将 UserInteractionEnable 设置为 false 或 Method swizzling。

如果在 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

这对我很有效:

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

这个问题在 Xcode 8中重新出现,我是这样解决的:

改为:

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

并在 Interface Builder 中选择可选项。

使用“可选择的”参数并不是很优雅,但它确实可以。

使用本期讨论的解决方案,UITextView 的这个扩展提供了一个 setTextInCurrentStyle()函数。基于 Alessandro Ranaldi 的解决方案,但不要求将当前 isSelectable 值传递给函数。

extension UITextView{
func setTextInCurrentStyle(_ newText: String) {
let selectablePreviously = self.isSelectable
isSelectable = true
text = newText
isSelectable = selectablePreviously
}
}