在禁用的UIButton上接收点击事件的最简单方法是什么?

时间:2014-09-09 22:11:56

标签: ios cocoa-touch uibutton gesture-recognition

我在表单上有一个UIButton,并希望在表单不完整时将其置于禁用状态。但是,我仍然希望能够检测用户是否尝试按下按钮即使处于禁用状态,以便界面可以让用户知道表单上的某些必填字段尚未填写(并且可能滚动到那个领域并指出它等。)。

似乎没有任何直接的方法来做到这一点。我尝试将UITapGestureRecognizer简单地附加到UIButton但是当按钮处于禁用状态时它没有响应。

如果可能的话,我想避免继承UIButton,除非这是唯一的方法。

3 个答案:

答案 0 :(得分:11)

创建一个后备按钮。把它放在主按钮后面。将其背景和文字颜色设置为[UIColor clearColor],以确保它不会显示。 (您不能将其alpha设置为0,因为这会使其忽略触摸。)在Interface Builder中,后备按钮应位于子视图列表中的主按钮上方,如下所示:

buttons in subview list

给它与主按钮相同的框架。如果您正在使用自动布局,请同时选择主按钮和后备按钮并创建约束以保持所有四条边相等。

当主按钮被禁用时,触摸将传递到后退按钮。启用主按钮后,它将捕获所有触摸,后退按钮不会收到任何触摸。

将后备按钮连接到某个操作,以便您可以检测它何时被轻击。

答案 1 :(得分:1)

根据@rob提示,我对UIButton进行了分类,并且在此按钮上的某个人addSubview之前添加透明按钮。

此自定义UIButton将节省很多时间来调整故事板上的UI组件。

更新2018/08

效果很好,并为此子类添加了一些增强的细节。我已经用了2年了。

    class TTButton : UIButton {

        // MARK: -
        private lazy var fakeButton : UIButton! = self.initFakeButton()
        private func initFakeButton() -> UIButton {
            let btn = UIButton(frame: self.frame)

            btn.backgroundColor = UIColor.clearColor()
            btn.addTarget(self, action: #selector(self.handleDisabledTouchEvent), forControlEvents: UIControlEvents.TouchUpInside)
            return btn
        }

        // Respect this property for `fakeButton` and `self` buttons
        override var isUserInteractionEnabled: Bool {
            didSet {
               self.fakeButton.isUserInteractionEnabled = isUserInteractionEnabled
            }
        }

        override func layoutSubviews() {
            super.layoutSubviews()

            // NOTE: `fakeButton` and `self` has the same `superView`. 
            self.fakeButton.frame = self.frame
        }

        override func willMoveToSuperview(newSuperview: UIView?) {
            //1. newSuperView add `fakeButton` first.  
            if (newSuperview != nil) {
                newSuperview!.addSubview(self.fakeButton)
            } else {
                self.fakeButton.removeFromSuperview()
            }
            //2. Then, newSuperView add `self` second.
            super.willMoveToSuperview(newSuperview)
        }

        @objc private func handleDisabledTouchEvent() {
            //NSLog("handle disabled touch event. Enabled: \(self.enabled)")
            self.sendActionsForControlEvents(.TouchUpInside)
        }

    }

答案 2 :(得分:-5)

您对用户体验有很大的误解。

如果禁用某个按钮,则表示该按钮不可互动。 您无法单击禁用的按钮,这就是禁用它的原因。

如果要在单击该按钮时向用户发出警告(例如,表单未正确填写或完全填写),则需要启用该按钮。只需在用户点击它时发出警告,而不是继续使用app逻辑。

或者您可以在符合表单条件之前禁用该按钮,但是使用其他方式显示表单有什么问题,例如在文本字段附近放置感叹号,将文本字段颜色更改为红色,或者类似的东西......

但永远不要尝试将手势识别器或隐藏的后备按钮添加到禁用按钮。

检查这些内容,如果您看到禁用按钮,请告诉我们:

twitter.com/signup

facebook.com/r.php

appleid.apple.com/account

accounts.google.com/SignUp

login.yahoo.com/account/create

signup.live.com/signup

这些网站上的所有继续按钮始终处于启用状态,当您尝试继续时,您会收到有关错误的反馈。

这是非常好的答案:https://ux.stackexchange.com/a/76306

长话短说:禁用的UI元素意味着无法互动。 尝试在禁用它们时使它们可交互是与首先启用它们相同的。

所以,对于你的问题,它只是一个样式问题。只需尝试设置按钮的样式,而不是禁用/启用它。