Gaya UITextView sedang diatur ulang setelah menyetel properti teks


145

Saya memiliki UITextView *_masterTextdan setelah setTextfont properti metode panggilan sedang diatur ulang. Itu terjadi setelah saya mengubah SDK 7. _masterText adalah IBOutlet, global dan properti diatur dalam storyboard. Hanya saya atau ini bug SDK umum?

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

@implementation myViewController

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

Jawaban:


450

Duduk dengan ini selama berjam-jam, saya menemukan bug. Jika properti "Selectable" = NO itu akan mengatur ulang font dan warna font ketika setText digunakan.

Jadi hidupkan ON Selectable dan bugnya hilang.


15
Ini terjadi pada saya juga di Xcode 5. Solusi saya adalah untuk sementara mengatur selectable = YES sebelum memanggil setText:
Rollin_s

8
Wow, sungguh bug yang konyol. Terima kasih atas wawasannya!
Mikha

3
Terima kasih banyak !
Magurizio

6
6.4 masih memiliki masalah ini
RndmTsk

4
Ini tampaknya diperbaiki di iOS 10, jika Anda masih menargetkan iOS 9 atau di bawah Anda perlu melakukan solusi.
user1184205

11

Saya mengalami masalah yang sama (pada Xcode 6.1) dan sementara jawaban John Cogan bekerja untuk saya, saya menemukan bahwa memperluas kelas UITextView dengan kategori adalah solusi yang lebih baik untuk proyek khusus saya.

antarmuka

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

penerapan

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

1
Dan dalam cepat:extension UITextView { func setSafeText(text: String){ let originalSelectable = selectable selectable = true self.text = text selectable = originalSelectable } }
sedikit

8

Jika Anda ingin tampilan teks Anda menjadi "hanya baca" Anda dapat memeriksa Diedit dan Dipilih dan hapus centang Interaksi Pengguna Diaktifkan, dengan ini UITextView berperilaku seperti yang saya inginkan

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini


3
Ini tampaknya di permukaan menjadi solusi yang layak, tetapi pada akhirnya bukan pilihan yang baik untuk UITextView. Biasanya Anda memilih UITextView karena Anda memerlukan area teks yang dapat digulir. menonaktifkan Interaksi Pengguna juga menonaktifkan tampilan gulir. Bagi saya pilihan untuk menggunakan UITextView adalah karena saya memiliki area yang perlu menampung lebih banyak teks daripada yang bisa muat di area itu, dan dapat menggulir.
jhelzer

6

Seandainya masalah ini sendiri dan jawaban di atas membantu tetapi saya menambahkan pembungkus ke kode ViewController saya sebagai berikut dan hanya meneruskan contoh uiview dan teks untuk berubah dan fungsi pembungkus mengaktifkan nilai yang dipilih pada, mengubah teks dan kemudian mematikannya lagi. Bermanfaat saat Anda membutuhkan uitextview dinonaktifkan setiap saat secara default.

/*
    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
Mungkin lebih baik untuk subclass UITextView dan menimpa setText dan menggunakan subclass Anda di app
powerj1984

2

EDIT:

Mengatur font untuk UITextView di iOS 7 berfungsi untuk saya jika pertama-tama Anda mengatur teks dan setelah itu Anda mengatur font:

@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

}

Pada file XIB, jika Anda menambahkan beberapa teks di UITextView Anda dan mengubah font atau warna itu akan berfungsi.


hmm .. Saya menggunakan properti tetapi tidak ada perubahan.
Błażej

lupa [super viewWillAppear: animated];
Jordan Montel

Saya lupa tentang itu, tapi itu tidak mempengaruhi :(
Błażej

bersihkan dan mulai ulang XCode Anda karena itu berfungsi dengan baik bagi saya tanpa baris "_myTextView.font ..." bahkan jika saya mengubah font dari file XIB
Jordan Montel

Bersih, memulai kembali dan tidak ada efek. Project> iOS Deployment Target 7.0, Base SDK 7.0 di target dengan pengaturan yang sama.
Błażej

2

Inilah solusi subclass cepat yang sering saya gunakan untuk masalah ini.

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

Masalah ini muncul kembali dalam Xcode 8. Ini adalah bagaimana saya memperbaikinya:

Mengubah ekstensi menjadi:

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

dan memeriksa opsi yang dapat dipilih di Interface Builder.

Tidak terlalu elegan untuk memiliki parameter 'dapat dipilih' tetapi itu akan berhasil.


1

Di iOS 8.3, penyelesaian pengaturan "dapat dipilih" untuk YA sebelum setText, dan TIDAK setelahnya, tidak memperbaikinya untuk saya.

Saya menemukan saya perlu mengatur "dipilih" untuk YA di papan cerita juga, sebelum ini akan berhasil.


Anda menyelamatkan hari saya, saya percaya ini hanyalah bug konyol di CocoaTouch
Chris

1

Ini bekerja untuk saya:

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

0

Bagi saya dengan teks yang dikaitkan, saya hanya perlu mengatur font di kamus atribut daripada mengaturnya di bidang itu sendiri.


0

Saya mengalami masalah ini. Solusi jawaban cepat @Ken Steele yang ramah. Saya memperluas UITextView dan menambahkan properti yang dihitung.

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

semoga membantu.


0

Sudah 3 tahun dan bug masih ada di versi stabil terbaru Xcode (7.3). Jelas apel tidak akan memperbaikinya dalam waktu dekat meninggalkan pengembang dengan dua opsi: meninggalkan yang dapat dipilih dan mengatur UserInteractionEnabled menjadi false atau Method swizzling.

Jika Anda memiliki tombol pada textView Anda, yang pertama tidak akan cukup.

Solusi no-code-change-requied dalam cepat:

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

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

Menggunakan work-around yang dibahas dalam masalah ini, ekstensi untuk UITextView ini menyediakan setTextInCurrentStyle()fungsi. Didasarkan pada solusi oleh Alessandro Ranaldi tetapi tidak memerlukan nilai isSelectable saat ini untuk diteruskan ke fungsi.

extension UITextView{
    func setTextInCurrentStyle(_ newText: String) {
        let selectablePreviously = self.isSelectable
        isSelectable = true
        text = newText
        isSelectable = selectablePreviously
    }
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.