Сбой в UITableView при анимации UIBarButtonItem - PullRequest
0 голосов
/ 08 сентября 2018

Я использую второй элемент правой панели кнопок в качестве индикатора при успешной синхронизации CloudKit. Однако, если tableView удерживается в прокрутке (с элементами теперь под панелью навигации), когда появляется индикатор, tableView отскакивает синхронно с анимацией. Этого не происходит, если пользователь не взаимодействует с tableView.

Вот GIF, демонстрирующий эффект.

Animated screenshot

Другие UIBarButtonItem настроены в раскадровке. Индикатор синхронизации моего iCloud настроен в коде viewDidLoad():

var cloudIndicator = UIImageView()
cloudIndicator.frame = CGRect(x: 0, y: 0, width: 25, height: 25)
cloudIndicator.contentMode = .center
cloudIndicator.transform = CGAffineTransform.identity
// Get existing right bar button item which was set up in storyboard
var rightButtonItems = self.navigationItem.rightBarButtonItems ?? []
let customButtonItem = UIBarButtonItem(customView: cloudIndicator)
rightButtonItems.append(customButtonItem)
self.navigationItem.rightBarButtonItems = rightButtonItems

Это метод, который анимирует индикатор синхронизации с облаком:

func cloudLabelImageAlert(_ image: UIImage, tintColor: UIColor = .darkGray) {
    DispatchQueue.main.async {
        self.cloudIndicator.alpha = 0
        self.cloudIndicator.transform = CGAffineTransform(scaleX: 0.1, y: 0.1)
        self.cloudIndicator.tintColor = tintColor
        self.cloudIndicator.image = image
        // Animate icon appearing
        UIView.animate(withDuration: 0.4, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 10, options: [], animations: {
            self.cloudIndicator.alpha = 1
            self.cloudIndicator.transform = CGAffineTransform.identity
        }, completion: { didFinish in
            // Animate icon disappearing
            UIView.animate(withDuration: 0.4, delay: 2.0, usingSpringWithDamping: 1.0, initialSpringVelocity: 0, options: [], animations: {
                self.cloudIndicator.alpha = 0
                self.cloudIndicator.transform = CGAffineTransform(scaleX: 0.1, y: 0.1)
            }, completion: nil)
        })
    }
)

Предположительно, эта проблема связана с изменением кадра представления изображения во время анимации, но кажется странным, что это происходит только во время взаимодействия с tableView.

Есть ли способ предотвратить это или лучший способ анимировать представление изображения как элемент панели кнопок?


Редактировать

Благодаря советам в комментариях выясняется, что это происходит из-за перезагрузки табличного представления и не имеет ничего общего с анимацией.

Я нашел проблемный код, который вызывается после синхронизации CloudKit:

if let index = self.tableView.indexPathForSelectedRow {
    self.tableView.deselectRow(at: index, animated: true)
    DispatchQueue.main.asyncAfter(deadline: .now()+1) {
        self.tableView.reloadData() // This is delayed as it was causing problems with autoselection (e.g. after coming from Spotlight or notification)
        let image = UIImage(named: "cloudTick")!
        self.cloudLabelImageAlert(image, tintColor: self.colors[0])
    }
} else {
    self.tableView.reloadData()
    let image = UIImage(named: "cloudTick")!
    self.cloudLabelImageAlert(image, tintColor: self.colors[0])
}

Комментирование строк self.tableview.reloadData() остановило ошибку, но анимация продолжилась, как и ожидалось.

Мне нужно обновить данные на данный момент для пользователя. Есть ли лучший способ сделать это?

Ответы [ 3 ]

0 голосов
/ 27 сентября 2018

Как уже упоминалось в разделе комментариев, вы, вероятно, вызываете метод cloudLabelImageAlert(image:, tintColor:) при загрузке новых ячеек таблицы.

Об обновлении данных я бы предложил использовать метод табличного представления reloadData() после завершения облачной анимации.

0 голосов
/ 27 сентября 2018

Привет, у меня был немного похожий сбой не то же самое, но для меня это было исправлено, установив self.automaticsScrollInsets в false в viewDidLoad и во время анимации imageView для скрытия и показа в заключительном блоке завершения UIView.animate, который я назвал reloadData (). Надеюсь, это поможет и спасибо!

0 голосов
/ 26 сентября 2018

По какой-то загадочной причине ваша панель навигации на мгновение показывает "большой заголовок", что приводит к изменению contentInset tableView.
Поэтому попробуйте вручную отключить большие заголовки в viewDidLoad:

if #available(iOS 11.0, *) {
     navigationItem.largeTitleDisplayMode = .never
     navigationController?.navigationBar.prefersLargeTitles = false
}
...