2013-11-24 15 views
23

Wpadłem w dziwny efekt, który z pewnością wygląda jak błąd w iOS7 - ale często w przeszłości, kiedy pomyślałem, że znalazłem błąd w API Apple'a, okazało się, że jest to mój własne nieporozumienie.Błąd UIDatePicker? UIControlEventValueChanged po trafieniu minimalnym wewnętrznym

Mam UIDatePicker z datePickerMode = UIDatePickerModeCountDownTimer i minuteInterval = 5. Inicjuję czas trwania do 1 godziny i prezentuję go użytkownikowi, gdzie pojawia się on jako dwukolumnowy selektor z godzinami i minutami. (Do tej pory tak dobrze.)

Użytkownik myśli "20 minut", a więc przewija kolumnę Godzina do 0. W tym momencie selektor odczytuje 0 godzin i 0 minut, a iOS7 nie jest z tym fajny, więc automatycznie przewija minutę do 5. Mój uchwyt UIControlEventValueChanged zostaje wywołany, a countDownDuration odczytuje 5 minut. (Nadal dobrze.)

Teraz użytkownik chwyta kółko minut i przeciąga je do 20. AND ... moja obsługa UIControlEventValueChanged nie zostaje wywołana. (Zły.)

Jeśli mam jakieś inne zdarzenie w interfejsie użytkownika, sprawdź selektor daty w tym miejscu, widzę, że countDownDuration jest ustawione na 20. Ale nie mogłem wiedzieć, że użytkownik zmienił go, moment został zmieniony. Jest to bardzo powtarzalne: zawsze dzieje się to przy pierwszej zmianie PO próbie wyboru zbieracza na 0 (przesuwanie do 5 minut).

Należy zauważyć, że jest to na iOS7; nie występuje w iOS6 (być może dlatego, że selektor jest ustawiony na 0 minut).

Więc ... czy coś tu brakuje? Czy jest to prawdziwy błąd w iOS7? A w tym drugim przypadku, czy ktokolwiek zna się na pracy lepiej niż posiadanie jakiegoś zegara okresowo sprawdzającego bieżący czas?

+0

powielana. Wygląda mi na błąd. – Kevin

Odpowiedz

33

Mogę również potwierdzić, że UIDatePicker w systemie iOS 7.0.3 zawiera błąd, gdy jest używany w trybie UIDatePickerModeCountDownTimer. Selektor nie wywołuje akcji docelowej związanej z zdarzeniem UIControlEventValueChanged, gdy użytkownik zmienia wartość, przewijając kółka. Działa dobrze dla kolejnych zmian.

Poniżej przedstawiono skuteczne obejście tego problemu. Po prostu dołącz kod, który ustawia początkową wartość countDownDuration w bloku wysyłki do pętli głównej. Twoja metoda działania docelowego będzie uruchamiana za każdym razem, gdy koła zostaną obrócone do nowej wartości. Takie podejście ma prawie żadnych napowietrznych i działa całkiem dobrze na iPhone 4 i iPad 4.

dispatch_async(dispatch_get_main_queue(), ^{ 
    self.myDatePicker.countDownDuration = (NSTimeInterval) aNewDuration ; 
}); 
+0

@Jeśli nadal mogę odtworzyć problem w zestawie SDK systemu iOS 7.1 na iPhone'a z systemem iOS 7.1. Jaką masz konfigurację, jeśli problem został rozwiązany? –

+0

To jest dość dziwne! Ten błąd nadal istnieje na iOS 7.1, ale poprawka w tej odpowiedzi zadziałała. Dzięki. –

+8

Ten błąd nadal istnieje na iOS 8;/ – Shial

4

ja wciąż uderzenie tego problemu w 7.1, ale dodanie następujących do obsługi UIControlEventValueChanged stacjonarnej to dla mnie.

// Value Changed Event is not firing if minimum value hit 
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ 
    [self.myDatePicker setCountDownDuration: self.myDatePicker.countDownDuration]; 
}); 
+0

To działało dla mnie pod iOS 8, a rozwiązanie Positron nie. – fatuhoku

+0

samo tutaj, wydaje się, że opóźnienie jest potrzebne – cdstamper

2

Jeśli ktoś nadal ma problemy z datepicker ... Używam Swift/iOS 8/Xcode 6.3

więc rozwiązać problem, który powinien bezużyteczna

picker.countDownDuration = NSTimeInterval 

zamiast użyj setDate

picker.setDate(NSDate, animated: true) 

działa bezpośrednio na viewDidLoad(), nie potrzebujesz używać `kolejek

1

Jeśli ktoś nadal ma problemy z datepicker ... Używam Swift/iOS 8/Xcode 6.3

Aby rozwiązać problem, nie powinieneś używać picker.countDownDuration = NSTimeInterval. Użyj .setDate(NSDate, animated: true).

działa bezpośrednio na viewDidLoad(), nie trzeba używać queues

Kompletny fragment:

override func viewDidLoad() { 
    super.viewDidLoad() 
    picker.setDate(setDateFromSeconds(seconds), animated: true) 
} 

func setDateFromSeconds(seconds: Double) -> (NSDate) { 
    let intSeconds = Int(seconds) 
    let minutes = (intSeconds/60) % 60 
    let hours = intSeconds/3600 
    let dateString = NSString(format: "%0.2d:%0.2d", hours, minutes) 

    let dateFormatter = NSDateFormatter() 
    dateFormatter.dateFormat = "hh:mm" 
    return dateFormatter.dateFromString(dateString as String) as NSDate! 
} 
+0

Dziękujemy za dodanie kodu SWIFT do konwersji czasu na datę. To działało dla mnie. Szalenie, że ten problem nadal występuje w iOS 10. – Mikrasya

1

Dla Swift 3:

DispatchQueue.main.async(execute: { 
    yourPicker.countDownDuration = TimeInterval() 
}) 
0

Ponieważ żadna odpowiedź nie zostało jeszcze zaakceptowane . Najprostszym rozwiązaniem, że pracował dla mnie w szybkim 3 jest po prostu zrobić

datePicker.countDownDuration = sekund

w viewDidAppear zamiast viewDidLoad

0

Swift 4

@IBOutlet weak var fromPickerView: UIDatePicker! 


@objc func toPickerViewDateChanged() { 
     fromPickerView.minimumDate = toPickerView.date 
    } 
    override func viewDidLoad() { 
     super.viewDidLoad() 



toPickerView.backgroundColor = UIColor.white 
    toPickerView.tintColor = .black 
    toPickerView.maximumDate = Date() 
    toPickerView.addTarget(self, action: 
    #selector(toPickerViewDateChanged), for: UIControlEvents.valueChanged) 
Powiązane problemy