Kiểu UITextView đang được đặt lại sau khi đặt thuộc tính văn bản


145

Tôi có UITextView *_masterTextvà sau khi setTextphông chữ thuộc tính phương thức cuộc gọi đang được thiết lập lại. Điều đó xảy ra sau khi tôi thay đổi sdk 7. _masterText là IBOutlet, toàn cầu và các thuộc tính được đặt trong bảng phân cảnh. Chỉ có tôi hoặc đây là lỗi SDK chung?

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

@implementation myViewController

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

Câu trả lời:


450

Ngồi với cái này hàng giờ, tôi thấy lỗi. Nếu thuộc tính "Có thể chọn" = KHÔNG, nó sẽ đặt lại phông chữ và phông chữ khi setText được sử dụng.

Vì vậy, bật Chọn có thể BẬT và lỗi đã biến mất.


15
Điều này cũng xảy ra với tôi trong Xcode 5. Cách giải quyết của tôi là tạm thời đặt có thể chọn = CÓ trước khi gọi setText:
Rollin_s

8
Wow, thật là một lỗi vô lý. Cảm ơn vì sự sáng suốt!
Mi-chê

3
Cảm ơn bạn rât nhiêu !
Magurizio

6
6.4 vẫn có vấn đề này
RndmTsk

4
Điều này dường như được khắc phục trong iOS 10, nếu bạn vẫn nhắm mục tiêu iOS 9 trở xuống, bạn sẽ cần phải giải quyết.
dùng1184205

11

Tôi gặp vấn đề tương tự (trên Xcode 6.1) và trong khi câu trả lời của John Cogan làm việc cho tôi, tôi thấy rằng việc mở rộng lớp UITextView với một danh mục là một giải pháp tốt hơn cho dự án cụ thể của tôi.

giao diện

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

thực hiện

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

1
Và nhanh chóng:extension UITextView { func setSafeText(text: String){ let originalSelectable = selectable selectable = true self.text = text selectable = originalSelectable } }
chút

8

Nếu bạn muốn chế độ xem văn bản của mình ở chế độ "chỉ đọc", bạn có thể kiểm tra Có thể chỉnh sửa và có thể chọn và bỏ chọn Kích hoạt tương tác người dùng, với điều này, UITextView đã hoạt động như tôi muốn

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây


3
Đây có vẻ là một giải pháp khả thi, nhưng cuối cùng không phải là một lựa chọn tốt cho UITextView. Thông thường bạn chọn UITextView vì bạn cần một vùng văn bản có thể cuộn. vô hiệu hóa Tương tác người dùng cũng vô hiệu hóa chế độ xem cuộn. Đối với tôi, sự lựa chọn sử dụng UITextView là vì tôi có một khu vực cần giữ nhiều văn bản hơn mức có thể phù hợp với khu vực đó và có thể cuộn.
jrczer

6

Có vấn đề này với bản thân tôi và câu trả lời ở trên đã giúp tôi nhưng tôi đã thêm một trình bao bọc vào mã ViewContoder của mình như sau và chỉ cần chuyển đối tượng và văn bản uiview để thay đổi và chức năng trình bao bọc bật giá trị có thể chọn, thay đổi văn bản và sau đó tắt nó đi. Hữu ích khi bạn cần tắt uitextview mọi lúc.

/*
    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
Có thể tốt hơn để phân lớp UITextView và ghi đè setText và sử dụng lớp con của bạn trong ứng dụng
powerj1984

2

BIÊN TẬP :

Cài đặt phông chữ cho UITextView trong iOS 7 hoạt động với tôi nếu trước tiên bạn đặt văn bản và sau đó bạn đặt phông chữ:

@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

}

Trên tệp XIB, nếu bạn thêm một số văn bản trong UITextView của bạn và thay đổi phông chữ hoặc màu sắc, nó sẽ hoạt động.


hmm .. tôi sử dụng tài sản nhưng không thay đổi
Błażej

quên [siêu viewWillAppear: hoạt hình];
Jordan Montel

Tôi đã quên nó, nhưng điều đó không ảnh hưởng đến :(
Błażej

làm sạch và khởi động lại XCode của bạn vì nó hoạt động tốt với tôi mà không cần dòng "_myTextView.font ..." ngay cả khi tôi thay đổi phông chữ từ tệp XIB
Jordan Montel

Sạch sẽ, reastart và không có tác dụng. Dự án> Mục tiêu triển khai iOS 7.0, SDK cơ sở 7.0 trong cùng một cài đặt.
Błażej

2

Đây là một giải pháp phân lớp nhanh mà tôi thường sử dụng cho vấn đề này.

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

Vấn đề này xuất hiện trở lại trong Xcode 8. Đây là cách tôi khắc phục nó:

Đã thay đổi phần mở rộng thành:

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

và kiểm tra tùy chọn Có thể chọn trong Trình tạo giao diện.

Thật không thanh lịch khi có thông số 'có thể lựa chọn' nhưng nó sẽ làm được.


1

Trong iOS 8.3, cách giải quyết của việc đặt "có thể chọn" thành CÓ trước setText và KHÔNG sau đó, đã không sửa nó cho tôi.

Tôi thấy tôi cũng cần phải đặt "có thể chọn" thành CÓ trong bảng phân cảnh, trước khi điều này hoạt động.


Bạn đã cứu ngày của tôi, tôi tin rằng đây chỉ là một lỗi vô lý khác trong Cốc Cốc
Chris

1

Điều này làm việc cho tôi:

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

0

Đối với tôi với văn bản được gán, tôi chỉ cần đặt phông chữ trong từ điển thuộc tính thay vì đặt nó trong trường riêng của nó.


0

Tôi đang có vấn đề này để. Một giải pháp thân thiện với câu trả lời của @Ken Steele. Tôi mở rộng UITextView và thêm một thuộc tính được tính toán.

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

hy vọng nó giúp.


0

Đã 3 năm và lỗi vẫn tồn tại trong phiên bản ổn định mới nhất của Xcode (7.3). Rõ ràng apple sẽ không sửa nó bất cứ lúc nào sớm khiến các nhà phát triển có hai tùy chọn: để lại có thể chọn và đặt UserInteractionEnables thành false hoặc Phương thức swizz.

Nếu bạn có một nút trên textView của bạn, cái trước sẽ không đủ.

Giải pháp không cần thay đổi mã trong 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
        }
    }
}

Mục tiêu-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

Sử dụng công việc được thảo luận trong vấn đề này, phần mở rộng này cho UITextView cung cấp một setTextInCurrentStyle()chức năng. Dựa trên giải pháp của Alessandro Ranaldi nhưng không yêu cầu giá trị isSelectable hiện tại được truyền cho hàm.

extension UITextView{
    func setTextInCurrentStyle(_ newText: String) {
        let selectablePreviously = self.isSelectable
        isSelectable = true
        text = newText
        isSelectable = selectablePreviously
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.