Добавление UIView Laggy на определенных моделях iPad - PullRequest
0 голосов
/ 27 февраля 2019

У меня есть программа просмотра PDF для нот, основанная на PDFKit.PDFKit имеет возможность использовать внутренний UIPageViewController, но это очень проблематично - вы не можете установить тип перехода, и, что еще хуже, нет способа проверить, был или нет сбой страницы.В итоге вы видите одну страницу, в то время как сообщаемый индекс страницы - другой.

Поэтому я решил создать свой собственный метод перелистывания страниц.Я добавил UITapGestureRecognizer, и когда правый или левый края касаются, страница переворачивается программно.Чтобы добиться анимации скручивания, я добавляю UIView с тем же изображением, что и под ним, делаю анимацию скручивания в PDFView, а затем удаляю вид.Вот часть кода:

// Function to flip pages with page curl
    func flipPage (direction: String) {
        let renderer = UIGraphicsImageRenderer(size: pdfView.bounds.size)
        let image = renderer.image { ctx in
            pdfView.drawHierarchy(in: pdfView.bounds, afterScreenUpdates: true)
        }
        let imageView = UIImageView(image: image)
        imageView.frame = pdfView.frame
        imageView.tag = 830
        self.view.addSubview(imageView)
        self.view.bringSubviewToFront(imageView)

        if direction == "forward" && pdfView.canGoToNextPage() {
            pdfView.goToNextPage(nil)
            let currentImageView = self.view.subviews.filter({$0.tag == 830})
            if currentImageView.count > 0 {
                UIView.transition(from: currentImageView[0],
                                  to: pdfView, duration: 0.3,
                                  options: [.transitionCurlUp, .allowUserInteraction],
                                  completion: {finished in
                                    currentImageView[0].removeFromSuperview()
                })
            }
        }

Теперь начинается странная часть.На моем собственном iPad Pro 12,9 дюйма 1-го поколения этот метод переворачивается быстро.Независимо от конфигурации сборки или уровня оптимизации, он просто работает.Если я нажимаю быстро, страницы переворачиваются так же быстро, как и я.

У меня есть пользователи с 2-го поколения iPad Pro 12.9, и они испытывают ужасную задержку, когда UIView отображается поверх PDFView.,Это также происходит во всех конфигурациях сборки - это происходило с сборкой выпуска, а также происходило, когда я устанавливал отладочную сборку со своего компьютера на такое устройство (к сожалению, я не мог оставить устройство для дальнейшего изучения).

В приложении есть несколько других экземпляров, в которых я добавляю UIView сверху - для добавления полупрозрачной завесы или для захвата UIGestureRecognizer.На моем собственном устройстве все это очень быстро.На iPad 2-го поколения, каждый вызывает отставание.Кстати, пользователь с iPad Pro третьего поколения сообщил, что на его устройстве производительность была очень высокой, без каких-либо задержек.На симуляторе анимация иногда бывает неполной, но реакция происходит так быстро, как и должно быть - для всех моделей iPad.

Я искал ответы и не нашел абсолютно никаких ссылок на такую ​​странную ситуацию.Кто-нибудь испытывал что-то подобное?Какие-нибудь быстрые исправления или заметные проблемы в логике моего кода?

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

1 Ответ

0 голосов
/ 01 марта 2019

После небольшого исследования я могу предложить решение для людей, которые сталкиваются с подобными проблемами.Кажется, проблема в планировании.

  1. Я до сих пор не знаю, почему модели 2017 года планируют свои потоки по-разному.Любые идеи о том, почему эта проблема возникла в первую очередь, приветствуются.Однако -
  2. На самом деле я не следовал лучшей практике.Изменения в пользовательском интерфейсе всегда должны происходить в основном потоке, поэтому, если вы столкнулись с такой задержкой, инкапсулируйте фактическое добавление и удаление UIView следующим образом:

    DispatchQueue.main.async {
        self.view.addSubview(imageView)
        self.view.bringSubviewToFront(imageView)
    }
    

    Мои пользователи сообщают, что проблема исчезла послечто.

РЕДАКТИРОВАТЬ

Обязательно включите и добавление UIView и блока анимации в один и тот же сегмент DispatchQueue, иначе они будут конкурировать заслот для исполнения.Мой окончательный код выглядит следующим образом:

func flipPage (direction: String) {
        let renderer = UIGraphicsImageRenderer(size: pdfView.bounds.size)
        let image = renderer.image { ctx in
            pdfView.drawHierarchy(in: self.pdfView.bounds, afterScreenUpdates: true)
        let imageView = UIImageView(image: image)
        imageView.frame = pdfView.frame

        if direction == "forward" && pdfView.canGoToNextPage() {
            DispatchQueue.main.async {
                self.view.addSubview(imageView)
                self.view.bringSubviewToFront(imageView)
                self.pdfView.goToNextPage(nil)
                UIView.transition(from: imageView,
                                  to: self.pdfView, duration: 0.3,
                                  options: [.transitionCurlUp, .allowUserInteraction],
                                  completion: {finished in
                                    imageView.removeFromSuperview()
                })
            }
        }

PS Если возможно, избегайте использования drawHierarchy - это не очень быстрый метод.

В любом случае, если вам нужно по-разному кодировать для конкретных устройств, проверьте DeviceKit .Прекрасный проект, который дает вам самый простой интерфейс.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...