简体   繁体   English

重新加载数据后,UITableView中的UIView动画不起作用

[英]UIView animation in UITableView doesn't work after reload data

I am facing a strange bug in my app right now. 我现在在我的应用程序中遇到一个奇怪的错误。 I have an extension for UIView that rotates an indicator 90 degrees to the left and right. 我有一个UIView扩展,可将指示器向左右旋转90度。 I am using an UITableViewController as a navigation drawer. 我正在使用UITableViewController作为导航抽屉。 I also added an expandable list and use an UITableViewHeaderFooterView for the main areas (which have subitems). 我还添加了一个可扩展列表,并将UITableViewHeaderFooterView用于主要区域(具有子项)。

The UITableViewHeaderFooterView are like the main 'cells'. UITableViewHeaderFooterView就像主要的“单元格”一样。 And below them are real cells of the UITableView that are deleted and inserted when the user taps the UITableViewHeaderFooterView. 在它们下面是UITableView的真实单元格,当用户点击UITableViewHeaderFooterView时,这些单元格将被删除并插入。

Depending on the URL the WebView (main view) has, I want to update the content of the tableView. 根据WebView(主视图)的URL,我想更新tableView的内容。 As soon as the data changes the animation of the extension no longer works. 数据更改后,扩展程序的动画将不再起作用。 The code still gets executed and the values are correct. 该代码仍将执行,并且值正确。 I just don't see the animation anymore. 我只是看不到动画了。

The UITableViewHeaderFooterView: 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)
    }
}

The method inside the WebViewController: 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()
        }
    })
 }

The UIView extension: 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")
    }

}

The relevant methods for the MenuTableViewController: 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)
    }
}

That's the implementation of the viewForHeaderInSection in my MenuTableViewController: 那就是我的MenuTableViewController中的viewForHeaderInSection的实现:

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()
}

I know it's a lot of code, but I guess it's somehow related to the reloadData() of the tableView. 我知道这是很多代码,但是我想它与tableView的reloadData()有某种关系。 The animation works perfectly fine before I perform the reload. 在执行重新加载之前,动画效果非常好。 If I have not opened the menu before it gets reloaded I also don't see the bug. 如果在重新加载菜单之前没有打开菜单,我也看不到该错误。 It just happens after the first reload of the data (even if the data is exactly the same). 它只是在第一次重新加载数据后发生(即使数据完全相同)。

Again, the animation code still gets executed and the expanded value is the correct one (true/false). 同样,动画代码仍然会执行,并且扩展值是正确的值(是/否)。 I've printed the UIImageView on which the animation takes place to the console and it seems to be the identical view even after the reload. 我已经在控制台上打印了在其上进行动画处理的UIImageView,即使重新加载后,它似乎也是相同的视图。 But the animation doesn't appear. 但是动画没有出现。

It turned out to be a mistake by myself! 原来这是我自己的一个错误! I was using two arrays (sectionHeaders, menuItems). 我正在使用两个数组(sectionHeaders,menuItems)。 I only changed one of them when I received new data. 当我收到新数据时,我只更改了其中之一。 Therefore, there was a mismatch between the cells and the content I was working on. 因此,单元格和我正在处理的内容之间不匹配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM