gpt4 book ai didi

ios - EXC_BAD_ACCESS,从另一个类调用按钮方法时

转载 作者:行者123 更新时间:2023-11-28 13:06:43 24 4
gpt4 key购买 nike

我正在从我的 ViewController 类中的 DrawMenu 类调用一个方法,它绘制一个椭圆形(当前为圆形)按钮,非常简单。它完美地绘制了按钮,但如果我点击按钮,它就会崩溃。

即使我在 DrawMenu 中创建了 ViewController 类的实例,并将它用于“button.addTarget”中的“target”参数,也会发生这种情况

代码如下:

DrawMenu类中定义的按钮方法:

func drawButton (superImageView: UIImageView, x_of_origin: CGFloat, y_of_origin: CGFloat, width_of_oval: CGFloat, height_of_oval: CGFloat, actionSelector: Selector, want_to_test_bounds:Bool) {

var VC = ViewController()

var button = UIButton.buttonWithType(UIButtonType.Custom) as! UIButton
button.addTarget(VC, action: actionSelector, forControlEvents: UIControlEvents.TouchUpInside)
button.frame = CGRect(x: x_of_origin, y: y_of_origin, width: width_of_oval, height: height_of_oval)

button.clipsToBounds = true
button.layer.cornerRadius = height_of_oval/2.0

if (want_to_test_bounds == true) {
button.layer.borderColor = UIColor.blackColor().CGColor
button.layer.borderWidth = 1.0
superImageView.userInteractionEnabled = true
superImageView.addSubview(button)

} else {
superImageView.userInteractionEnabled = true
superImageView.addSubview(button)
}

}

ViewController类中调用的方法:

override func viewDidLoad() {
super.viewDidLoad()

var drawMenu = DrawMenu()

drawMenu.drawButton(imageView, x_of_origin: 100, y_of_origin: 150, width_of_oval: 100, height_of_oval: 100, actionSelector: "buttonTap:" as Selector, want_to_test_bounds: true)
}

buttonTap 也在 ViewController 类中:

    func buttonTap(sender:UIButton!){
println("Button is working")
}

感谢任何帮助。谢谢你

最佳答案

在方法 drawButton 中,您将 touchUpInside 的目标设置为 View Controller 的新实例。此引用在 drawButton 中的局部变量中创建,并将在该方法退出时释放。当 Action 处理程序被触发时,它会尝试调用无效对象上的函数,然后您会崩溃。

此处使用的正确设计模式是委托(delegate) - 为处理程序定义一个协议(protocol)并让您的 View Controller 实现该协议(protocol)。然后,您可以将 View Controller 传递给 drawButton 方法 -

首先在 DrawMenu 中定义协议(protocol) -

protocol ButtonDelegate:NSObjectProtocol
{
func buttonTap(sender: UIButton!) -> Void
}

然后您可以在drawButton 方法中使用协议(protocol)引用-

func drawButton (superImageView: UIImageView, x_of_origin: CGFloat, y_of_origin: CGFloat, width_of_oval: CGFloat, height_of_oval: CGFloat, delegate: ButtonDelegate, want_to_test_bounds:Bool) {

var button = UIButton.buttonWithType(UIButtonType.Custom) as! UIButton
button.addTarget(delegate, action: "buttonTap:", forControlEvents: UIControlEvents.TouchUpInside)
button.frame = CGRect(x: x_of_origin, y: y_of_origin, width: width_of_oval, height: height_of_oval)

button.clipsToBounds = true
button.layer.cornerRadius = height_of_oval/2.0

if (want_to_test_bounds == true) {
button.layer.borderColor = UIColor.blackColor().CGColor
button.layer.borderWidth = 1.0
superImageView.userInteractionEnabled = true
superImageView.addSubview(button)

} else {
superImageView.userInteractionEnabled = true
superImageView.addSubview(button)
}

}

最后,确保您的 ViewController 实现了协议(protocol) -

class ViewController : UIViewController, ButtonDelegate

并在创建按钮时将引用传递给 ViewController 实例 -

override func viewDidLoad() {
super.viewDidLoad()

var drawMenu = DrawMenu()

drawMenu.drawButton(imageView, x_of_origin: 100, y_of_origin: 150, width_of_oval: 100, height_of_oval: 100, delegate: self, want_to_test_bounds: true)
}

我建议的其他改进是使 drawButton 方法成为一个静态的类方法,这样您就不需要实例化 DrawMenu 的实例来使用它并让方法简单地返回按钮而不是向方法传递一个 View 来添加按钮。按照您的方式,如果您想进行进一步的更改,很难获得对该按钮的引用。以这种方式更改功能也使得将按钮添加到不是 UIImageViews 的 View 变得简单

最后,使用 CGRect 而不是传递不同的 x,y,width,height

class func drawButton (frame: CGRect, delegate: ButtonDelegate, showOutline:Bool) -> UIButton {

var button = UIButton.buttonWithType(UIButtonType.Custom) as! UIButton
button.addTarget(delegate, action: "buttonTap:", forControlEvents: UIControlEvents.TouchUpInside)
button.frame = frame
button.clipsToBounds = true
button.layer.cornerRadius = frame.size.height/2.0

if (showOutline) {
button.layer.borderColor = UIColor.blackColor().CGColor
button.layer.borderWidth = 1.0
}
return button
}

然后你会说——

override func viewDidLoad() {
super.viewDidLoad()

var newButton = DrawMenu.drawButton(CGRect(x: 100, y: 150, width: 100, height: 100),
delegate: self,
showOutline: true)
imageView.userInteractionEnabled = true
imageView.addSubview(newButton)
}

关于ios - EXC_BAD_ACCESS,从另一个类调用按钮方法时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32515325/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com