繁体   English   中英

Swift 中的 UIButton 未注册触摸

[英]UIButton in Swift is not registering touches

我正在尝试使用 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)

在同一个 class 中,这里是 function 'touchedSet':

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

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

谢谢!

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

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

例如。

  • Rootviewcontroller 有后视图

  • Topviewcontroller 有顶视图

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

简而言之:只需尝试使用以下方法将按钮超级视图的视图控制器作为子视图控制器添加到父视图视图控制器

func addChildViewController(_ childController: UIViewController)

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

这样做...

为 Swift 4 更新

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

那应该这样做。

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

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")
    }   
}

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

我在关注 Apple 的“开始开发 iOS 应用程序(Swift)”时遇到了同样的问题。 结果是我在教程中忽略了这些代码行:

override var intrinsicContentSize : CGSize {
    return CGSize(width: 240, height: 44)
}

将它们添加到我的 RatingControl 解决了这个问题。

对于遇到此问题的其他手动视图布局的人,您可能已经像这样定义了子视图:

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) }

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

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

这导致没有触发任何 tapHandlers,解决方案是,而不是仅使用 addArrangedSubview(subViewController.view),我还在addChildViewController(subViewController)使用addChildViewController(subViewController)以允许 childViewController 继续作为 viewController 运行,而不仅仅是一个看法。

所以你应该使用以下行

settings.userInteractionEnabled = true

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

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

(环境:iOS12,xcode10.1)

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

一旦我将其更改为 ">=" 开关就能够在开/关之间改变状态。 可笑的是,它几乎就像无法改变一样,因为它需要“空间”(显然会有所不同)来进行改变。

不确定,但将其归档为其中之一“嗯?” 记忆中的物品。

另一项(坦率地说,这真的不重要)是 valueChanged 和 tappedUpInside 都没有触发(在实际手机和模拟器上都是如此)。 此外,他们通过故事板联系在一起。 但是,据我所知,这应该无关紧要。

我遇到过同样的问题。 问题是视图有顶部约束,但没有左/右和高度约束。 因此,视图缩小到 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])

老问题,但我也发现自己被一个无响应的按钮卡住了。 我只是改变了我的初始化

let button = UIButton(frame: .zero)

let button = UIButton(type: .system)

如果您使用故事板,请确保将按钮与代码中的 IBOutlet 实例变量链接起来。

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

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

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

你说在同一个班级。 如果您正在使用视图,请确保按钮代码本身在 viewDidLoad() 中,并且操作在它之外但在类内。

Apple 的那个教程的问题在于他们将 UIView (RatingControl) 放在 StackView 中的方式,这是不正确的。 UIView (RatingControl) 应该在 StackView 之外。 因此,解决方案是: 1. 将 UIView (RatingControl) 拖到 StackView 之外 2. 设置RatingControl 新位置的约束 - Container 的前导边距等于零 - Container 的尾距边距等于零 - Top margin to StackView 等于零

有了这个新的约束,现在 RatingControl 将与容器相同,无论设备屏幕大小如何,并且始终位于照片选择器将出现的 StackView 的后面。

我希望这对你们有帮助。

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

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

希望这对某人有所帮助,并希望它是准确的。

我为 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)

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

就我而言,我在视图层次结构中的UIButton上方有一个透明的UIView ,这就是为什么当我“单击UIButton ”时,我实际上是在单击它上面的透明UIView

使用parentUIView.sendSubviewToBack(transparentUIView)发送透明UIView对我parentUIView.sendSubviewToBack(transparentUIView) ,因为这样做后UIButton位于视图层次结构的顶部。 单击 Xcode 中的“Debug View Hierarchy”按钮以检查UIButton是否在顶部。

如果您使用自动布局来构建您的 UI,请确保在您的视图和父视图中声明所有约束

有时我们忘记设置所有这些,系统会抱怨它,绘制您的 UI 但在您的触摸事件中没有正确响应。

就我而言,我忘记在我的视图中设置底部约束,所以我在这里将此评论设置为提醒。

当像按钮这样的视图放置在另一个视图(如图像视图等)旁边时,尤其是如果图像视图位于另一个视图之上时,Xcode 有时会认为您的按钮在该图像视图下方,即使它不是。 有时您需要清除所有约束并重置所有约束才能使按钮起作用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM