Я столкнулся со странной ошибкой в своем приложении прямо сейчас. У меня есть расширение для UIView, которое поворачивает индикатор на 90 градусов влево и вправо. Я использую UITableViewController в качестве навигационного ящика. Я также добавил расширяемый список и использовал UITableViewHeaderFooterView для основных областей (у которых есть подэлементы).
UITableViewHeaderFooterView похож на основные «ячейки». А под ними реальные ячейки UITableView, которые удаляются и вставляются, когда пользователь нажимает на UITableViewHeaderFooterView.
В зависимости от URL-адреса, который имеет WebView (основной вид), я хочу обновить содержимое tableView. Как только данные изменяются, анимация расширения перестает работать. Код по-прежнему выполняется, и значения верны. Я просто больше не вижу анимацию.
UITableViewHeaderFooterView:
import UIKit
class TableSectionHeader: UITableViewHeaderFooterView {
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var containerView: UIView!
@IBOutlet weak var indicatorImage: UIImageView!
override func draw(_ rect: CGRect) {
super.draw(rect)
indicatorImage.image = IconFont.image(fromIcon: .next, size: Constants.Sizes.MENU_INDICATOR_SIZE, color: Constants.Colors.WHITE_COLOR)
}
func setExpanded(expanded: Bool) {
indicatorImage.rotate(expanded ? .pi / 2 : 0.0)
}
}
Метод внутри WebViewController:
private func loadNewMenu(href: String) {
NetworkService.sharedInstance.getNavigation(path: href, completion: { menu in
if let menuController = self.menuVC {
menuController.menuItems = menu
menuController.tableView.reloadData()
}
})
}
Расширение UIView:
import UIKit
extension UIView {
func rotate(_ toValue: CGFloat, duration: CFTimeInterval = 0.2) {
let animation = CABasicAnimation(keyPath: "transform.rotation")
animation.toValue = toValue
animation.duration = duration
animation.isRemovedOnCompletion = false
animation.fillMode = kCAFillModeForwards
self.layer.add(animation, forKey: "rotationIndicator")
}
}
Соответствующие методы для MenuTableViewController:
// MARK: Custom Menu Methods
@objc func handleExpandClose(sender: UITapGestureRecognizer) {
guard let section = sender.view?.tag else {
return
}
var indexPaths = [IndexPath]()
for row in subItems.indices {
let indexPath = IndexPath(row: row, section: section)
indexPaths.append(indexPath)
}
let isExpanded = menuItems[section].isExpanded
menuItems[section].isExpanded = !isExpanded
sectionHeaders[section].setExpanded(expanded: !isExpanded)
if isExpanded {
tableView.deleteRows(at: indexPaths, with: .fade)
} else {
tableView.beginUpdates()
closeOpenedSections(section: section)
tableView.insertRows(at: indexPaths, with: .fade)
tableView.endUpdates()
}
}
private func closeOpenedSections(section: Int) {
var closeIndexPaths = [IndexPath]()
for (sectionIndex, sec) in menuItems.enumerated() {
guard let subItems = sec.subItems, sec.isExpanded, sectionIndex != section else {
continue
}
sec.isExpanded = false
for rowIndex in subItems.indices {
let closeIndexPath = IndexPath(row: rowIndex, section: sectionIndex)
closeIndexPaths.append(closeIndexPath)
}
sectionHeaders[sectionIndex].setExpanded(expanded: false)
tableView.deleteRows(at: closeIndexPaths, with: .fade)
}
}
Это реализация viewForHeaderInSection в моем MenuTableViewController:
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if let sectionHeader = self.tableView.dequeueReusableHeaderFooterView(withIdentifier: "TableSectionHeader") as? TableSectionHeader {
sectionHeader.setUpHeader(emphasize: menuItems[section].emphasize)
sectionHeader.titleLabel.text = menuItems[section].title
let tap = UITapGestureRecognizer(target: self, action: #selector(MenuTableViewController.handleExpandClose(sender:)))
sectionHeader.addGestureRecognizer(tap)
sectionHeader.indicatorImage.isHidden = menuItems[section].subItems != nil ? false : true
sectionHeader.tag = section
self.sectionHeaders.append(sectionHeader)
return sectionHeader
}
return UIView()
}
Я знаю, что это много кода, но я думаю, что это как-то связано с reloadData() tableView. Анимация работает отлично, прежде чем я выполню перезагрузку. Если я не открыл меню до его перезагрузки, я также не вижу ошибки. Это просто происходит после первой перезагрузки данных (даже если данные точно такие же).
Опять же, код анимации все еще выполняется, и расширенное значение является правильным (true/false). Я напечатал UIImageView, на котором происходит анимация, на консоль, и кажется, что это идентичное представление даже после перезагрузки. Но анимация не появляется.
.reloadData()
, можете ли вы запустить анимацию снова? - person DonMag   schedule 29.01.2018CABasicAnimation
, так что просто выскажу мысль... Нужно ли вызывать.removeAnimation(forKey:)
перед повторной анимацией? - person DonMag   schedule 29.01.2018.reloadData()
из блока завершения. Это работает в основном потоке? Мне стоит попытаться обернуть это в блокDispatchQueue.main.async()
и/или убедиться, что вы вызываетеindicatorImage.rotate(...)
в основном потоке. - person DonMag   schedule 29.01.2018.setNeedsDisplay()
в заголовке? - person DonMag   schedule 29.01.2018