iPhone : 슬라이더 드래그 끝을 감지하는 방법은 무엇입니까?


96

사용자가 슬라이더 포인터의 드래그를 종료했을 때 이벤트를 감지하는 방법은 무엇입니까?


1
사용 : [slider addTarget : self action : @selector (sliderStoppedDragging :) forControlEvents : UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
Henry Sou

답변:


179

드래그 사이에 데이터가 필요하지 않은 경우 간단히 설정해야합니다.

[mySlider setContinuous: NO];

이렇게 valueChanged하면 사용자가 슬라이더 이동을 중지 할 때만 이벤트 를 받게 됩니다.

Swift 5 버전 :

mySlider.isContinuous = false

2
이것이이 질문에 대한 최선의 대답입니다. 나는 우리가 이것에 대한 답을 바꿀 수 있기를 바랍니다.
M. Porooshani 2015 년

1
i.imgur.com/0Edd2xe.png?1 XCode 버전 6.x에는 IDE 자체를 통해 setContinuous를 설정하는이 기능이 있습니다.
Abhijeet 2015 년

1
네, 가장 좋은 대답은 이것입니다.
sabiland

3
훌륭한 답변입니다. 여기 스위프트 4 코드는 다음과 같습니다self.mySlider.isContinuous = false
마르코 베버

2
이것은 저자가 요구하는 것이 아닙니다. 그는 계속 미끄러지기를 원하며 언제 멈춰야할지 알고 싶어합니다.
lbsweek

120

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

Swift 4 및 5

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에서 작업에 보낸 사람과 이벤트 매개 변수를 모두 추가 할 수도 있습니다.


1
완벽하게 작동합니다! 그 출처는 어디서 얻었습니까?
Roi Mulia

2
감사합니다 @RoiMulia, 내가 처음 본 곳을 기억하지 못합니다. 몇 년 동안 슬라이더를 사용해 왔습니다. 사용자가 손가락을 떼면 값이 점프하는 경향이 있기 때문에 UITouchPhaseEnded의 변경 사항을 무시하는 데 가끔 사용합니다.
Devin Pitcher

2
설정하는 것을 잊지 마십시오 isContinuous = true당신에 UISlider.
krlbsk

2
이것은 훌륭한 솔루션이지만 터치 취소에 문제가 있습니다. touchEvent 열거 형에 "cancelled"이벤트가 있음에도 불구하고 터치가 취소 될 때 시작되지 않습니다. 따라서 Slider에서 touchCancel 이벤트에 대한 리스너도 추가하는 것이 좋습니다. 이것은 모든 가능성을 포함해야합니다.
bnussey

2
나는 때때로 단계가 진행될 수 있음을 보았다 : 시작, 정지, 이동, 그러나 결코 끝나거나 취소되지 않았다. 모든 상호 작용이 종료되거나 취소 될 것으로 예상했기 때문에 내 사용 사례에 문제가 있습니다. 수정 사항은 위에 언급되어 있습니다. 별도의 터치 취소 대상 / 작업을 사용하십시오.
Jordan H

71

"내부 손질"및 "외부 손질"알림을 사용합니다.

인터페이스 빌더 :

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

19

은의 UISlider하위 클래스 이므로 UIControl해당에 대한 대상과 작업을 설정할 수 있습니다 UIControlEventTouchUpInside.

코드에서 수행하려는 경우 다음과 같습니다.

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

dragEndedForSlider:터치가 끝나면 메시지 가 전송 됩니다.

펜촉에서이 작업을 수행하려면 슬라이더를 컨트롤-클릭하여 연결 메뉴를 가져온 다음 "Touch Up Inside"소켓에서 대상 개체로 드래그 할 수 있습니다.

또한에 대한 대상과 작업을 추가해야 UIControlEventTouchUpOutside합니다 UIControlEventTouchCancel.


1
@rob mayoff 죄송하지만 UIControlEventTouchUpOutside를 사용해야합니다. 그렇지 않으면 드래그를 마쳤을 때 손가락이 슬라이더에 있지 않으면 선택기가 호출되지 않습니다.
user3164248

2
UISlider이 답변을 작성한 이후 의 동작 이 변경되었습니다.
rob mayoff 2015-04-11

당신이 확인할 수 있습니다 않습니다 또한 아이폰 OS 9에서 UIControlEventTouchUpOutside에 대한 핸들러를 등록해야합니다
LMS

나는 호출 할 수 결코 UIControlEventTouchCancel아이폰 OS 9에서 핸들러 그러나 나는 호출 할 수있어 UIControlEventTouchUpInsideUIControlEventTouchUpOutside단지.
petrsyn

17

Swift 5 및 Swift 4

  1. touchUpInsidetouchUpOutside이벤트에 대한 대상을 추가하십시오 . 프로그래밍 방식으로 또는 스토리 보드에서 수행 할 수 있습니다. 이것이 프로그래밍 방식으로 수행하는 방법입니다.

    slider.addTarget(self, action: #selector(sliderDidEndSliding), for: [.touchUpInside, .touchUpOutside])
    
  2. 슬라이더 드래그 끝을 처리하는 함수 작성

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

여보세요. 드래그를 시작할 때 비디오를 일시 중지하려면 어떻게합니까?
kemdo jul.

이것은 반드시 드래그가 발생했는지 여부를 감지하지 않으며 드래그하지 않고 간단히 탭하여 트리거 할 수 있습니다.
Chewie The Chorkie 2018 년

9

당신이 사용할 수있는:

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

UISlider에서 touchDown 및 touchUp 이벤트가 발생하는시기를 감지합니다.



5

신속한 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")
    }
}

2
솔루션 좋은,하지만 조심 때문에 슬라이더 끌기 시작할 때 호출되는 출시 최종 드래그
가이 Daher를

출시시 "Slider Released"라고도 부르지 않습니다
Vadim


4

스위프트 3.1

때때로 슬라이더의 드래그 이벤트가 계속 실행되기를 원하지만 슬라이더가 아직 드래그되고 있는지 또는 방금 드래그가 완료되었는지에 따라 다른 코드를 실행할 수있는 옵션이 있습니다.

이를 위해 슬라이더의 isTracking속성을 사용하는 위의 Andy의 답변을 확장 했습니다. 두 가지 상태를 기록해야했습니다 : 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
  }
}

4

Swift 4에서는이 기능을 사용할 수 있습니다.

첫 번째 단계 :-슬라이더에 대상 추가

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

2 두 번째 단계 :-함수 생성

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

2

UIControlEventTouchUpInside 、 UIControlEventTouchUpOutside 、 UIControlEventTouchCancel 이벤트에 대한 대상을 추가해야 할 수도 있습니다.

UIControlEventTouchCancel 이벤트에 대한 대상을 추가하지 않았기 때문에 이전에 동일한 문제가 발생 했습니다.


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로 설정하면 원하는 것을 수행합니다.


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

드래그가 끝날 때뿐만 아니라 슬라이더의 엄지가 움직일 때마다 액션을 보냅니다.
rob mayoff 2012

0

RxSwift :

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

0

슬라이더에 대한 작업 및 출력을 만들고 (또는 작업에서 UISlider로 보낸 사람을 typecast 할 수 있음) UI에서 연속 업데이트 확인란을 선택 취소합니다. 이렇게하면 슬라이더가 드래그를 멈출 때만 슬라이더 값을 얻을 수 있습니다.

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

여기에 이미지 설명 입력

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.