将圆角半径应用于递减按钮

Posted

技术标签:

【中文标题】将圆角半径应用于递减按钮【英文标题】:Apply corner radius to the decreasing button 【发布时间】:2018-07-02 16:58:33 【问题描述】:

我有一个非常好看的按钮。

import UIKit
class NiseButtonVC: UIViewController 
var button = MyShrinkingButton()
var button2 = UIButton()
override func viewDidLoad() 
    super.viewDidLoad()
    view.backgroundColor = .white
    button = MyShrinkingButton()
    button.bounds = CGRect(x: 0, y: 0, width: 200, height: 80)

    button.center = view.center
    button.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)


    button.setTitle("button", for: .normal)
    button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 40)
    button.titleLabel?.adjustsFontSizeToFitWidth = true
    let backGroundImage = UIImage.from(color: .orange)
    button.setBackgroundImage(backGroundImage, for: .normal)
    button.adjustsImageWhenHighlighted = false
//        button.layer.cornerRadius = 10
//        button.layer.masksToBounds = true
    view.addSubview(button)
 
@objc func buttonPressed(sender: UIButton)
    print("button pressed")




extension CGSize 
func sizeByDelta(dw:CGFloat, dh:CGFloat) -> CGSize 
    return CGSize(width:self.width + dw, height:self.height + dh)


class MyShrinkingButton: UIButton 

override func backgroundRect(forBounds bounds: CGRect) -> CGRect 
    var result = super.backgroundRect(forBounds:bounds)
    if self.isHighlighted 
        result = result.insetBy(dx: 3, dy: 3)
    
    return result

override var intrinsicContentSize : CGSize 
    return super.intrinsicContentSize.sizeByDelta(dw:25, dh: 20)


override func titleRect(forContentRect bounds: CGRect) -> CGRect 
    var result = super.titleRect(forContentRect:bounds)
    if self.isHighlighted 
        result = result.insetBy(dx: 3, dy: 3)
    
    return result




extension UIImage 
static func from(color: UIColor) -> UIImage 
    let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
    UIGraphicsBeginImageContext(rect.size)
    let context = UIGraphicsGetCurrentContext()
    context!.setFillColor(color.cgColor)
    context!.fill(rect)
    let img = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return img!


但我希望按钮具有圆角边缘。我可以使用cornerRadius 来实现.normal 状态,但是当按下按钮时效果消失。事实上,我想为按钮添加阴影,我可以自己添加阴影,但我不知道如何结合阴影和圆角边缘。

现在看起来

我想看看

我不能使用 button.backgroundColor 代替 button.setBackgroundColor,因为那样当你点击时按钮不会减小。这是我几周前发现的: What is the method "backgroundRect(forBounds:)" of UIButton used for?

最终代码。只有影子不起作用。但是圆角半径也只对 viewDidLoad 起作用:

import UIKit
class ViewController: UIViewController 

var button = ShrinkingButton()
override func viewDidLoad() 
    super.viewDidLoad()

    button = ShrinkingButton()
    button.bounds = CGRect(x: 0, y: 0, width: 200, height: 80)

    button.center = view.center
    button.setTitle("button", for: .normal)
    button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 40)
    button.titleLabel?.adjustsFontSizeToFitWidth = true
    button.backgroundColor = .orange
    button.setTitleColor(.white, for: .normal)
    button.adjustsImageWhenHighlighted = false
    button.layer.cornerRadius = 10
    button.layer.masksToBounds = true
    view.addSubview(button)




class ShrinkingButton: UIButton 

override var isHighlighted: Bool 
    didSet 
        UIView.animate(withDuration: 0.1) 
            self.isHighlighted ?     self.layer.setAffineTransform(CGAffineTransform(scaleX: 0.9, y: 0.9 )) :
                self.layer.setAffineTransform(.identity)
        
    


override func awakeFromNib() 
    super.awakeFromNib()

    layer.cornerRadius = 10

    layer.shadowOffset = CGSize(width: -1, height: 2)
    layer.shadowRadius = 5
    layer.shadowOpacity = 0.5

 

【问题讨论】:

