Подтвердить что ты не робот

Медленное время загрузки для пользовательского UIView с использованием свойства UITextView в Swift

Я изначально спросил этот вопрос. Я предположил, что причиной медленного времени загрузки моего пользовательского представления было из-за многослойного отображения нескольких точек зрения или, возможно, из-за некоторой проблемы рекурсии. Однако, вырезав все больше и больше кода, чтобы понять, что будет иметь значение, все сводилось к тому, имел ли я UITextView подарок или нет. Поскольку явный источник моей проблемы настолько отличается от того, что я ожидал в своем первом вопросе, я решил начать новый вопрос, а не добавлять длительное обновление к старому.

Я установил свой тестовый проект двумя диспетчерами. Кнопка на первом контроллере представления вызовет серию show во второй контроллер представления. На втором контроллере есть мой пользовательский вид. (Используя второй контроллер просмотра, позвольте мне понять, сколько времени потребовалось для загрузки пользовательского представления.)

Пользовательский код просмотра:

import UIKit

@IBDesignable class UIMongolTextView: UIView {

    var textView = UITextView() // key line

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override init(frame: CGRect){
        super.init(frame: frame)
    }
}

Как вы можете видеть, единственное отличие от UIView заключается в том, что я добавил свойство UITextView. И это настраиваемое представление загружается очень медленно. Запуск инструмента "Выделения" в "Инструменты" я получаю следующие результаты (счет 997):

введите описание изображения здесь

Однако, если я прокомментирую строку

    //var textView = UITextView()

тогда я пользовательский просмотр загружается очень быстро и имеет только счет 7.

введите описание изображения здесь

Что здесь происходит? Возможно ли использовать свойство UITextView в пользовательском представлении и избежать этого медленного времени загрузки?

4b9b3361

Ответ 1

Пробовал что-то подобное, когда метка и текстовое поле были добавлены как подзаголовки в подкласс uiview. Я сделал так:

@interface CustomTextField : UIView

@property (weak, nonatomic) IBOutlet UITextField *valueField;

@end

Итак, у нас был xib файл, на котором мы фактически добавляем метку и текстовое поле. В файле xib владельцем файла является "CustomTextField", и выходы связаны с файлом заголовка оттуда.

Метод конструктора выглядит следующим образом:

- (id)initWithValue:(NSString *)value
{
    self = [super initWithFrame:CGRectZero];
    if (self) {
        NSArray *nibs = [[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:self options:nil];
        UIView *view = nibs[0];
        self.valueField.frame = view.bounds;
        [self setFrame:view.bounds];
        [self addSubview:view];
        [self.valueField setText:value];
    }

    return self;
}

Прекрасно работает для меня.

Ответ 2

Узким местом является свойство selectable вашего UITextView. Существует необъяснимая проблема производительности при создании UITextView с selectable, установленным по умолчанию значением true.

Самый простой способ обойти эту проблему - добавить текстовое представление с помощью раскадровки, убедившись, что вы отключили свойство selectable. Как представляется, не существует документального способа создания неселективного текстового представления в коде (поскольку параметр, выбираемый как false после создания, не позволяет избежать проблем с производительностью во время создания). Если вам нужно выбрать текстовое представление, сначала создайте неселективный текстовый вид, а затем установите для него значение true в viewDidAppear.

Если вы не можете использовать раскадровку, вам может потребоваться использовать сторонний класс, например TTTAttributedLabel.

Похоже, что Apple использует частный API, чтобы избежать этой проблемы. Другие предприимчивые разработчики обнаружили, что в ChatKit текстовые представления создаются с использованием частного метода под названием initReadonlyAndUnselectableWithFrame:textContainer:.

Ответ 3

скачал ваш код из github, почему бы вам просто не написать подкласс UITextView вместо UIView?

//
//  UIMongolTextView-A.swift
//  Mongol App Componants
//
//  Created by Allen Zhang on 12/13/15.
//  Copyright © 2015 MongolSuragch. All rights reserved.
//

import UIKit

class UIMongolTextView_A: UITextView {

    override func awakeFromNib() {
        super.awakeFromNib()
        self.setup()
    }

    func setup() {
        // 1-10: ᠨᠢᠭᠡ ᠬᠤᠶᠠᠷ ᠭᠤᠷᠪᠠ ᠳᠦᠷᠪᠡ ᠲᠠᠪᠤ ᠵᠢᠷᠭᠤᠭ᠎ᠠ ᠳᠤᠯᠤᠭ᠎ᠠ ᠨᠠᠢ᠌ᠮᠠ ᠶᠢᠰᠦ ᠠᠷᠪᠠ

        self.transform = translateRotateFlip()


    }

    /*
    // Only override drawRect: if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func drawRect(rect: CGRect) {
        // Drawing code
    }
    */
    func translateRotateFlip() -> CGAffineTransform {

        var transform = CGAffineTransformIdentity

        // translate to new center
        transform = CGAffineTransformTranslate(transform, (self.bounds.width / 2)-(self.bounds.height / 2), (self.bounds.height / 2)-(self.bounds.width / 2))
        // rotate counterclockwise around center
        transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2))
        // flip vertically
        transform = CGAffineTransformScale(transform, -1, 1)

        return transform
    }
}

Ответ 4

У меня была очень похожая проблема производительности с UITextView, но я думаю, что причина и решение для меня были разными.

У меня был UITextView со статическим текстом на раскадровке. Он не редактировался и не был выбран. При медленном подключении iPod Touch ViewController займет 5 секунд.

Оказывается, что в статическом тексте у меня был эможи. Когда я удалил эможи, проблема исчезла! Я использовал инструменты, чтобы вникать в то, что происходило, и около 25 уровней в глубине следа, который он получал в кучу... шрифтов... методов. Я использовал системный шрифт без атрибутов, поэтому первая идея, которая пришла на ум, была символом эможи в моем тексте.