Make UILabel focusable and tappable (tvOS)

倾然丶 夕夏残阳落幕 提交于 2019-12-01 05:26:30

Ok, answering my own question :)

So it appears that some some views are "focusable" on tvOS out-of-the-box, and other have to be instructed to do so.

I finally ended up using UITextView, which has a selectable property, but if not one of these focusable views by default. Editing of TextView has to be disabled to make it look like UILabel. Also, currently there is a bug which prevents you from using selectable property from Interface Builder but works from code.

Naturally, canBecomeFocused() and didUpdateFocusInContext had to be implemented too. You'll also need to pass a UIViewController because UITextView is not capable of presenting a modal view controller. Bellow is what I ended up creating.

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)
        }
    }

}

Use a collection view with just one cell and add transform to cell and change cell background color in didUpdateFocusInContext when focus moves to cell.

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)
}

As an additional step you could try to extract the color of the image if you are using the image as background like iTunes and use that for Visual effect view behind the cell.

Also you can apply transform to the collectionView in the video controller to make it look like in focus

You can use system button, and set the background image in storyboard to an image that contains the color you would like

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!