如何自定义UIInterpolatingMotionEffect以根据设备方向设置不同的阴影效果?

3
我正在使用UIInterpolatingMotionEffect来生成基于设备倾斜的“阴影效果”。
我有一个带有一些文字的标签,并应用以下代码来获得效果:
// Set shadow properties
let layer = self.label.layer
layer.shadowColor = UIColor.blackColor().CGColor
layer.shadowRadius = 9
layer.shadowOpacity = 0.7
layer.shadowOffset = CGSizeMake(10, 10)

// Set vertical shadow effect
let verticalMotionEffect: UIInterpolatingMotionEffect = UIInterpolatingMotionEffect(keyPath: "layer.shadowOffset.height", type: .TiltAlongVerticalAxis)
verticalMotionEffect.minimumRelativeValue = 100
verticalMotionEffect.maximumRelativeValue = -100
    
// Set horizontal shadow effect
let horizontalMotionEffect: UIInterpolatingMotionEffect = UIInterpolatingMotionEffect(keyPath: "layer.shadowOffset.width", type: .TiltAlongHorizontalAxis)
horizontalMotionEffect.minimumRelativeValue = 100
horizontalMotionEffect.maximumRelativeValue = -100
    
// Create group to combine both
let group = UIMotionEffectGroup()
group.motionEffects = [horizontalMotionEffect, verticalMotionEffect]
    
// Add both effects to the label
self.label.addMotionEffect(group)

结果如下所示: 设备屏幕截图 但是我希望当设备静止或平行于眼睛时,文字是看不见的。因此,人们必须旋转/倾斜设备才能理解写了什么。
字体颜色是白色的。在初始位置,阴影也应该是白色或透明度为0,并随着设备倾斜而逐渐增加透明度和半径。
我找不到一种方法来捕获设备的倾斜值,然后我可以根据条件进行调整以获得我想要的效果。我所有的网络搜索都导向了 CMMotionManager。有没有办法通过 UIInterpolatingMotionEffect 或者 UIMotionEffect 来做到这一点?
提前致谢!
2个回答

2

通过控制图层的阴影不透明度,我成功实现了所需效果。我通过倾斜轴来控制阴影的不透明度,最小值和最大值分别为-1.0和1.0,因为我希望最初的不透明度为0。以下是代码:

let layer = self.layer
layer.shadowColor = UIColor.blackColor().CGColor
layer.shadowRadius = radius
//layer.shadowOpacity = opacity
layer.shadowOffset = CGSizeMake(offset, offset)

// Set vertical shadow effect
let verticalMotionEffect = UIInterpolatingMotionEffect(keyPath: "layer.shadowOffset.height", type: .TiltAlongVerticalAxis)
verticalMotionEffect.minimumRelativeValue = -parallaxIntensity
verticalMotionEffect.maximumRelativeValue = parallaxIntensity

// Set vertical shadow opacity effect
let verticalTransparencyEffect = UIInterpolatingMotionEffect(keyPath: "layer.shadowOpacity", type: .TiltAlongVerticalAxis)
verticalTransparencyEffect.minimumRelativeValue = -1.0
verticalTransparencyEffect.maximumRelativeValue = 1.0

// Set horizontal shadow effect
let horizontalMotionEffect = UIInterpolatingMotionEffect(keyPath: "layer.shadowOffset.width", type: .TiltAlongHorizontalAxis)
horizontalMotionEffect.minimumRelativeValue = -parallaxIntensity
horizontalMotionEffect.maximumRelativeValue = parallaxIntensity

// Set horizontal shadow opacity effect
let horizontalTransparencyEffect = UIInterpolatingMotionEffect(keyPath: "layer.shadowOpacity", type: .TiltAlongHorizontalAxis)
horizontalTransparencyEffect.minimumRelativeValue = -1.0
horizontalTransparencyEffect.maximumRelativeValue = 1.0

// Create group to combine all effects
let group = UIMotionEffectGroup()
group.motionEffects = [verticalMotionEffect, verticalTransparencyEffect, horizontalMotionEffect, horizontalTransparencyEffect]

// Add both effects to the label
self.addMotionEffect(group)

注意:为使其起作用,需要禁用手动设置layer.shadowOpacity。


1
UIInterpolatingMotionEffect 的概念是自我管理的,您只需提供最小值和最大值,它会读取轴值并将倾斜值(在-1到1范围内)转换为相对于您最小和最大值的值。它不适用于直接向您提供倾斜值。
一种可能的“hack”方法(我不建议使用)是创建一个透明视图,最小值为-1,最大值为1。这样,您可以从此视图中读取倾斜值。
编辑: 您可以查看此答案Use UIMotionEffect with OpenGL ES,其中解释了类似的方法。

谢谢您的回复。但正如您所说,这并不是真正推荐的做法。不过,这确实是一个好的技巧。 - Ashin Mandal
1
很高兴它对你有帮助。我看到,在你的解决方案中,你使用了类似的方法。 - o15a3d4l11s2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接