Swift中的UIButton没有注册

时间:2014-06-04 12:45:49

标签: ios uibutton swift

我正在尝试使用Swift创建一个UIButton。它编译得很好,我可以在模拟器中看到我的按钮,但是当我点击它时,没有任何反应。这是我正在使用的代码:

let settings = UIButton()
settings.addTarget(self, action: "touchedSet:", forControlEvents: UIControlEvents.TouchUpInside)
settings.setTitle("Settings", forState: .Normal)
settings.frame = CGRectMake(0, 530, 150, 50)
scrollView.addSubview(settings)

在同一个班级中,这里是'touchSet'功能:

func touchedSet(sender: UIButton!) {
    println("You tapped the button")
}

我正在使用模拟器,因为我没有iOS 8.0设备,这可能是问题吗?

谢谢!

19 个答案:

答案 0 :(得分:15)

我认为这是一个古老的问题,但我昨天遇到了非常类似的问题。我的按钮在触摸时突出显示但没有触发动作。

我有两个视图控制器。一个视图覆盖其他视图,按钮位于顶视图中。

例如

  • Rootviewcontroller有后视图

  • Topviewcontroller有顶视图

如果我没有将topviewcontroler添加为rootviewcontroller的childviewcontroller,则顶视图上的按钮不会调用操作。将topviewcontroller添加为childviewcontroller后,它开始工作。

简而言之:只是尝试使用以下方法将按钮superview的视图控制器作为childviewcontroller添加到父视图viewcontroller

awk 'FNR==NR{a[$0];next}!($0 in a)' processed-list all-list

答案 1 :(得分:8)

选择器是必须创建的结构。

这样做......

更新了Swift 4

