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

问题描述 投票:5回答:3

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

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

除非可能,否则我想避免子类化UIButton,除非它是唯一的方法。

ios cocoa-touch uibutton gesture-recognition
3个回答
13
投票

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

“子视图列表中的按钮”

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

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

将后备按钮连接到动作,以便可以检测到何时点击它。


1
投票

基于@rob的想法,我将UIButton子类化,并且在此按钮上的addSubview的某人之前添加透明按钮。

此自定义UIButton将节省许多有关在情节提要上调整UI组件的时间。


更新2018/08

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

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

    }

-4
投票

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

如果按钮被禁用,则表示该按钮不可交互。您不能单击禁用的按钮,这就是禁用它的原因。

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

或者您可以使按钮保持禁用状态,直到满足表单标准为止,但是可以使用另一种方法来显示表单出了什么问题,例如在文本字段附近放置感叹号,将文本字段的颜色更改为红色,等等。] >

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

检查这些,让我知道您是否看到禁用的按钮:

https://airbnb.com/signup_login

https://spotify.com/us/signup/

https://netflix.com/signup/regform

https://reddit.com/register/

https://twitter.com/signup

https://facebook.com/r.php

https://appleid.apple.com/account

https://accounts.google.com/SignUp

https://login.yahoo.com/account/create

https://signup.live.com/signup

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

这是一个很好的答案:https://ux.stackexchange.com/a/76306

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

因此,对于您的问题,这只是样式问题。只需尝试对按钮进行样式设置,而不要使其禁用/启用即可。

© www.soinside.com 2019 - 2024. All rights reserved.