将 UIImageView 或 UITextView 添加到自定义 UIButton 类的正确方法是啥?

Posted

技术标签:

【中文标题】将 UIImageView 或 UITextView 添加到自定义 UIButton 类的正确方法是啥?【英文标题】:What's the correct way to add a UIImageView or UITextView to a custom UIButton class?将 UIImageView 或 UITextView 添加到自定义 UIButton 类的正确方法是什么? 【发布时间】:2017-02-21 08:02:47 【问题描述】:

我已经构建了一个自定义 UIButton 类,但我正在努力添加对象而不影响按钮的行为。我已经展示了下面的课程。当我在主代码中使用该类并添加目标时,该按钮仅适用于图像或文本未覆盖的区域。如何添加对象并使整个按钮区域的行为方式相同?

class TestButton: UIButton 
    var myText: UITextView!
    var myImageView: UIImageView!

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

    override init(frame: CGRect) 
        super.init(frame: frame)
        backgroundColor = UIColor.blue

        let myImage = UIImage(named: "AnImage")
        myImageView = UIImageView(image: myImage)
        myImageView.frame = CGRect(x: 10, y: 10, width: (myImage?.size.width)!, height: (myImage?.size.height)!)
        addSubview(myImageView)

        myText = UITextView()
        myText.font = UIFont(name: "Courier", size: 12)!
        myText.isEditable = false
        addSubview(myText)

    

【问题讨论】:

您可以禁用 imageview 和 textview 的用户交互以获取单击按钮。或者可以覆盖 hittest 方法。 您可以简单地将 UIButton 放在您想要的任何位置并关闭其他组件的交互,而不是将组件添加到 UIButton 中,只保留其他组件。 【参考方案1】:

这里是一个猜测,希望它有效。

UIImageViewUITextView 通常不允许“用户交互”,这意味着用户不能点击它们并期望应用程序基于此做出反应。这可能就是为什么当您点击图像视图时,该事件没有传递到下面的UIButton

幸运的是,修复很容易。您可以将布尔属性isUserInteractionEnabled 设置为true,您应该可以再次营业。

所以在你的情况下:

override init(frame: CGRect) 
    super.init(frame: frame)
    backgroundColor = UIColor.blue

    let myImage = UIImage(named: "AnImage")
    myImageView = UIImageView(image: myImage)
    myImageView.frame = CGRect(x: 10, y: 10, width: (myImage?.size.width)!, height: (myImage?.size.height)!)
    myImageView.isUserInteractionEnabled = true
    addSubview(myImageView)

    myText = UITextView()
    myText.font = UIFont(name: "Courier", size: 12)!
    myText.isEditable = false
    myText.isUserInteractionEnabled = true
    addSubview(myText)

更新(在您发表评论后)

好的,所以我只是尝试使用您的按钮创建一个快速项目......它似乎工作,我可以点击 imageView,我可以点击标签,仍然从我的函数中得到答案,所以必须在我们的设置方式上有所不同。

这是我的MyButton 按钮,与您所做的非常接近,唯一的区别是我在myImageView 上添加了一个backgroundColor,在myText 和@987654333 上添加了一个frame @上myText

class MyButton: UIButton 
    var myText: UITextView!
    var myImageView: UIImageView!

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

    override init(frame: CGRect) 
        super.init(frame: frame)
        backgroundColor = UIColor.blue

        let myImage = UIImage(named: "AnImage")
        myImageView = UIImageView(image: myImage)
        myImageView.frame = CGRect(x: 10, y: 10, width: (myImage?.size.width)!, height: (myImage?.size.height)!)
        myImageView.backgroundColor = UIColor.red
        addSubview(myImageView)

        myText = UITextView()
        myText.font = UIFont(name: "Courier", size: 12)!
        myText.frame = CGRect(x: 10, y: 80, width: 100, height: 30)
        myText.isEditable = false
        myText.isUserInteractionEnabled = false
        addSubview(myText)
     

这是我使用按钮的ViewController

import UIKit

class ViewController: UIViewController 
    override func viewDidLoad() 
        super.viewDidLoad()

        let button = MyButton(frame: CGRect(x: 10, y: 100, width: 200, height: 200))
        button.myText.text = "Hello"
        button.addTarget(self, action: #selector(didTapButton(_:)), for: .touchUpInside)
        view.addSubview(button)

        // Do any additional setup after loading the view, typically from a nib.
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    

    @IBAction func didTapButton(_ sender: MyButton) 
        print("It's alive!!")
    

这给了我这个漂亮的用户界面

当我点击红色图像、蓝色按钮本身或“Hello”标签时,我可以在控制台中看到:

It's alive!!
It's alive!!
It's alive!!

好消息是它似乎有效,现在我们只需要弄清楚你的设置和我的设置之间的区别是什么:)

希望有效并有所帮助。

【讨论】:

感谢您回来,但不幸的是,它不起作用。我试过将 UIImageView 和 UITextView 放在 UIButton 的顶部,在 UIButton 之外,但是这两个视图挡住了按钮。你知道我怎样才能改变对象的顺序吗?我试过 "let myButton = UIButton()" "myButton.bringSubview(toFront: self.view!)" 当其他两个对象在它前面时,按钮目标仍然没有被调用。

以上是关于将 UIImageView 或 UITextView 添加到自定义 UIButton 类的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

将contentMode设置为UIViewContentModeScaleAspectFit时如何设置UIImageView左对齐或右对齐?

将 UIImageView 或 UITextView 添加到自定义 UIButton 类的正确方法是啥?

使用 UIImageView 或 UIView 快速绘图

更改 UIImageView 或 UIImage 宽度

如何保存 UIImage 或 UIImageView 的状态?

UIImageView - 如果图像高度很小,则将内容向上移动