iPhone:如何检测滑块拖动的结束?

问题描述 投票:74回答:14

如何在用户结束拖动滑块指针时检测事件?

ios iphone ios5 ios4 uislider
14个回答
143
投票

如果你不需要拖动之间的任何数据,那么你应该简单地设置:

[mySlider setContinuous: NO];

这样,只有当用户停止移动滑块时,您才会收到valueChanged事件。


4
投票

在Swift 4中,您可以使用此功能

1第一步: - 在滑块中添加目标

self.distanceSlider.addTarget(self, action: #selector(self.sliderDidEndSliding(notification:)), for: ([.touchUpInside,.touchUpOutside]))

2第二步: - 创建一个功能

@objc func sliderDidEndSliding(notification: NSNotification)
{
   print("Hello-->\(distanceSlider.value)")
}

3
投票

Swift 3.1

有时您会希望滑块的拖动事件连续触发,但可以选择执行不同的代码,具体取决于滑块是否仍在拖动或刚刚完成拖动。

要做到这一点,我已经扩展了Andy上面的答案,它利用了滑块的isTracking属性。我需要记录两个状态:sliderHasFinishedTrackingsliderLastStoredValue

我的代码正确:

  • 开始拖动时不会触发动作
  • 如果用户只用一次点击轻推滑块(意味着isTracking仍然是false),则触发动作

class SliderExample: UIViewController {
  var slider: UISlider = UISlider()
  var sliderHasFinishedTracking: Bool = true
  var sliderLastStoredValue: Float!

  override func loadView() {
    super.loadView()

    slider.minimumValue = 100.0
    slider.maximumValue = 200.0
    slider.isContinuous = true
    slider.value = 100.0
    self.sliderLastStoredValue = slider.value
    slider.addTarget(self, action: #selector(respondToSlideEvents), for: .valueChanged)
    // add your slider to the view however you like
  }

  func respondToSlideEvents(sender: UISlider) {
    let currentValue: Float = Float(sender.value)
    print("Event fired. Current value for slider: \(currentValue)%.")

    if(slider.isTracking) {
      self.sliderHasFinishedTracking = false
      print("Action while the slider is being dragged ⏳")
    } else {
      if(self.sliderHasFinishedTracking && currentValue == self.sliderLastStoredValue){
        print("Slider has finished tracking and its value hasn't changed, " +
              "yet event was fired anyway. 🤷") // No need to take action.
      } else {
        self.sliderHasFinishedTracking = true
        print("Action upon slider drag/tap finishing ⌛️")
      }
    }

    self.sliderLastStoredValue = currentValue
  }
}

1
投票

我最近有类似的问题。这是我在Swift中所做的:

    theSlider.continuous = false;

保存此连续值的代码为:

public var continuous: Bool // if set, value change events are generated
    // any time the value changes due to dragging. default = YES

默认值似乎为YES(true)。将它设置为false可以实现您想要的功能。


1
投票

也许你应该为UIControlEventTouchUpInside,UIControlEventTouchUpOutside,UIControlEventTouchCancel事件添加目标。

之前我遇到了同样的问题,因为我没有为UIControlEventTouchCancel事件添加目标。


0
投票

试试这样吧

customSlider.minimumValue = 0.0;
    customSlider.maximumValue = 10.0;
[customSlider addTarget:self action:@selector(changeSlider:) forControlEvents:UIControlEventValueChanged];


-(void)changeSlider:(id)sender{
    UISlider *slider=(UISlider *)sender;
    float sliderValue=(float)(slider.value );
NSLog(@"sliderValue = %f",sliderValue);
}

69
投票

我使用“Touch Up Inside”和“Touch up outside”通知。

界面生成器:

将Interface Builder中的两个通知连接到您的接收方法。该方法可能如下所示:

- (IBAction)lengthSliderDidEndSliding:(id)sender {
    NSLog(@"Slider did end sliding... Do your stuff here");
}

在代码中:

如果你想以编程方式连接它,你会在viewWillAppear(或适合你的任何地方)调用这样的东西:

[_mySlider addTarget:self
              action:@selector(sliderDidEndSliding:) 
    forControlEvents:(UIControlEventTouchUpInside | UIControlEventTouchUpOutside)];

接收方法如下所示:

- (void)sliderDidEndSliding:(NSNotification *)notification {
     NSLog(@"Slider did end sliding... Do your stuff here");
}

67
投票

您可以为UIControlEventValueChanged添加一个带有两个参数(发件人和事件)的操作:

[slider addTarget:self action:@selector(onSliderValChanged:forEvent:) forControlEvents:UIControlEventValueChanged]

然后检查处理程序中触摸对象的阶段:

- (void)onSliderValChanged:(UISlider*)slider forEvent:(UIEvent*)event {     
    UITouch *touchEvent = [[event allTouches] anyObject];
    switch (touchEvent.phase) {     
        case UITouchPhaseBegan:
            // handle drag began
            break;
        case UITouchPhaseMoved:
            // handle drag moved
            break;
        case UITouchPhaseEnded:
            // handle drag ended
            break;
        default:
            break;
    }
}

斯威夫特4

slider.addTarget(self, action: #selector(onSliderValChanged(slider:event:)), for: .valueChanged)
@objc func onSliderValChanged(slider: UISlider, event: UIEvent) {
    if let touchEvent = event.allTouches?.first {
        switch touchEvent.phase {
        case .began:
            // handle drag began
        case .moved:
            // handle drag moved
        case .ended:
            // handle drag ended
        default:
            break
        }
    }
}

注意在Interface Builder中添加操作时,您还可以选择将发件人和事件参数添加到操作中。


16
投票

由于UISliderUIControl的子类,因此您可以为其UIControlEventTouchUpInside设置目标和操作。

如果你想在代码中执行它,它看起来像这样:

[self.slider addTarget:self action:@selector(dragEndedForSlider:)
    forControlEvents:UIControlEventTouchUpInside];

当触摸结束时,这将向您发送dragEndedForSlider:消息。

如果要在笔尖中执行此操作,可以按住Ctrl键单击滑块以获取其连接菜单,然后从“Touch Up Inside”套接字拖动到目标对象。

您还应该为UIControlEventTouchUpOutsideUIControlEventTouchCancel添加目标和操作。


12
投票

Swift 4 and Swift 3

  1. 添加touchUpInsidetouchUpOutside事件的目标。您可以以编程方式或从故事板中执行此操作。这是你以编程方式进行的 slider.addTarget(self, action: #selector(sliderDidEndSliding), for: [.touchUpInside, .touchUpOutside])
  2. 编写函数来处理滑块拖动的结束 func sliderDidEndSliding() { print("end sliding") }

10
投票

您可以使用:

- (void)addTarget:(id)target action:(SEL)action 
                   forControlEvents:(UIControlEvents)controlEvents  

检测UISlider中何时发生touchDown和touchUp事件


7
投票

我认为你需要控制事件UIControlEventTouchUpInside


4
投票

连接Touch Up InsideValue Changed

enter image description here


4
投票

斯威夫特3回答

我有同样的问题,并最终得到这个工作,所以也许它会帮助别人。在故事板中将your_Slider连接到“Value Changed”,当滑块移动“Slider Touched”动作时,松开“Slider Released”。

@IBAction func your_Slider(_ sender: UISlider) {
    if (yourSlider.isTracking) {
        print("Slider Touched")
    } else {
        print("Slider Released")
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.