动画时 UITableView 剪辑到边界

Posted

技术标签:

【中文标题】动画时 UITableView 剪辑到边界【英文标题】:UITableView clips to bounds while animating 【发布时间】:2017-08-28 20:52:04 【问题描述】:

我有一个 UITableView,其中一些单元格有阴影。 当我做出平移手势以查看任何单元格的行操作时,表格视图会剪切单元格的边界,直到手势完成。

我在单元格的contentView 及其父视图以及表格视图中将clipsToBounds 设置为false

我的自定义单元格代码:

var isExpanded: Bool = false

@IBOutlet weak var shadowView: UIView!
@IBOutlet weak var fullContainer: UIView!

override func awakeFromNib() 
    super.awakeFromNib()
    reloadUI()


func reloadUI() 
    contentView.superview?.clipsToBounds = false
    contentView.clipsToBounds = false

    fullContainer.layer.masksToBounds = true
    fullContainer.layer.cornerRadius = 8

    shadowView.layer.masksToBounds = false
    shadowView.layer.cornerRadius = 8
    shadowView.layer.shadowOpacity = 1.0
    shadowView.layer.shadowOffset = CGSize(width: 0.0, height: 0.0)
    shadowView.layer.shadowPath = UIBezierPath(roundedRect: fullContainer.bounds, cornerRadius: 8).cgPath


override func setSelected(_ selected: Bool, animated: Bool) 
    super.setSelected(selected, animated: animated)
    isExpanded = selected
    reloadUI()

带有tableview的viewcontroller代码:

extension SecondViewController: UITableViewDelegate 

    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool 
        return true
    

    func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? 
        let action = UITableViewRowAction(style: .destructive, title: "Delete")  (action, indexPath) in
            tableView.deleteRows(at: [indexPath], with: .automatic)
        
        return [action]
    

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
        tableView.reloadRows(at: [indexPath], with: .automatic)
        selectedIndex = indexPath.section
    

    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat 
        return section != 0 ? 8 : 1
    

    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? 
        let view = UIView()
        view.clipsToBounds = false
        return view
    

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat 
        if selectedIndex == indexPath.section 
            return 120
        
        return 108
    

SecondViewController 也有这个代码,因为它有一个平移识别器,可以通过手势在视图控制器之间进行切换

extension SecondViewController: UIGestureRecognizerDelegate 

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool 
        if gestureRecognizer == recognizer || otherGestureRecognizer == recognizer 
            return false
        
        return true
    

    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool 
        if gestureRecognizer == recognizer
            for cell in tableView.visibleCells 
                let location = gestureRecognizer.location(in: cell.contentView)
                if cell.contentView.layer.contains(location) 
                    return false
                
            
            return true
        
        return true
    

边界被剪裁的 UITableViewCell:

【问题讨论】:

你能贴一些代码来帮助你吗? 当然,我刚刚添加了很多代码 我不确定,但我认为你的代码过于复杂,或者我遗漏了一些东西,你能告诉我fullContainer的功能是什么@我已经解决了你的问题,但我不确定你的fullContainerView 需要一些东西,我的解决方案没有它也可以工作 层次结构是shadowView-> fullContainer 整个容器更像是我从另一个开发人员那里学到的“好习惯”,但在这种情况下我使用它是因为我需要圆角和阴影 您可以从情节提要中发布您的视图层次结构吗? 【参考方案1】:

这看起来像是 UITableView 中的一个错误。可以通过以下扩展来解决:

extension UITableView 
    func fixCellBounds() 
        DispatchQueue.main.async  [weak self] in
            for cell in self?.visibleCells ?? [] 
                cell.layer.masksToBounds = false
                cell.contentView.layer.masksToBounds = false
            
        
    

调用reloadRows/insertRows/deleteRows等后调用即可:

tableView.reloadRows(at: <index paths>, with: .automatic)
tableView.fixCellBounds()

之前:

之后:

【讨论】:

这应该是公认的答案。我在动画 GIF 中注意到的一件事,上面单元格的阴影投射在下面的单元格上。有没有办法防止这种情况,使所有单元格看起来都在所有阴影之上? 我对这个问题有另一种解决方案,但仍然受到您在此处描述的启发。这是link

以上是关于动画时 UITableView 剪辑到边界的主要内容,如果未能解决你的问题,请参考以下文章

如何阻止扩展舞台的动画剪辑的边缘进入 AS3 中的舞台边界?

ios试图让文本剪辑超出uitableview单元格的范围

iOS 7 UITableViewCell 剪辑暂时

将 UITableView 单元格滚动到表格边界之外

Android ScrollView 在旋转动画上丢失剪辑

在动画上滴 SVG 剪辑路径