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

ahy6op9u  于 12个月前  发布在  iOS
关注(0)|答案(4)|浏览(97)

我在一个表单上有一个UIButton,当表单不完整时,我想把它置于禁用状态。然而,我仍然希望能够检测到用户是否试图按下按钮,即使在禁用状态下,这样界面就可以让用户知道表单上的某些必填字段尚未填写(也许滚动到该字段并指出它,等等)。
似乎没有任何直接的方法来做到这一点。我试图简单地附加一个UITapGestureRecognizerUIButton,但它不响应时,按钮处于禁用状态。
如果可能的话,我想避免子类化UIButton,除非这是唯一的方法。

rbl8hiat

rbl8hiat1#

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


的数据
给予与主按钮相同的框架。如果你使用自动布局,选择主按钮和备用按钮,并创建约束以保持所有四个边缘相等。
当主按钮被禁用时,触摸将传递到备用按钮。当主按钮被启用时,它将捕获所有触摸,而备用按钮不会接收任何触摸。
将回退按钮连接到一个操作,以便您可以检测它何时被点击。

im9ewurl

im9ewurl2#

基于@rob的想法,我子类化了一个UIButton,并在这个按钮上的someone 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)
        }

    }

字符串

brjng4g3

brjng4g33#

模仿@AechoLiu的回答,下面是我如何在UIButton子类中实现它:

// Properties
private lazy var disabledButton: UIButton = {
    let disabledButton = UIButton(frame: frame)
    disabledButton.backgroundColor = .clear
    disabledButton.addTarget(self, action: #selector(disabledButtonTouchUpInside(_:)), for: .touchUpInside)
    
    return disabledButton
}()

// Method overrides
override func awakeFromNib() {
    super.awakeFromNib()
    
    // Do any other set up you need
    
    if let superview = superview {
        // Place the disabled button behind self in the hierarchy.
        // When `self` is disabled it will pass its touches through.
        superview.insertSubview(disabledButton, belowSubview: self)
    }
}

override func layoutSubviews() {
    super.layoutSubviews()
    
    // Sync `disabledButton` frame to main button's
    disabledButton.frame = frame
}

// Button handling
@objc private func disabledButtonTouchUpInside(_ sender: UIButton) {
    // Handle as required. You could:
    //  - Trigger the button's normal action using sendActions(for: .touchUpInside).
    //  - Add a delegate protocol to the button subclass and triggered one of its methods here.
}

字符串

50pmv0ei

50pmv0ei4#

你对用户体验有很大的误解。
如果一个按钮被禁用,它意味着不可交互。你不能点击一个禁用的按钮,这就是它被禁用的原因。
如果你想在点击按钮时警告用户某些事情(例如表单没有正确或完全填写),你需要启用该按钮。并且只需在用户点击它时警告用户,而不是继续应用逻辑。
或者,您可以保持该按钮禁用,直到满足表单条件,但使用另一种方式显示表单的错误,例如在文本字段附近放置感叹号,将文本字段颜色更改为红色或类似的东西。
但永远不要尝试添加手势识别器,或隐藏的回退按钮到禁用的按钮。
检查这些,让我知道,如果你看到一个禁用按钮:
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元素意味着不可交互。试图在禁用时使它们可交互与首先启用它们是一样的。
所以,对于你的问题来说,这只是一个样式问题。只要尝试样式化你的按钮,而不是使其禁用/启用。

相关问题