使UILabel可调焦和可点击(tvOS)

时间:2015-11-23 13:10:05

标签: focus uilabel tvos

我试图实现6行高描述标签,我希望它可以集中精力。理想情况下,这意味着扩展UILabel类以创建自定义组件。我通过实施canBecomeFocuseddidUpdateFocusInContext尝试了这一点,但我的UILabel似乎没有得到任何关注。

我也尝试用UIButton替换UILabel,但按钮并没有真正针对这类事情进行优化。这也意味着我需要将焦点上的buttonType从自定义更改为普通..而buttonType似乎是一个现成的属性。

实际上,我希望Apple在Apple TV电影应用中使用完全相同的文本标签。对于电影描述,他们有一个文本标签,显示几行文字和一个"更多"。聚焦时,它看起来像一个按钮(阴影周围)和改变背景颜色。点击时 - 它会打开一个包含整个电影描述的模态窗口。

enter image description here

有什么建议吗?或者有人已经为tvOS实现了这个自定义控件?或事件更好 - 苹果有一个组件可以做到这一点,我错过了一些东西。

P.S:欢迎Swift解决方案:)

4 个答案:

答案 0 :(得分:6)

好的,回答我自己的问题:)

所以看起来有些观点是可以关注的#34;在tvOS开箱即用,其他必须指示这样做。

我最终使用UITextView,它具有selectable属性,但默认情况下,如果不是其中一个可聚焦视图。必须禁用TextView的修改才能使其显示为UILabel。此外,目前存在一个错误,它阻止您使用Interface Builder中的selectable属性,但可以使用代码。

当然,canBecomeFocused()didUpdateFocusInContext也必须实施。您还需要传递UIViewController,因为UITextView无法呈现模态视图控制器。贝娄是我最终创造的。

class FocusableText: UITextView {

    var data: String?
    var parentView: UIViewController?

    override func awakeFromNib() {
        super.awakeFromNib()
        let tap = UITapGestureRecognizer(target: self, action: "tapped:")
        tap.allowedPressTypes = [NSNumber(integer: UIPressType.Select.rawValue)]
        self.addGestureRecognizer(tap)
    }

    func tapped(gesture: UITapGestureRecognizer) {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        if let descriptionView = storyboard.instantiateViewControllerWithIdentifier("descriptionView") as? DescriptionViewController {
            if let view = parentView {
                if let show = show {
                    descriptionView.descriptionText = self.data
                    view.modalPresentationStyle = UIModalPresentationStyle.OverFullScreen
                    view.presentViewController(descriptionView, animated: true, completion: nil)
                }
            }
        }
    }

    override func canBecomeFocused() -> Bool {
        return true
    }

    override func didUpdateFocusInContext(context: UIFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator) {

        if context.nextFocusedView == self {
            coordinator.addCoordinatedAnimations({ () -> Void in
                self.layer.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.2).CGColor
            }, completion: nil)
        } else if context.previouslyFocusedView == self {
            coordinator.addCoordinatedAnimations({ () -> Void in
                self.layer.backgroundColor = UIColor.clearColor().CGColor
            }, completion: nil)
        }
    }

}

答案 1 :(得分:1)

只使用一个单元格的集合视图,并在焦点移动到单元格时,将变换添加到单元格并更改didUpdateFocusInContext中的单元格背景颜色。

override func didUpdateFocusInContext(context: UIFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator) {
    coordinator.addCoordinatedAnimations({
        if self.focused {
            self.transform = CGAffineTransformMakeScale(1.01, 1.01)
            self.backgroundColor = UIColor.whiteColor()
            self.textLabel.textColor = .blackColor()
        }
        else {
            self.transform = CGAffineTransformMakeScale(1, 1)
            self.backgroundColor = UIColor.clearColor()
            self.textLabel.textColor = .whiteColor()
        }
        }, completion: nil)
}

作为附加步骤,如果您将图像用作iTunes之类的背景,则可以尝试提取图像的颜色,并将其用于单元格后面的视觉效果视图。

此外,您可以将变换应用于视频控制器中的collectionView,使其看起来像焦点

答案 2 :(得分:1)

关于使UILabel成为焦点:

class MyLabel: UILabel {

    override var canBecomeFocused: Bool {
        return true
    }

    override func didUpdateFocus(in context: UIFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {
        super.didUpdateFocus(in: context, with: coordinator)

        backgroundColor = context.nextFocusedView == self ? .blue:.red

    }
}

重要!!! 如苹果开发者门户网站上所述:

如果视图可以成为焦点,则此属性的值为true;否则为false。否则为假。

默认情况下,此属性的值为false。此属性通知焦点引擎是否可以聚焦视图。有时,即使某个视图返回true,由于以下原因,该视图也可能无法聚焦:

  • 该视图已隐藏。

  • 该视图的alpha设置为0。

  • 该视图的userInteractionEnabled设置为false。

  • 该视图当前不在视图层次结构中。

答案 3 :(得分:-1)

您可以使用系统按钮,并将故事板中的背景图像设置为包含您想要的颜色的图像