Làm thế nào để phát hiện sự kiện khi người dùng đã kết thúc việc kéo con trỏ thanh trượt?
Làm thế nào để phát hiện sự kiện khi người dùng đã kết thúc việc kéo con trỏ thanh trượt?
Câu trả lời:
Nếu bạn không cần bất kỳ dữ liệu nào giữa quá trình kéo, bạn chỉ cần đặt:
[mySlider setContinuous: NO];
Bằng cách này, bạn sẽ chỉ nhận được valueChanged
sự kiện khi người dùng ngừng di chuyển thanh trượt.
Phiên bản Swift 5 :
mySlider.isContinuous = false
Events [x] Continuous Updates
cài đặt cho UISliderView. Bỏ chọn này sẽ đặt continuous
thành false / NO.
self.mySlider.isContinuous = false
Bạn có thể thêm một hành động có hai tham số, người gửi và một sự kiện, cho UIControlEventValueChanged:
[slider addTarget:self action:@selector(onSliderValChanged:forEvent:) forControlEvents:UIControlEventValueChanged]
Sau đó, kiểm tra giai đoạn của đối tượng cảm ứng trong trình xử lý của bạn:
- (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
}
}
}
Lưu ý trong Trình tạo giao diện khi thêm một hành động, bạn cũng có tùy chọn để thêm cả thông số người gửi và sự kiện vào hành động.
isContinuous = true
trong của bạn UISlider
.
Tôi sử dụng thông báo "Chạm lên bên trong" và "Chạm lên bên ngoài".
Trình tạo giao diện:
Kết nối cả hai thông báo trong Trình tạo giao diện với phương thức nhận của bạn. Phương thức có thể trông như thế này:
- (IBAction)lengthSliderDidEndSliding:(id)sender {
NSLog(@"Slider did end sliding... Do your stuff here");
}
Trong mã:
Nếu bạn muốn kết nối nó theo chương trình, bạn sẽ có một cái gì đó như thế này trong viewWillAppear (hoặc bất cứ nơi nào nó phù hợp với bạn) hãy gọi:
[_mySlider addTarget:self
action:@selector(sliderDidEndSliding:)
forControlEvents:(UIControlEventTouchUpInside | UIControlEventTouchUpOutside)];
Phương thức nhận sẽ giống như sau:
- (void)sliderDidEndSliding:(NSNotification *)notification {
NSLog(@"Slider did end sliding... Do your stuff here");
}
Vì UISlider
là một lớp con của UIControl
, bạn có thể đặt mục tiêu và hành động cho nó UIControlEventTouchUpInside
.
Nếu bạn muốn làm điều đó trong mã, nó sẽ giống như sau:
[self.slider addTarget:self action:@selector(dragEndedForSlider:)
forControlEvents:UIControlEventTouchUpInside];
Điều đó sẽ gửi cho bạn một dragEndedForSlider:
tin nhắn khi chạm kết thúc.
Nếu bạn muốn làm điều đó trong nib của mình, bạn có thể điều khiển khi nhấp vào thanh trượt để nhận menu kết nối của nó, sau đó kéo từ ổ cắm “Touch Up Inside” vào đối tượng mục tiêu.
Bạn cũng nên thêm mục tiêu và hành động cho UIControlEventTouchUpOutside
và cho UIControlEventTouchCancel
.
UISlider
đã thay đổi kể từ khi tôi viết câu trả lời này.
UIControlEventTouchCancel
handler trong iOS 9. Nhưng tôi có thể gọi UIControlEventTouchUpInside
và UIControlEventTouchUpOutside
chỉ.
Thêm mục tiêu cho touchUpInside
và touchUpOutside
các sự kiện. Bạn có thể làm điều đó theo chương trình hoặc từ bảng phân cảnh. Đây là cách bạn thực hiện theo chương trình
slider.addTarget(self, action: #selector(sliderDidEndSliding), for: [.touchUpInside, .touchUpOutside])
Viết hàm của bạn để xử lý phần cuối của quá trình kéo thanh trượt
func sliderDidEndSliding() {
print("end sliding")
}
Bạn có thể dùng:
- (void)addTarget:(id)target action:(SEL)action
forControlEvents:(UIControlEvents)controlEvents
để phát hiện khi nào sự kiện touchDown và touchUp xảy ra trong UISlider
Tôi nghĩ bạn cần sự kiện kiểm soát UIControlEventTouchUpInside
.
Câu trả lời Swift 3
Tôi đã gặp vấn đề tương tự và cuối cùng đã giải quyết được vấn đề này, vì vậy có thể nó sẽ giúp ích cho ai đó. Kết nối your_Slider với 'Giá trị đã thay đổi' trong bảng phân cảnh và khi thanh trượt di chuyển "Đã chạm vào thanh trượt" được kích hoạt và khi nào buông ra "Đã phát hành thanh trượt".
@IBAction func your_Slider(_ sender: UISlider) {
if (yourSlider.isTracking) {
print("Slider Touched")
} else {
print("Slider Released")
}
}
Đôi khi bạn sẽ muốn các sự kiện kéo của thanh trượt kích hoạt liên tục, nhưng có tùy chọn thực thi mã khác nhau tùy thuộc vào việc thanh trượt vẫn đang được kéo hay vừa được kéo xong.
Để làm điều này, tôi đã mở rộng câu trả lời của Andy ở trên sử dụng thuộc tính của thanh trượt isTracking
. Tôi cần ghi lại hai trạng thái: sliderHasFinishedTracking
vàsliderLastStoredValue
.
Mã của tôi đúng:
không kích hoạt một hành động khi bắt đầu kéo
kích hoạt hành động nếu người dùng chỉ di chuyển thanh trượt bằng một lần nhấn (nghĩa là isTracking
vẫn còn 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
}
}
Trong Swift 4, bạn có thể sử dụng chức năng này
1 Bước ngón tay: - Thêm mục tiêu trong thanh trượt
self.distanceSlider.addTarget(self, action: #selector(self.sliderDidEndSliding(notification:)), for: ([.touchUpInside,.touchUpOutside]))
2 Bước thứ hai: - Tạo một hàm
@objc func sliderDidEndSliding(notification: NSNotification)
{
print("Hello-->\(distanceSlider.value)")
}
Tôi đã gặp vấn đề tương tự gần đây. Đây là những gì tôi đã làm trong Swift:
theSlider.continuous = false;
Mã giữ giá trị liên tục này đọc:
public var continuous: Bool // if set, value change events are generated
// any time the value changes due to dragging. default = YES
Giá trị mặc định dường như là CÓ (true). Đặt nó thành false sẽ làm được điều bạn muốn.
Hãy thử như thế này
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);
}
RxSwift:
self.slider.rx.controlEvent([.touchUpInside, .touchUpOutside])
.bind(to: self.viewModel.endSlidingSlider)
.disposed(by: self.disposeBag)
Tạo một hành động và lối thoát cho thanh trượt (hoặc bạn có thể nhập người gửi từ hành động đến UISlider) và trong giao diện người dùng Bỏ chọn hộp kiểm Cập nhật liên tục. Bằng cách này, chúng ta sẽ chỉ nhận được giá trị thanh trượt khi thanh trượt ngừng kéo.
@IBAction func actionSlider(_ sender: Any) {
let value = sliderSpeed.value.rounded()
}