settingsButton.addTarget(self, action: #selector(showSettings), for: .touchUpInside)

应该这样做。

答案 2 :(得分:5)

在模拟器中,有时它无法识别选择器。似乎有一个错误。我刚刚更改了动作名称(选择器),它起作用了。

let buttonPuzzle:UIButton = UIButton(frame: CGRectMake(100, 400, 100, 50))
buttonPuzzle.backgroundColor = UIColor.greenColor()
buttonPuzzle.setTitle("Puzzle", forState: UIControlState.Normal)
buttonPuzzle.addTarget(self, action: "buttonAction:", forControlEvents: UIControlEvents.TouchUpInside)
buttonPuzzle.tag = 22;
self.view.addSubview(buttonPuzzle)

选择器功能在这里:

func buttonAction(sender:UIButton!)
{
    var btnsendtag:UIButton = sender
    if btnsendtag.tag == 22 {
        //println("Button tapped tag 22")
    }   
}

答案 3 :(得分:5)

对于那些也被困在教程中的人:

当我关注Apple"开始开发iOS应用程序(Swift)"时,我遇到了同样的问题。原来我在教程

中监督了这些代码行
override var intrinsicContentSize : CGSize {
    return CGSize(width: 240, height: 44)
}

将它们添加到我的RatingControl可以解决问题。

答案 4 :(得分:3)

当我有一个带有按钮和tapHandlers匹配的subViewController时,我遇到了类似的问题,我想把它放在一个单独的superViewController中的堆栈中。

这导致没有tapHandler触发,解决方案是仅使用addArrangedSubview(subViewController.view),我还在superview中使用addChildViewController(subViewController)来允许childViewController继续作为viewController而不仅仅是一个视图。

答案 5 :(得分:2)

对于遇到此问题进行手动视图布局的其他人,您可能已经定义了子视图,如下所示:

let settingsButton: UIButton = {
    let button = UIButton(type: .system)
    // do some more setup
    button.addTarget(self, selector: #selector(openSettings), for: .touchUpInside)
    return button
}()

错误在于您要添加目标并在实际可用之前传递self

可以通过两种方式解决此问题

  1. 使变量lazy并仍将目标添加到初始化块中:

    lazy var button: UIButton = {
        let button = UIButton(type: .system)
        // since this variable is lazy, we are guaranteed that self is available
        button.addTarget(self, selector: #selector(openSettings), for: .touchUpInside)
        return button
     }()
    
  2. 在初始化父视图之后添加目标:

    init() { 
        self.settingsButton = .init(type: .system)
        super.init(frame: .zero)
        self.settingsButton.addTarget(self, selector: #selector(openSettings), for: .touchUpInside)
    }
    

答案 6 :(得分:1)

当我的按钮的父视图有isUserInteractionEnabled == false时,我遇到了这个问题。所有子视图与其父视图具有相同的userInteraction。所以我刚刚添加了这一行parentView.isUserInteractionEnabled = true,问题就消失了。希望这有助于某人。

答案 7 :(得分:0)

我已将高度和宽度约束更改为 0,出于某种原因,我需要这样做,以便它在一个用例的多用途视图上正确显示,按钮可见但触摸停止工作。

答案 8 :(得分:0)

如果您使用的是故事板,请确保在代码中将您的按钮与IBOutlet实例变量相关联。

答案 9 :(得分:0)

一个老问题,但是我也发现自己陷入了一个没有响应的按钮。我只是从

更改了初始化
let button = UIButton(frame: .zero)

let button = UIButton(type: .system)

答案 10 :(得分:0)

我有同样的问题。问题在于视图具有顶部约束,但没有左/右和高度约束。因此,视图缩小为1x1,并且没有将触摸事件传递给孩子。

通过添加更多约束,孩子们现在可以触摸事件并开始工作...

let guide = view.safeAreaLayoutGuide
viewHeader.topAnchor.constraint(equalTo: guide.topAnchor).isActive = true
viewHeader.rightAnchor.constraint(equalTo: guide.rightAnchor).isActive = true
viewHeader.leftAnchor.constraint(equalTo: guide.leftAnchor).isActive = true
let heightConstraint = NSLayoutConstraint(item: viewHeader,
                                          attribute: NSLayoutConstraint.Attribute.height,
                                          relatedBy: NSLayoutConstraint.Relation.equal,
                                          toItem: nil,
                                          attribute: NSLayoutConstraint.Attribute.notAnAttribute,
                                          multiplier: 1,
                                          constant: 44)
viewHeader.addConstraints([heightConstraint])

答案 11 :(得分:0)

有趣的是,我在最新版本的iOS / Xcode(v12.4 / v10.3)上遇到了同样的问题。原来对我来说问题是LayoutConstraint!不是开玩笑。我在uiSwitch的右边有一个前导标签,发现我需要更改两者之间的约束,使得它不是8点的固定常数(Label-8-Switch-0- |)。 / p>

当我将其更改为“> =”时,开关便能够在开/关之间更改状态。可笑的是,它几乎无法更改,因为它需要“房间”(显然有所不同)来进行更改。

不确定,但是将其作为“哼哼”之一归档吗?记忆中的项目。

另外一项(坦率地说,这实际上不重要)是valueChanged和tappedUpInside均未触发(在实际的手机和模拟器上均为true)。此外,他们还通过情节提要挂钩。但是,据我所知这无关紧要。

答案 12 :(得分:0)

在容器视图(UIView)上实现UIButton和SearchBar时遇到相同的问题。 就我而言,原因是约束问题。对searchBar的约束存在问题,因此,从未调用过函数集。

您可以通过“调试视图层次结构”按钮查看是否有任何内容。 (约束问题显示为紫色警告)

(环境:iOS12,xcode10.1)

答案 13 :(得分:0)

我找到了Swift 2的类似示例并适用于Swift 3.测试它运行良好。我希望它有所帮助。

// http://lab.dejaworks.com/ios-swift-3-playground-uibutton-action
// Trevor D. Beydag

import UIKit
import PlaygroundSupport
class Responder : NSObject {
    func action() {
        print("Button pressed!")
    }
}

let containerView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 300.0,    height: 600.0))
PlaygroundPage.current.liveView = containerView
let responder = Responder()

let button = UIButton(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
button.backgroundColor = UIColor.green
button.setTitle("TEST", for: .normal)
button.addTarget(responder, action: #selector(Responder.action), for: .touchUpInside)
containerView.addSubview(button)

答案 14 :(得分:0)

老问题,但我想我会帮助其他人寻找这个问题。首先,我不完全确定这是正确的,所以如果我错了请纠正我。

但是如果你错误地设置了选择器,当你按下按钮时应用程序会崩溃,因为它订阅了一个不存在的选择器。这意味着您的选择器正在工作。我的猜测是假设UIButton.enabled = trueUIButton.userInteractionEnabled = true阻止了触摸事件。通常你可以通过长按按钮检查它,看它是否击中。如果确实如此,那么你会在某个地方添加UIGestureRecognizer,然后首先占用点击量。也可能是延迟触摸输入的UIScrollView(在检查器中有一个复选框)。

希望这有助于某人,并希望它是准确的。

答案 15 :(得分:0)

Apple教程的问题在于他们将UIView(RatingControl)置于StackView中,这是不正确的。 UIView(RatingControl)应该在StackView之外。所以,解决方案是: 1.将UIView(RatingControl)拖到StackView外部 2.设置RatingControl的新位置的约束     - Container的前沿保证金等于零     - 容器的尾随边距等于零     - StackView的上边距等于零

使用这些新约束,现在RatingControl将与Container一样,无论设备屏幕大小是多少,并且总是会落后于将出现照片选择器的StackView。

我希望这可以帮到你们。

答案 16 :(得分:0)

所以你应该使用以下行

settings.userInteractionEnabled = true

答案 17 :(得分:0)

你在同一个班级里说过。确保按钮代码本身位于viewDidLoad()中,并且操作在其外部,但如果您正在使用视图,则在类中。

答案 18 :(得分:0)

我只能看到一个问题:您必须将action设置为Selector,如下所示:

settings.addTarget(self, action: Selector("touchedSet:"), forControlEvents: UIControlEvents.TouchUpInside)

如果需要将参数传递给函数,请不要忘记插入: