在视图大小更改时更改 UIView 阴影大小会产生奇怪的效果

Posted

技术标签:

【中文标题】在视图大小更改时更改 UIView 阴影大小会产生奇怪的效果【英文标题】:Changing UIView shadow size on view size change producing weird effect 【发布时间】:2018-05-10 14:16:23 【问题描述】:

我有一个视图,上面有一个平移手势识别器,可以在您向上或向下滑动时增加视图的整体高度。这目前工作得很好,但我还想添加一个我设计的阴影,并确保它与不断变化的可拖动视图的高度保持一致。但是,这会产生一些奇怪的效果,我想看看是否有办法解决这个问题

处理改变视图高度和阴影高度的相关代码如下

// SET SHADOW FOR DRAGABLE VIEW PATH IN VIEW DID LOAD
draggableView.layer.shadowColor = UIColor.black.cgColor
draggableView.layer.shadowOffset = CGSize(width: 0, height: 12)
draggableView.layer.shadowOpacity = 0.33
draggableView.layer.shadowRadius = 8
draggableView.layer.shadowPath = UIBezierPath(roundedRect: 
draggableView.bounds, cornerRadius: 12).cgPath

// INSIDE THE RECOGNIZER HANDLER

if recognizer.state == .began || recognizer.state == .changed 
    translation = recognizer.translation(in: self.view)
    recognizer.setTranslation(CGPoint(x: 0.0, y: 0.0), in: self.view)
    let endPosition = recognizer.location(in: draggableView) // the posiion at which PanGesture Ended
    difference = endPosition.y - startPosition.y
    var newFrame = draggableView.frame
    newFrame.origin.x = draggableView.frame.origin.x
    newFrame.origin.y = draggableView.frame.origin.y + difference
    // HERE WE SET THE HEIGHT OF THE VIEW THAT IS BEING "DRAGGED"
    newFrame.size.height = draggableView.frame.size.height - difference
    // HERE WE UPDATE THE SHADOW PATH WITH THE NEW DRAGGABLE VIEW BOUNDS
    draggableView.layer.shadowPath = UIBezierPath(roundedRect: draggableView.bounds, cornerRadius: 12).cgPath
    draggableView.frame = newFrame

我得到的效果是阴影没有随着当前平移手势及时更新,这是一个看起来像的 gif 图像

我希望有一种方法可以在没有这种奇怪行为的情况下使其工作,尽管我理解这些概念,但我对 swift 还是很陌生,但更多的是关于不真正了解做事的所有最佳方法

【问题讨论】:

先更新frame再更新shadow path试试?即,颠倒代码最后两行的顺序 这行得通,就在一分钟前,我要发布另一个解决方案,而不是指向draggableView 的边界,我创建了一个具有相同宽度和计算高度的新CGRect我刚刚申请了draggableView,它有效,但代码更多,对 DRY 不太友好 还在更新的答案中添加了我的建议以提高性能:) 快乐编码 【参考方案1】:

以下两行代码需要颠倒顺序

draggableView.layer.shadowPath = UIBezierPath(roundedRect: draggableView.bounds, cornerRadius: 12).cgPath
draggableView.frame = newFrame

原因是您正在 PanGesture 委托方法中更新 draggableView 的药水(框架)。但是,在更新可拖动视图(第 2 行)的位置(框架)之前,您正在更新阴影框架(第 1 行)。因此,反转两条线对您有用

建议:

在您的情况下,您正在更新两个视图(可拖动和阴影)的框架。我们可以看到 CPU 正在努力尝试更新它们,因为它是滞后的(尤其是在阴影部分,因为你正在重新绘制它。)

我的建议是您可以创建一个父透明视图并将当前的可拖动视图放入其中并绘制阴影。这只会在您的viewDidLoad 中发生一次。然后在手势删除中,您只会更新父视图的框架。这种情况下,不需要每次都更新阴影,拖动会更流畅

【讨论】:

您是否建议我将阴影放在父视图上并更改父视图的框架高度?因为那是我已经拥有的,但如果我不更新阴影位置,它不会随着容器一起增长,它会保持原始大小

以上是关于在视图大小更改时更改 UIView 阴影大小会产生奇怪的效果的主要内容,如果未能解决你的问题,请参考以下文章

如何在滚动时更改 UIView 大小并延迟

自定义 UI 视图更改帧大小

使用自动调整子视图大小为 UIView 帧大小更改动画

嵌套 UIView 调整大小

如何在启用自动布局的情况下更改 iOS6 中的 UIView 大小?

旋转UIView并使其更改视图大小以适应相对于旋转的空间