请展示一下,您的按钮应该是什么样子? 我尝试添加图片。但是整个代码都在这里。如果你现在启动它,我会看看它的外观。如果您取消注释第 21 和 22 行,您将看到它应该是什么样子。但是当你点击时按钮应该保持比例。 为此,您可以使用普通按钮并设置相同的背景颜色。这比创建自定义类更容易且更可取。 嗨,zombie 的回答可能是正确的。您的问题现在存在吗? 不,我不能。带有背景颜色的普通按钮在按下时不会减少。 【参考方案1】:

按钮消失是因为您只将背景图像设置为正常状态。

这意味着对于任何其他状态,按钮都没有背景图像。

更好的方法是设置背景颜色而不是图像

button.backgroundColor = .orange

如果您想使用不仅仅是颜色的背景图像,那么也许您可以使用它

button.setBackgroundImage(image, for: UIControlState())

用showdow在印刷机上产生收缩效果

import UIKit

class ShrinkingButton: UIButton 

    override var isHighlighted: Bool 
        didSet 
            UIView.animate(withDuration: 0.1) 
                self.isHighlighted ? self.layer.setAffineTransform(CGAffineTransform(scaleX: 0.9, y: 0.9 )) :
                self.layer.setAffineTransform(.identity)
            
        
    

    override func awakeFromNib() 
        super.awakeFromNib()

        layer.cornerRadius = 10

        layer.shadowOffset = CGSize(width: -1, height: 2)
        layer.shadowRadius = 5
        layer.shadowOpacity = 0.5
    

【讨论】:

不,我试过 UIControlState(),还是不行。使用 utton.backgroundColor = .orange 按钮甚至不会在按下时减小。 @Sergey 检查我的更新答案以使按钮缩小(应该使用背景颜色和 layer.cornerRadius) 是的,它有效。谢谢你。但是有一些细微差别。按钮的反应有点慢 - 起初我以为它听起来,但真的有点慢。当然,这不是一般的问题。我也没有看到按钮的标题,尽管它已设置。 @Sergey 我通过改变持续时间让它更快了一点,现在动画也在覆盖范围内 真的。我没有注意到 "UIView.animate(withDuration: 0.1)" :( 现在好多了。但我还是看不到标题。【参考方案2】:

最后,这段代码可以工作了

import UIKit

class NiseButtonwhithShadowVC: UIViewController 

override func viewDidLoad() 
    super.viewDidLoad()

    // constants
    let radius: CGFloat = 20, dimension: CGFloat = 200, offset = 4
    let frame = CGRect(x: 0, y: 0, width: 200, height: 50)

    // custom view
    let customView = ShrinkingButton2(frame: frame)
    customView.setTitle("Button", for: .normal)

    // image layer
    let imageLayer = CALayer()
    imageLayer.backgroundColor = UIColor.orange.cgColor
    imageLayer.masksToBounds = true
    imageLayer.frame = frame
    imageLayer.cornerRadius = radius
    imageLayer.masksToBounds = true

    // rounded layer
    let roundedLayer = CALayer()
    roundedLayer.shadowColor = UIColor.gray.cgColor
    roundedLayer.shadowPath = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: dimension, height: 50), cornerRadius: radius).cgPath
    roundedLayer.shadowOffset = CGSize(width: offset, height: offset)
    roundedLayer.shadowOpacity = 0.5
    roundedLayer.shadowRadius = 2
    roundedLayer.frame = frame

    // views and layers hierarchy
    customView.layer.addSublayer(imageLayer)
    customView.layer.insertSublayer(roundedLayer, below: imageLayer)
    view.addSubview(customView)

    // layout
    customView.center = CGPoint(x: view.bounds.midX, y: view.bounds.midY)





class ShrinkingButton2: UIButton 

override var isHighlighted: Bool 
    didSet 
        UIView.animate(withDuration: 0.1) 
            self.isHighlighted ? self.layer.setAffineTransform(CGAffineTransform(scaleX: 0.95, y: 0.95 )) :
                self.layer.setAffineTransform(.identity)
        
    



感谢所有帮助过我的人。

【讨论】:

以上是关于将圆角半径应用于递减按钮的主要内容,如果未能解决你的问题,请参考以下文章

Swift - 圆角半径和阴影问题

按钮的圆角半径没有变化,怎么办?

如何实现具有圆角半径的自定义按钮

SwiftUI:将背景颜色应用于圆角矩形

在可变高度元件上保持完美的圆角

iphone:按钮角半径未设置