根据内容(主要是标题和图像)自动调整 UIButton 大小的最佳方法是啥?

Posted

技术标签:

【中文标题】根据内容(主要是标题和图像)自动调整 UIButton 大小的最佳方法是啥?【英文标题】:What is the best way to auto-resize a UIButton based on its contents, mainly its title and image?根据内容(主要是标题和图像)自动调整 UIButton 大小的最佳方法是什么? 【发布时间】:2019-06-10 16:56:16 【问题描述】:

我编写了以下代码来生成一个自定义 UIButton,我打算在我的应用程序的不同位置使用它:

import UIKit

import ChameleonFramework

class CustomButton: UIButton 

    override init(frame: CGRect) 

        super.init(frame: frame)

    

    required init?(coder aDecoder: NSCoder) 

        super.init(coder: aDecoder)

    

    convenience init(buttonTitleTexForNormalState titleForNormalState: String, buttonTitleTextColourForNormalState normalTextColour: UIColor, buttonTitleTextColourForHighlightedState highlightedTextColour: UIColor, buttonTitleFontType fontType: String, buttonTitleFontSize fontSize: CGFloat, buttonBackgroundHexColourCode hexColour: String, buttonFrameCornerRadius cornerRadius: CGFloat, buttonFrameBorderWidth borderWidth: CGFloat, buttonFrameBorderColour borderColour: String, buttonBackgroundTransperancyAlphaValue transperancy: CGFloat, buttonTagNumber tagValue: Int, buttonTarget: Any?, buttonSelector: Selector, buttonImageForNormalState normalButtonImage: String) 

        self.init()

        setupButtonEssentials(buttonTitleTexForNormalState: titleForNormalState, buttonTitleTextColourForNormalState: normalTextColour, buttonTitleTextColourForHighlightedState: highlightedTextColour, buttonTitleFontType: fontType, buttonTitleFontSize: fontSize, buttonBackgroundHexColourCode: hexColour, buttonFrameCornerRadius: cornerRadius, buttonFrameBorderWidth: borderWidth, buttonFrameBorderColour: borderColour, buttonBackgroundTransperancyAlphaValue: transperancy, buttonTagNumber: tagValue, buttonTarget: buttonTarget, buttonSelector: buttonSelector, buttonImageForNormalState: normalButtonImage)

    

    func setupButtonEssentials(buttonTitleTexForNormalState titleForNormalState: String, buttonTitleTextColourForNormalState normalTextColour: UIColor, buttonTitleTextColourForHighlightedState highlightedTextColour: UIColor, buttonTitleFontType fontType: String, buttonTitleFontSize fontSize: CGFloat, buttonBackgroundHexColourCode hexColour: String, buttonFrameCornerRadius cornerRadius: CGFloat, buttonFrameBorderWidth borderWidth: CGFloat, buttonFrameBorderColour borderColour: String, buttonBackgroundTransperancyAlphaValue transperancy: CGFloat, buttonTagNumber tagValue: Int, buttonTarget: Any?, buttonSelector: Selector, buttonImageForNormalState normalButtonImage: String) 

        setTitleColor(normalTextColour, for: .normal)

        setTitleColor(highlightedTextColour, for: .highlighted)

        titleLabel?.font = UIFont(name: fontType, size: fontSize)

        setTitle(titleForNormalState, for: .normal)

        backgroundColor = UIColor(hexString: hexColour)

        layer.cornerRadius = cornerRadius

        layer.borderWidth =  borderWidth

        layer.borderColor = UIColor(hexString: borderColour)?.cgColor

        showsTouchWhenHighlighted = true

        alpha = transperancy

        contentHorizontalAlignment = .center

        self.tag = tagValue

        addTarget(target, action: buttonSelector, for: .touchUpInside)

        if let buttonImage = UIImage(named: normalButtonImage) 

            setImage(buttonImage.withRenderingMode(.alwaysOriginal), for: .normal)

            contentMode = .scaleAspectFit

        

        setShadow()

        translatesAutoresizingMaskIntoConstraints = false

    

    private func setShadow() 

        layer.shadowColor = UIColor.black.cgColor

        layer.shadowOffset = CGSize(width: 0.0, height: 6.0)

        layer.shadowRadius = 8

        layer.shadowOpacity = 0.5

        clipsToBounds = true

        layer.masksToBounds = false

    

    func shake() 

        let shake = CABasicAnimation(keyPath: "position")

        shake.duration = 0.1

        shake.repeatCount = 2

        shake.autoreverses = true

        let fromPoint = CGPoint(x: center.x-8, y: center.y)

        let fromValue = NSValue(cgPoint: fromPoint)

        let toPoint = CGPoint(x: center.x+8, y: center.y)

        let toValue = NSValue(cgPoint: toPoint)

        shake.fromValue = fromValue

        shake.toValue = toValue

        layer.add(shake, forKey: "position")

    


