如何检测UISlider拖动结束?

问题描述 投票:0回答:16

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

ios uikit uislider
16个回答
219
投票

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

[mySlider setContinuous: NO];

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

valueChanged
事件。

Swift 5版本:

mySlider.isContinuous = false

173
投票

您可以为 UIControlEventValueChanged 添加一个采用 two 参数、发送者和事件的操作:

[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;
    }
}

斯威夫特

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 中添加操作时,您还可以选择将发送者和事件参数添加到操作中。


74
投票

我使用“内部修饰”和“外部修饰”通知。

界面生成器:

将 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");
}

21
投票

Swift 5 和 Swift 4

  1. touchUpInside
    touchUpOutside
    事件添加目标。您可以通过编程或故事板来完成此操作。这就是您以编程方式执行此操作的方式

    slider.addTarget(self, action: #selector(sliderDidEndSliding), for: [.touchUpInside, .touchUpOutside])
    
  2. 编写函数来处理滑块拖动的结束

    func sliderDidEndSliding() {
        print("end sliding")
    }
    

20
投票

由于

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

如果你想用代码来做,它看起来像这样:

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

触摸结束时,会向您发送一条

dragEndedForSlider:
消息。

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

您还应该为

UIControlEventTouchUpOutside
UIControlEventTouchCancel
添加目标和操作。


9
投票

您可以使用:

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

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


7
投票

我认为你需要控制事件

UIControlEventTouchUpInside


6
投票

Swift 3 回答

我遇到了同样的问题,并最终让它发挥作用,所以也许它会对某人有所帮助。将 your_Slider 连接到情节提要中的“值已更改”,并且当滑块移动时“滑块已触摸”动作,当放开时“滑块已释放”。

@IBAction func your_Slider(_ sender: UISlider) {
    if (yourSlider.isTracking) {
        print("Slider Touched")
    } else {
        print("Slider Released")
    }
}

4
投票

连接

Touch Up Inside
Value Changed


4
投票

斯威夫特3.1

有时您会希望滑块的拖动事件连续触发,但可以选择根据滑块是仍在拖动还是刚刚完成拖动来执行不同的代码。

为此,我扩展了安迪上面的答案,利用滑块的

isTracking
属性。我需要记录两种状态:
sliderHasFinishedTracking
sliderLastStoredValue

我的代码正确:

  • 开始拖动时不触发动作

  • 如果用户只需轻按一下滑块,
  • 就会触发该操作(意味着

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

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
投票

为滑块创建一个操作和出口(或者您可以将发送者从操作类型转换为 UISlider),并在 UI 中取消选中“连续更新”复选框。这样只有当滑块停止拖动时我们才会获取滑块值。

@IBAction func actionSlider(_ sender: Any) {
   let value = sliderSpeed.value.rounded()
}


2
投票

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

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


2
投票

RxSwift:

self.slider.rx.controlEvent([.touchUpInside, .touchUpOutside])
    .bind(to: self.viewModel.endSlidingSlider)
    .disposed(by: self.disposeBag)

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(真)。将其设置为 false 可以实现您想要的功能。


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);
}
© www.soinside.com 2019 - 2024. All rights reserved.