【问题标题】:Way to make a UIButton continuously fire during a press-and-hold situation?在按住的情况下使 UIButton 连续触发的方法?
【发布时间】:2010-10-28 12:51:29
【问题描述】:

你知道当你按住方向键上的右键时马里奥是如何一直向右跑的吗?以同样的方式,我希望我的 UIButton 在它被按住的时间内持续触发它的动作。这对 UIButton 可行吗?如果不是,这是否可以通过以某种方式覆盖触摸处理方法来处理 UIImageView ?实际上,在尝试使用 UIButton 完成此操作之前,我有一些 UIImageViews(被安排用作 D-Pad),它们通过触摸处理方法进行了检查,但事情开始变得混乱,所以我认为这可以通过 UIButton 更轻松地完成,因此切换了。任何知道如何识别连续、静止(不移动)的向下触摸的人,请分享。

【问题讨论】:

    标签: iphone cocoa-touch uibutton multi-touch


    【解决方案1】:

    不要使用按钮,使用多点触控和 NSTimer:

    在你的界面中创建一个本地视图 NSTimer 对象,然后使用它来启动/取消计时器

    -(void)movePlayer:(id)sender {
       <Code to move player>
    }
    
    -(void)touchesBegan:(NSSet*)touches  withEvent:(UIEvent*)event {
        timer = [NSTimer scheduledTimerWithTimeInterval:0.3 target:self selector:@selector(movePlayer:) userInfo:nil repeats:YES];
    }
    
    -(void)touchesEnded:(NSSet*)touches  withEvent:(UIEvent*)event {
       if (timer != nil) 
          [timer invalidate];
          timer = nil;
    }
    
    -(void)touchesMoved:(NSSet*)touches  withEvent:(UIEvent*)event {
        if (timer != nil) {
           [timer invalidate];
           timer = nil;
        }
    }
    

    这样,您可以以预定义的时间间隔重复事件,而不必依赖按钮,并获得您正在寻找的重复行为。 注意 touchesMoved 触发器 - 如果他们移动手指,这将取消计时器,并且玩家停止移动。

    【讨论】:

    • 你有 2 次 touchesBegan,我认为第 2 次应该是 touchesMoved。
    • 太好了,不过您能否将重复的 touchesBegan 触发器更正为您的预期 touchesMoved,这样没人会感到困惑。
    【解决方案2】:

    您也可以执行与上一个答案中显示的类似的操作,但仍使用 UIButton。

    只需在“Touch Down”处启动计时器,然后在“Touch Up Inside”或“Touch Up Outside”处停止计时器。

    就我个人而言,我喜欢使用 UIButton,因为它们提供了一些内置的视觉增强功能,您不必自己编写代码。

    【讨论】:

    • 为了清楚起见,“Touch Up Inside”和“Touch Up Outside”事件都应该配置为停止计时器。
    • 在我看来,比所选的答案更好。可以通过界面生成器进行配置。此外,与 touchesBegan 和frieds 相比,使用 IBActions 通常会导致代码更清晰、更容易理解。
    • 如果您采用这种方法,请不要忘记处理 UIControlEventTouchCancel。 (虽然我绝对推荐一个封装 NSTimer 的 UIButton 子类。视图控制器往往太大,所以你可以做任何事情来将代码 移出视图控制器是一件好事。)
    • UIControlEventTouchCancel 对我不起作用,以防用户按住按钮并将手指拖出按钮区域。与其使用 TouchCancel 事件,不如使用(在我看来)TouchDragExit。总而言之,我们正在使用:
    【解决方案3】:

    对我来说,以下作品:

    1. 创建一个按钮。
    2. 在视图控制器或子类中创建 2 个方法(停止触摸和开始触摸)。
    3. 添加 3 控制事件。 Touch Up InsideTouch Drag Exit 都是停止触摸的方法,Touch Down 是开始触摸的方法。
    4. 当开始触摸方法调用时,我们应该启动一个间隔大约为 0.2 的 NSTimer(取决于您希望被调用的速度),重复 true 并作为选择器作为您想要调用的方法(具有实际当用户点击按钮时你想要执行的东西)。
    5. 当停止触摸方法调用时,我们应该使计时器无效 (.invalidate()) 并将计时器分配为 nil。

    就是这样!

    【讨论】:

      【解决方案4】:

      现在完全不同:
      ReactiveCocoa 6

      self.button.reactive
          .controlEvents([.touchDown])
          .observeValues { button in
              SignalProducer.timer(interval: .milliseconds(500), on: QueueScheduler.main)
                  .take(until: button.reactive.controlEvents([.touchDragOutside, .touchDragExit, .touchUpInside, .touchUpOutside, .touchCancel]).map { _ in return })
                  .prefix(value: Date())
                  .startWithValues { date in
                      NSLog("\(date)")
                  }
              }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-04-15
        • 2021-07-18
        • 1970-01-01
        • 2021-11-27
        • 1970-01-01
        • 2013-06-02
        • 2011-06-16
        • 2017-07-13
        相关资源
        最近更新 更多