如何设置对tvOS焦点元素的约束

时间:2016-02-14 12:07:57

标签: autolayout tvos focus-engine

我的tvOS应用中有一个UICollectionView,其中包含图片和标题文字。我已经设置了一个约束来固定图像下面的标题文本。

enter image description here

当细胞聚焦并且图像增长时,文本不会移动并停留在图像上。有没有办法设置一个考虑到聚焦图像大小的约束?

Image without focus

Image with focus

3 个答案:

答案 0 :(得分:7)

您可以使用UIImageView属性focusedFrameGuide。它返回一个UILayoutGuide对象,遗憾的是它不能在Interface Builder中使用,但您可以在代码中使用它创建约束。请注意,此约束仅在视图聚焦时才有意义,因此您必须根据active属性设置其self.focused属性。

首先在视图初始化上创建约束:

self.focusedSpacingConstraint = NSLayoutConstraint(item: imageView.focusedFrameGuide, attribute: .BottomMargin, relatedBy: .Equal, toItem: label, attribute: .Top, multiplier: 1, constant: 0)
//add it to the view and set active to false

然后根据焦点激活此约束或默认约束:

override func didUpdateFocusInContext(context: UIFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator) {
    coordinator.addCoordinatedAnimations({
  self.focusedSpacingConstraint.active = self.focused
  self.spacingConstraint.active = !self.focused

  //set label's transform and animate layout changes
}

您还可以使用focusedFrameGuide设置标签的高度(占图像高度的百分比)。

这种方法的优点是,只要图像大小发生变化,您就不必更改(硬编码)constant

答案 1 :(得分:2)

我最终设置@IBOutlet到我的间距约束,然后在didUpdateFocusInContext方法中更新它。为了增加一些效果,我也改变了标签。

在我的收藏细胞中:

override func didUpdateFocusInContext(context: UIFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator) {
    coordinator.addCoordinatedAnimations({
        if self.focused {
            self.spacingConstraint.constant = 30
            UIView.animateWithDuration(0.3) {
                self.label.transform = CGAffineTransformMakeScale(1.15, 1.15)
                self.layoutIfNeeded()

            }
        }
        else {
            self.spacingConstraint.constant = 0
            UIView.animateWithDuration(0.3) {
                self.label.transform = CGAffineTransformMakeScale(1, 1)
                self.layoutIfNeeded()

            }
        }
        }, completion: nil)
}

答案 2 :(得分:0)

使用此代码,希望对您有所帮助。此代码写入自定义单元格类。

def trash_admin
  @order_summary = OrderSummary.only_deleted
end

def delete_trash
  @order_summary = OrderSummary.find params[:id]
  @order_summary.really_destroy!
  flash[:notice] = "Order Deleted Permanently!!!"
  redirect_to :action=>"trash_admin"
end