下面的代码说明了我从 ViewController 中的自定义 UIButton 类(如上所示)创建实例的示例:

import UIKit

import ChameleonFramework

class MainScreen: UIViewController, UINavigationBarDelegate 

    var newFileButton = CustomButton(buttonTitleTexForNormalState: "New...", buttonTitleTextColourForNormalState: .black, buttonTitleTextColourForHighlightedState: .blue, buttonTitleFontType: "Apple SD Gothic Neo", buttonTitleFontSize: 17, buttonBackgroundHexColourCode: "#B24B32", buttonFrameCornerRadius: 25, buttonFrameBorderWidth: 2, buttonFrameBorderColour: "#7AFFD2", buttonBackgroundTransperancyAlphaValue: 0.75, buttonTagNumber: 1, buttonTarget: self, buttonSelector: #selector(buttonPressed(sender:)), buttonImageForNormalState: "New File")

    override func viewDidLayoutSubviews() 

        super.viewDidLayoutSubviews()

        print("viewDidLayoutSubviews")

        view.addSubview(newFileButton)

        newFileButton.frame.size.width = 140

        newFileButton.frame.size.height = 100

    

    @objc func buttonPressed(sender : UIButton) 

        if sender.tag == 1 

            newFileButton.shake()

            guard let nextViewControllerToGoTo = storyboard?.instantiateViewController(withIdentifier: "NewFileButtonPressedTabController") else 

                print("NewFileButtonPressedTabController could not be presented")

                return

            

            present(nextViewControllerToGoTo, animated: true, completion: nil)         

    


但是,从上面的代码可以看出,我最终根据宽度和高度手动定义了自定义 UIButton 的大小。

我想知道 Xcode 是否有办法根据每个自定义 UIButton 的内容(主要是其标题和图像)找出最佳宽度和高度?

P.S:我尝试使用intrinsicContent,但是,它对我没有用。任何建议都非常感谢。

谢谢, 沙迪。

【问题讨论】:

【参考方案1】:

删除设置newFileButton.frame.size.width.height 的代码,它应该采用您添加到其中的任何标题/图像的内容大小 - 但仅限于最低限度。如果您希望它比这更大,只需设置内容插入(有点像内容周围的填充)。

在你的按钮类中:

self.contentEdgeInsets = UIEdgeInsets(top: 10, left: 30, bottom: 10, right: 20)
self.imageEdgeInsets = UIEdgeInsets(top: 0, left: -20, bottom: 0, right: 0)

【讨论】:

感谢您回复我。但是,据我了解 UIEdgeInsets 用于修改 UIButton 的整体内容、其文本和/或图像的位置。我想要实现的是首先根据 UIButton 将包含的内容弄清楚它的近似(或精确)宽度和高度是多少? 您的意思是基于您提供的实际文本(或实际图像)? 没错,Xcode 会根据 UIButton 包含的图像和文本计算出它的高度和宽度吗? 尝试首先在按钮上设置您想要的图像/文本,然后调用button.layoutIfNeeded()(在您的MainScreen 视图控制器中)。然后立即检查button.frame.height(或button.frame.width)——应该是一个准确的返回值。

以上是关于根据内容(主要是标题和图像)自动调整 UIButton 大小的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

根据 UILabel 文本和图像自动调整单元格大小,例如聊天

如何根据屏幕大小调整按钮的图像和文本大小(自动布局)

根据图像的宽度自动调整 div 的各个部分的大小?

根据分辨率自动调整背景图像大小

将图像拉伸到浏览器边缘并根据浏览器的大小自动调整大小

水平图像滚动,图像大小调整以适合高度显示空白空间