10

我要做的就是为所有状态的按钮添加背景颜色。但是我想保持在tvOS情节提要中使用系统按钮时“免费”获得的自动焦点阴影。到目前为止,我还没有找到允许这样做的组合。

或者,我也对一种在按钮获得焦点时以编程方式添加阴影的方法感兴趣,但没有对按钮进行子类化(我还没有尝试过),我也不知道该怎么做。

4

8 回答 8

8

您可以像这样为自定义按钮添加阴影:

- (void)didUpdateFocusInContext:(UIFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator
{
    context.nextFocusedView.layer.shadowOffset = CGSizeMake(0, 10);
    context.nextFocusedView.layer.shadowOpacity = 0.6;
    context.nextFocusedView.layer.shadowRadius = 15;
    context.nextFocusedView.layer.shadowColor = [UIColor blackColor].CGColor;
    context.previouslyFocusedView.layer.shadowOpacity = 0;
}
于 2015-09-25T18:39:52.960 回答
7

对简单的颜色更改不满意,所以我制作了一个自定义按钮子类,使其看起来更像是使用系统按钮获得的默认动画 -

class CustomButton: UIButton
{
    private var initialBackgroundColour: UIColor!


    required init?(coder aDecoder: NSCoder)
    {
        super.init(coder: aDecoder)

        initialBackgroundColour = backgroundColor
    }

    override func didUpdateFocusInContext(context: UIFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator)
    {
        coordinator.addCoordinatedAnimations(
        {
            if self.focused
            {
                self.backgroundColor = UIColor.whiteColor()

                UIView.animateWithDuration(0.2, animations:
                {
                    self.transform = CGAffineTransformMakeScale(1.1, 1.1)
                },
                completion: 
                {
                    finished in

                    UIView.animateWithDuration(0.2, animations:
                    {
                        self.transform = CGAffineTransformIdentity
                    },
                    completion: nil)
                })
            }
            else
            {
                self.backgroundColor = self.initialBackgroundColour
            }
        },
        completion: nil)
    }
}

没什么太复杂的,但可以完成工作

于 2015-11-10T21:06:19.967 回答
6

覆盖didUpdateFocusInContext方法并检查下一个焦点视图是否为按钮,如果是,则自定义其 UI,并将其设置回原始状态检查context.previousFocusedView该按钮,如下所示

- (void)didUpdateFocusInContext:(UIFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator
{
    if (context.nextFocusedView == _button)
    {
        // set background color
    }
    else if (context.previousFocusedView == _button)
    {
        // set background color to background
    }
}
于 2015-09-22T19:12:45.790 回答
4

灵感来自 SomaMan 的终极解决方案。只需对所有自定义按钮进行子类化,即可获得:

在此处输入图像描述

包括:点击动画和释放和拖走。

//
//  CustomFocusButton.swift
//

import UIKit

class CustomFocusButton: UIButton {


let focusedScaleFactor : CGFloat = 1.2
let focusedShadowRadius : CGFloat = 10
let focusedShadowOpacity : Float = 0.25
let shadowColor = UIColor.blackColor().CGColor
let shadowOffSetFocused = CGSizeMake(0, 27)
let animationDuration = 0.2

override func didUpdateFocusInContext(context: UIFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator)
{
    coordinator.addCoordinatedAnimations({
            if self.focused{
                UIView.animateWithDuration(self.animationDuration, animations:{ [weak self] () -> Void in

                        guard let weakSelf = self else {return}
                        weakSelf.transform = CGAffineTransformMakeScale(weakSelf.focusedScaleFactor, weakSelf.focusedScaleFactor)
                        weakSelf.clipsToBounds = false
                        weakSelf.layer.shadowOpacity = weakSelf.focusedShadowOpacity
                        weakSelf.layer.shadowRadius = weakSelf.focusedShadowRadius
                        weakSelf.layer.shadowColor = weakSelf.shadowColor
                        weakSelf.layer.shadowOffset = weakSelf.shadowOffSetFocused

                    },completion:{ [weak self] finished in

                        guard let weakSelf = self else {return}
                        if !finished{
                            weakSelf.transform = CGAffineTransformMakeScale(weakSelf.focusedScaleFactor, weakSelf.focusedScaleFactor)
                            weakSelf.clipsToBounds = false
                            weakSelf.layer.shadowOpacity = weakSelf.focusedShadowOpacity
                            weakSelf.layer.shadowRadius = weakSelf.focusedShadowRadius
                            weakSelf.layer.shadowColor = weakSelf.shadowColor
                            weakSelf.layer.shadowOffset = weakSelf.shadowOffSetFocused
                        }

                    })
            } else {
                UIView.animateWithDuration(self.animationDuration, animations:{  [weak self] () -> Void in
                    guard let weakSelf = self else {return}

                    weakSelf.clipsToBounds = true
                    weakSelf.transform = CGAffineTransformIdentity

                    }, completion: {[weak self] finished in
                        guard let weakSelf = self else {return}
                        if !finished{
                            weakSelf.clipsToBounds = true
                            weakSelf.transform = CGAffineTransformIdentity
                        }
                })
            }
        }, completion: nil)
}

override func pressesBegan(presses: Set<UIPress>, withEvent event: UIPressesEvent?) {
    UIView.animateWithDuration(animationDuration, animations: { [weak self] () -> Void in

        guard let weakSelf = self else {return}
        weakSelf.transform = CGAffineTransformIdentity
        weakSelf.layer.shadowOffset = CGSizeMake(0, 10);

    })
}

override func pressesCancelled(presses: Set<UIPress>, withEvent event: UIPressesEvent?) {

    if focused{
        UIView.animateWithDuration(animationDuration, animations: { [weak self] () -> Void in
            guard let weakSelf = self else {return}
            weakSelf.transform = CGAffineTransformMakeScale(weakSelf.focusedScaleFactor, weakSelf.focusedScaleFactor)
            weakSelf.layer.shadowOffset = weakSelf.shadowOffSetFocused
        })
    }

}

override func pressesEnded(presses: Set<UIPress>, withEvent event: UIPressesEvent?) {

    if focused{
        UIView.animateWithDuration(animationDuration, animations: {[weak self] () -> Void in

            guard let weakSelf = self else {return}
            weakSelf.transform = CGAffineTransformMakeScale(weakSelf.focusedScaleFactor, weakSelf.focusedScaleFactor)
            weakSelf.layer.shadowOffset = weakSelf.shadowOffSetFocused
        })
    }
}
}
于 2016-02-04T16:57:56.920 回答
2

我发现了更好的东西:

-(void)didUpdateFocusInContext:(UIFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator {
    [coordinator addCoordinatedAnimations:^{
        if (self.focused) {
            self.backgroundColor = [UIColor whiteColor];
        }
        else {
            self.backgroundColor = [UIColor clearColor];
        }
    } completion:nil];
}
于 2015-10-03T14:14:02.603 回答
1

Swift 4 /tvOS11 及更好:

将 Interface Builder 按钮属性中的 ButtonType 设置为“Plain”。

将此私有扩展添加到您的课程中:

private extension UIImage {

    static func imageWithColor(color: UIColor, size: CGSize) -> UIImage? {
        let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
        UIGraphicsBeginImageContextWithOptions(size, false, 0)
        color.setFill()
        UIRectFill(rect)
        let image: UIImage? = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return image
    }
}

然后在您连接的 IBOutlet 中为按钮的焦点状态设置背景图像:

@IBOutlet weak var myButton: UIButton! {
    didSet {
        let backgroundImageSelected = UIImage.imageWithColor(color: .red, size: myButton.bounds.size)
        myButton.setBackgroundImage(backgroundImageSelected, for: .focused)
    }
}
于 2018-11-28T11:13:38.900 回答
0

您可以将情节提要中的背景图像设置为包含您想要的颜色的图像

于 2016-05-03T17:26:11.403 回答
0

您可以使用该UIButton方法setBackgroundImage(image: UIImage?, forState state: UIControlState)并传递一个平面颜色和状态的图像.Normal

此图像可以很容易地以编程方式从 aUIColor和 1x1 的大小创建:

func getImageWithColor(color: UIColor, size: CGSize) -> UIImage {
    let rect = CGRectMake(0, 0, size.width, size.height)
    UIGraphicsBeginImageContextWithOptions(size, false, 0)
    color.setFill()
    UIRectFill(rect)
    let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return image
}
于 2016-01-05T04:42:02.637 回答