ลักษณะ UITextView กำลังถูกรีเซ็ตหลังจากการตั้งค่าคุณสมบัติข้อความ


145

ฉันมีแบบอักษรUITextView *_masterTextและหลังจากsetTextคุณสมบัติการโทรวิธีการจะถูกรีเซ็ต มันเกิดขึ้นหลังจากที่ฉันเปลี่ยน sdk 7 _masterText คือIBOutletglobal และ properties ถูกกำหนดไว้ในกระดานเรื่องราว เป็นเพียงฉันหรือนี่เป็นข้อผิดพลาด SDK ทั่วไป

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

@implementation myViewController

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

คำตอบ:


450

เมื่อนั่งกับสิ่งนี้เป็นเวลาหลายชั่วโมงฉันก็พบข้อผิดพลาด ถ้าคุณสมบัติ "Selectable" = NO มันจะรีเซ็ตแบบอักษรและสีแบบอักษรเมื่อใช้ setText

ดังนั้นเปิด Selectable ON และข้อบกพร่องหายไป


15
สิ่งนี้เกิดขึ้นกับฉันใน Xcode 5 วิธีแก้ปัญหาของฉันคือการตั้งค่า selectable = YES ชั่วคราวก่อนที่จะเรียก setText:
Rollin_s

8
ว้าวช่างเป็นแมลงที่ไร้สาระ ขอบคุณสำหรับความเข้าใจ!
คาห์

3
ขอบคุณมาก ๆ !
Magurizio

6
6.4 ยังมีปัญหานี้
RndmTsk

4
ดูเหมือนว่าจะได้รับการแก้ไขใน iOS 10 หากคุณยังคงกำหนดเป้าหมาย iOS 9 หรือต่ำกว่าคุณจะต้องแก้ไขปัญหา
user1184205

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

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

มีปัญหานี้ด้วยตัวเองและคำตอบข้างต้นช่วย แต่ฉันเพิ่ม wrapper ในรหัส ViewController ของฉันดังนี้และเพิ่งผ่านตัวอย่าง uiview และข้อความที่จะเปลี่ยนและฟังก์ชั่น wrapper สลับค่า 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];
    }
}

1
อาจดีกว่า subclass 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

ลืม [super viewWillAppear: animated];
Jordan Montel

ฉันลืมไปแล้ว แต่นั่นไม่ได้ส่งผลกระทบต่อ :(
Błażej

ทำความสะอาดและรีสตาร์ท XCode ของคุณเพราะมันใช้ได้ดีสำหรับฉันโดยไม่มีบรรทัด "_myTextView.font ... " แม้ว่าฉันจะเปลี่ยนแบบอักษรจากไฟล์ XIB
Jordan Montel

ทำความสะอาดเริ่มต้นใหม่และไม่มีผลกระทบ โครงการ> การปรับใช้ iOS เป้าหมาย 7.0, ฐาน SDK 7.0 ในเป้าหมายการตั้งค่าเดียวกัน
Błażej

2

นี่เป็นวิธีแก้ปัญหา subclass ด่วนที่ฉันมักใช้กับปัญหานี้

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

และตรวจสอบตัวเลือกที่เลือกได้ในเครื่องมือสร้างส่วนต่อประสาน

มันไม่ได้สวยงามมากที่จะมีพารามิเตอร์ 'selectable' แต่มันจะทำ


1

ใน iOS 8.3 การแก้ปัญหาของการตั้งค่า "selectable" เป็น YES ก่อน setText และ NO after ไม่ได้แก้ไขให้ฉัน

ฉันพบว่าฉันต้องการตั้งค่า "selectable" เป็น YES ในกระดานเรื่องราวด้วยก่อนหน้านี้จะใช้งานได้


คุณบันทึกวันของฉันฉันเชื่อว่านี่เป็นข้อผิดพลาดที่น่าหัวเราะอีกครั้งใน CocoaTouch
Chris


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 เป็นเท็จหรือวิธีการกระเพื่อม

หากคุณมีปุ่มบนข้อความของคุณดูเดิมจะไม่พอเพียง

วิธีการแก้ปัญหาที่ไม่มีรหัสเปลี่ยนแปลงอย่างรวดเร็ว:

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

เมื่อใช้วิธีแก้ไขปัญหาที่กล่าวถึงในส่วนขยายนี้ไปยัง UITextView จะมีsetTextInCurrentStyle()ฟังก์ชัน อ้างอิงโซลูชันโดย Alessandro Ranaldi แต่ไม่ต้องการให้ค่า isSelectable ปัจจุบันถูกส่งผ่านไปยังฟังก์ชัน

extension UITextView{
    func setTextInCurrentStyle(_ newText: String) {
        let selectablePreviously = self.isSelectable
        isSelectable = true
        text = newText
        isSelectable = selectablePreviously
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.