长按后如何跟踪按钮选择? [英] How to track button selection after long press?

查看:23
本文介绍了长按后如何跟踪按钮选择?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图模仿键盘的长按提示 UIButton 控件的字母.我想要做的是长按 UIButton,在按住按钮 3 个新按钮后,选择这 3 个新按钮之一.就像键盘字母建议一样.

I am trying to imitate the long press of the keyboard suggesting a letter for UIButton control. What I am trying to do is long press on UIButton, after keep pressing on the button 3 new buttons shows and select one of these 3 new buttons. just like the Keyboard letter suggestion.

我该怎么做?任何的想法?谢谢

How can I do this? any idea? Thank you

推荐答案

这已经很老了,但因为我遇到了同样的问题,所以我将提出我的解决方案.

This is quite old, but as I had the same problem I will present my solution for it.

我的键盘是由派生自 UIView 的类键盘布局和创建的每个字母按钮都是类 LetterButton,派生自 UIButton.键盘实现了一个协议,用于处理来自按钮的 KeyPressed 事件.

I have my keyboard laid out and created by class Keyboard, derived from UIView Each of the letter buttons is of class LetterButton, derived from UIButton. Keyboard implements a protocol which handles KeyPressed events from the buttons.

对于主键盘的每个按钮应用一个 UILongPressGestureRecognizer:

For each button of the main keyboard a UILongPressGestureRecognizer is applied:

let longTouchRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(onButtonLongPressed))
longTouchRecognizer.cancelsTouchesInView = false
button.addGestureRecognizer(longTouchRecognizer)
button.delegate = self

@objc func onButtonLongPressed (_ sender: UIGestureRecognizer)
{
    if (sender.state == .began)
    {
        guard let tag = sender.view?.tag else { return }
        createPopupView(button: buttons[tag])
    }
}

必须将cancelsTouchesInView 设置为false,否则我们将不会收到任何进一步的事件!

It is essential to set cancelsTouchesInView to false, else we wouldn't receive any further events !

在一个按钮上长按时,会在触摸的按钮上方创建一个或多个按钮的弹出视图.我们可以直接从触摸的按钮滑动到这些按钮.

On a longtouch on a button a popupview is created with one or more buttons above the button touched. We can swipe to these buttons directly from the button touched.

LetterButton 类的实现:

Implementation of LetterButton class:

class LetterButton : UIButton
{
  var delegate : LetterButtonDelegate?
  var isInside = false

这是从键盘类调用的:

  func setIsInside(val: Bool)
  {
    if (val)
    {
        if (!isInside)
        {
            setBackgroundColor(UIColor.lightGray, for: .normal)
        }
    }
    else
    {
        if (!isInside)
        {
            setBackgroundColor(UIColor.white, for: .normal)
       }
    }
    isInside = val
}

实际上我只需要键盘类的按钮

Actually I only need the button here for the Keyboard class

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
{
    if let touch = touches.first
    {
        let point = touch.location(in: self)
        delegate?.onBegan(button: self, point: point)
    }

    super.touchesBegan(touches, with: event)
}

只要我们将触摸移到按钮外,移动信息就会被发送到Keyboard类:

As long as we move the touch outside of the button, the movement information will be sent to the Keyboard class:

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?)
{
    if let touch = touches.first
    {
        let point = touch.location(in: self)
        if !bounds.contains(point)
        {
            delegate?.onMoved(point: convert(point, to: superview))
            return
        }
    }

    super.touchesMoved(touches, with: event)
}

这是按钮的字母实际处理的地方

This is where the letter of the button is actually processed

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?)
{
    if let touch = touches.first
    {
        let point = touch.location(in: self)
        delegate?.onEnded(point: convert(point, to: superview))
    }

    super.touchesEnded(touches, with: event)
}
}

如我们所见,LetterButton 类建立了以下需要由 Keyboard 类实现的协议:

As we see, the LetterButton class establishes the following protocol which need to be implemented by the Keyboard class:

protocol LetterButtonDelegate
{
    func onBegan(button: LetterButton, point: CGPoint)
    func onMoved(point: CGPoint)
    func onEnded(point: CGPoint)
}

Keyboard 类中协议的实现如下:

The implementation of the protocol within Keyboard class is as follows:

最初被触摸的按钮存储在这里

The button which got initially touched is stored here

func onBegan(button: LetterButton, point: CGPoint)
{
    buttonPressed = button
}

处理我们滑动的按钮的背景颜色变化

Processes background color change for buttons we swipe over

func onMoved(point: CGPoint)
{
    let _ = findPopupButton(point: point)
}

触摸结束的处理

func onEnded(point: CGPoint)
{
    // Check if touch ended on a popup button
    if let button = findPopupButton(point: point)
    {
        // yes, let the keyboard process the key
        delegate?.KeyPressed(key: button.title(for: .normal)!)
        button.setIsInside(val: false)

        // remove popupbuttons
        popupView?.removeFromSuperview()
        popupView = nil
    }
    else
    {
        // remove popup buttons if touch ended anywhere else
        if popupView != nil
        {
            popupView!.removeFromSuperview()
            popupView = nil

        }

        // buttons is an array of all normal keyboard buttons
        // we use it to check if the button, where the touch ended is the same where the touch began
        for button in buttons
        {
            if (button.frame.contains(point))
            {
                if (button.button.tag == buttonPressed?.tag)
                {
                    // Still on same button, process the key
                    delegate?.KeyPressed(key: button.button.title(for: .normal)!)              break
                }
            }
        }


    }
}


// Let's see if we are moving within the bounds of a popup button
func findPopupButton (point: CGPoint) -> LetterButton?
{
    var result : LetterButton? = nil

    if (popupView != nil)
    {
        if (popupView!.frame.contains(point))
        {
            for sub in popupView!.subviews
            {
                if (sub.isKind(of: LetterButton.self))
                {
                    let button = sub as! LetterButton
                    let frame = popupView!.convert(button.frame, to: self)

                    if (frame.contains(point))
                    {
                        button.setIsInside(val: true)
                        result = button
                    }
                    else
                    {
                        button.setIsInside(val: false)
                    }
                }
            }
        }
    }

    return result
}

这篇关于长按后如何跟踪按钮选择?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