146

我有UITextView *_masterText并且在调用方法setText属性字体被重置之后。它发生在我更改 sdk 7 之后。 _masterText 是IBOutlet,全局和属性在情节提要中设置。只有我还是这是一般的 SDK 错误?

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

@implementation myViewController

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

13 回答 13

451

坐了几个小时,我发现了这个错误。如果属性“Selectable”=NO,它将在使用 setText 时重置字体和 fontcolor。

所以打开 Selectable ON 并且错误消失了。

于 2013-10-01T12:17:23.317 回答
11

我遇到了同样的问题(在 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
于 2014-10-22T23:23:40.570 回答
8

If you want your text view to be "read only" you can check Editable and Selectable and uncheck User Interaction Enabled, with this the UITextView was behaving as I wanted

enter image description here

enter image description here

于 2015-09-08T20:23:07.813 回答
6

我自己遇到了这个问题,上面的答案有帮助,但是我在我的 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];
    }
}
于 2013-12-28T19:26:52.513 回答
2

编辑 :

如果首先设置文本然后设置字体,则在 iOS 7 中为 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 中添加一些文本并更改字体或颜色,它将起作用。

于 2013-09-27T12:07:04.627 回答
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
        }
    }
}
于 2016-05-20T14:39:12.973 回答
2

这个问题在 Xcode 8 中重新出现。这就是我修复它的方法:

将扩展名更改为:

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

并检查了 Interface Builder 中的 Selectable 选项。

拥有那个“可选”参数并不是很优雅,但它会做到的。

于 2017-02-22T15:20:32.533 回答
1

在 iOS 8.3 中,在 setText 之前将“可选”设置为 YES,之后设置为 NO 的解决方法并没有为我解决。

我发现我也需要在情节提要中将“可选择”设置为“是”,然后才能使用。

于 2015-06-15T13:18:59.230 回答
1

这对我有用:

let font = textView.font
textView.attributedText = attributedString
textView.font  = font
于 2016-10-15T14:25:12.237 回答
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;
        }
    }
}

希望能帮助到你。

于 2015-03-19T17:13:32.127 回答
0

使用此问题中讨论的解决方法,此 UITextView 扩展提供了一个setTextInCurrentStyle()功能。基于 Alessandro Ranaldi 的解决方案,但不需要将当前 isSelectable 值传递给函数。

extension UITextView{
    func setTextInCurrentStyle(_ newText: String) {
        let selectablePreviously = self.isSelectable
        isSelectable = true
        text = newText
        isSelectable = selectablePreviously
    }
}
于 2017-08-24T22:59:59.417 回答
0

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

如果您的 textView 上有一个按钮,则前者是不够的。

swift中无需更改代码的解决方案:

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
于 2016-08-28T13:27:26.240 回答
0

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

于 2015-12-10T21:31:04.377 回答