我有一个自定义的UICollectionViewCell
在我的tvOS应用程序。它有一个UIImageView
和一些UILabel
s在它。我可以通过实现UIFocusEnvironment
协议而没有任何问题地使单元集中,但是我不知道如何给我的自定义单元集中的外观。(抬高和响应用户在触摸板上的移动)。
我知道UIImageView
的adjustsImageWhenAncestorFocused
属性,但这只会提升我单元格中的图像,而不是整个单元格。
是否有一种方法可以使tvOS应用(看似)标准焦点外观/行为到我的自定义视图,还是我必须手动完成?
tvOS 12.0+更新:查看Apple在TVUIKit中提供的新类!你现在可以自定义具有这种聚焦行为的视图了!
,
我在苹果开发者论坛上问过同样的问题。苹果员工回答:对于自定义视图,您必须实现焦点外观你自己。在焦点更新功能中,你可以应用转换和使用UIMotionAffect API
- (void)didUpdateFocusInContext:(UIFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator { if (context.nextFocusedView == self) { // handle focus appearance changes } else { // handle unfocused appearance changes } }
我认为这将是非常有帮助的,使UIView
扩展能够应用相同的行为任何自定义视图。
也许他们希望我们用更有趣的方式向用户显示焦点?这将是一个很好的理由,使这很容易只对UIImageView
(更不用说,这种行为还增加模拟光在UIImageView
,这是美丽的,但可能只对图像有意义)。
正如前面的答案所述,没有标准的方法,但是有3个选项供您选择:
-
(推荐)实现您自己的自定义焦点行为,这类似于
UIImageView
倾斜:class MotionView: UIView { let motionEffectGroup = UIMotionEffectGroup() override init(frame: CGRect = .zero) { super.init(frame:frame) self.backgroundColor = .red addFocusMotionEffect() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } func addFocusMotionEffect() { let min = CGFloat(-15) let max = CGFloat(15) let xMotion = UIInterpolatingMotionEffect(keyPath: "layer.transform.translation.x", type: .tiltAlongHorizontalAxis) xMotion.minimumRelativeValue = min xMotion.maximumRelativeValue = max let yMotion = UIInterpolatingMotionEffect(keyPath: "layer.transform.translation.y", type: .tiltAlongVerticalAxis) yMotion.minimumRelativeValue = min yMotion.maximumRelativeValue = max motionEffectGroup.motionEffects = [xMotion,yMotion] self.addMotionEffect(motionEffectGroup) } func removeFocusMotionEffect() { UIView.animate(withDuration: 0.5) { self.removeMotionEffect(self.motionEffectGroup) } }
-
使
UIImageView
成为单元格contentView
的主导视图,然后将您的自定义视图附加到imageView's
overlayContentetView
,以便您的自定义视图将与UIImageView
一起动画,如下所示:self.imageView.overlayContentView.addSubview(logoView)
-
从TVUIKit中添加合适的元素,该元素具有行为,目前截至2022年,
TVCardView
服务器的目的很好。然后将CardView作为UICollectionViewCell
的子视图添加到UIImageView
或TVPosterView
之上,它将与它们协调其动画。您需要将自定义视图添加为TVCardView
和contentView
的子视图。缺点是TVCardView
不能真正有清晰的背景,你也不能改变它的圆角。class CardView: TVCardView{ override init(frame: CGRect = .zero) { super.init(frame:frame) let lbl = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 50)) lbl.text = "Test Label" self.contentView.addSubview(lbl) self.cardBackgroundColor = .red } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } }