【问题标题】:How to set image size and ratio between text into UIButton如何将图像大小和文本之间的比例设置为 UIButton
【发布时间】:2022-01-14 09:40:02
【问题描述】:

我有一个UIButton。最后,我应该得到这个:

无论我如何尝试,我都无法获得想要的结果。我已经阅读了很多关于这个主题的questions。我尝试尝试使用titleEdgeInsetsimageEdgeInsets,但没有帮助。事实是,当我为按钮设置图像时,它占据了按钮的全部内容,而文本则留在后面。下面我如何设置标题

let button = UIButton()

button.frame = CGRect(x: 150, y: 300, width: 100, height: 20)
button.backgroundColor = .blue
button.layer.borderColor = UIColor.green.cgColor
button.layer.borderWidth = 2

button.setImage(UIImage(named: "baseline_play_arrow_black_48.png"), for: .normal)
button.imageView?.backgroundColor = .red
button.imageView?.contentMode = .scaleAspectFit

button.setTitle("Play", for: .normal)
button.setTitleColor(.green, for: .normal)
button.titleLabel?.backgroundColor = .yellow

作为我在操场上尝试过的实验。上面的代码给出了以下结果:

.

我怎样才能得到想要的结果?

【问题讨论】:

标签: ios swift


【解决方案1】:

我相信有几种方法可以实现这个 Ahmet,我将介绍一个想法。

您的问题中有趣的挑战是您不仅要左对齐图像。

你想:

  • 仅相对于按钮标题左对齐图像
  • 但是,图像和文本应该在 UIButton 中作为一个整体居中对齐

我创建了以下扩展程序,通过一些 cmets 让您接近您想要的结果来解释我的思维过程:

extension UIButton
{
    func configureWithLeftImage(_ imageName: String)
    {
        // Retrieve the desired image and set it as the button's image
        let buttonImage = UIImage(named: imageName)?.withRenderingMode(.alwaysOriginal)
        
        // Resize the image to the appropriate size if required
        let resizedButtonImage = resizeImage(buttonImage)
        
        setImage(resizedButtonImage, for: .normal)
        
        // Set the content mode
        contentMode = .scaleAspectFit
        
        // Align the content inside the UIButton to be left so that
        // image can be left and the text can be besides that on it's right
        contentHorizontalAlignment = .left
        
        // Set or compute the width of the UIImageView within the UIButton
        let imageWidth: CGFloat = imageView!.frame.width
        
        // Specify the padding you want between UIButton and the text
        let contentPadding: CGFloat = 10.0
        
        // Get the width required for your text in the button
        let titleFrame = titleLabel!.intrinsicContentSize.width
        
        // Keep a hold of the button width to make calculations easier
        let buttonWidth = frame.width
        
        // The UIImage and the Text combined should be centered so we need to calculate
        // the x position of the image first.
        let imageXPos = (buttonWidth - (imageWidth + contentPadding + titleFrame)) / 2
        
        // Adjust the content to be centered
        contentEdgeInsets = UIEdgeInsets(top: 0.0,
                                         left: imageXPos,
                                         bottom: 0.0,
                                         right: 0.0)
    }
    
    // Make sure the image is sized properly, I have just given 50 x 50 as random
    // Code taken from: https://www.createwithswift.com/uiimage-resize-resizing-an-uiimage/
    private func resizeImage(_ image: UIImage?,
                                   toSize size: CGSize = CGSize(width: 50, height: 50)) -> UIImage?
    {
        if let image = image
        {
            UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
            image.draw(in: CGRect(origin: CGPoint.zero, size: size))
            
            let resizedImage = UIGraphicsGetImageFromCurrentImageContext()!
            UIGraphicsEndImageContext()
            return resizedImage
        }
        
        return nil
    }
}

那么当你想使用它时:

        // Initialize a UIButton and set its frame
        let customButton: UIButton = UIButton(type: .custom)
        customButton.frame = CGRect(x: 100, y: 200, width: 150, height: 40)
        
        // Customize the button as you wish
        customButton.backgroundColor = .white
        customButton.layer.cornerRadius = 5.0
        customButton.setTitleColor(.black, for: .normal)
        customButton.setTitle("смотрите", for: .normal)
        
        // Call the function we just created to configure the button
        customButton.configureWithLeftImage("play_icon")
        
        // Finally add the button to your view
        view.addSubview(customButton)

这是我认为接近您预期目标的最终结果:

如果你想测试一下,这也是我在 UIButton 中使用的图像

更新

您在 cmets 中正确识别了您的场景问题,您的图像尺寸太大。

我已经更新了上面的 UIButton 扩展,加入了一个可以解决问题的图像大小调整功能。

我已经为按钮内的 UIImage 提供了随机大小,但是您需要根据您的情况调整它的大小,或者根据按钮大小根据可用空间动态计算图像的大小。

我还为标题插入添加了一些代码,以使最终结果更好。

现在结果适用于 PlayGround 和 iOS 应用:

应用使用您的图片

使用您的图片的游乐场

更新 2.0

正如 Ahmet 指出的,当使用 titleInsets 和 imageInsets 改变字符串长度时,计算图像和标题的正确位置时会出现问题,有时会导致按钮和图像重叠。

改为按如下方式调整内容插图(也在上面的扩展中更新)

// The UIImage and the Text combined should be centered so we need to calculate
// the x position of the image first.
let imageXPos = (buttonWidth - (imageWidth + contentPadding + titleFrame)) / 2

// Adjust the content to be centered
contentEdgeInsets = UIEdgeInsets(top: 0.0,
                                 left: imageXPos,
                                 bottom: 0.0,
                                 right: 0.0)

如果按钮标题的文本长度为 1 个或多个字符,这将起作用

【讨论】:

  • 您对我的问题的描述非常正确。但是当我使用您的解决方案时,按钮中的 titleLabel 越界。一个区别我没有使用硬编码值指定按钮的大小和位置,例如您的示例。它落在了我的自定义 uiview 上,它的大小是自动计算的
  • @AhmetHudayberdyyev 也许用视图和按钮大小的计算方式来更新您的问题,然后我可以尝试更新我的答案。现在我只在你的代码button.frame = CGRect(x: 150, y: 300, width: 100, height: 20) 中看到这一点 - 所以也许可以用视图的创建方式以及视图和按钮的大小分配方式来更新代码。
  • 抱歉回复晚了。我在操场上实施您的解决方案。但都一样,imageView 填充了 Button 框架。因此 imageXPos 变为负值。我很困惑,为什么图像填充了按钮框架?
  • 但是我理解你的解决方案,如果图像没有填满按钮,我会得到想要的结果。如果你能帮我解决这个问题,你的代码应该可以正常工作。
  • 感谢您的详细解释。我得到了想要的结果。但是您的解决方案还有一个问题,应该解决。修复后,我将其设置为答案。当您指定 titleEdgeInsets 时,对于左插图,我们应该提供 imageXPos。 titleEdgeInsets = UIEdgeInsets(top: 0.0, left: imageXPos, bottom: 0.0, right: 0.0) 在您的解决方案中,如果标题的文本长度小于 5,则标题覆盖图像表面。在分析了您的代码后,我猜想,这两个元素的 leftInset 应该是 imageXPos。而且效果很好。
猜你喜欢
  • 2018-12-11
  • 2016-02-23
  • 2018-05-06
  • 1970-01-01
  • 2011-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多