2015-02-03 8 views
10

Mam UIDate Picker osadzony w statycznym TableViewCell i w tej chwili wyłączyłem większość kodu, z wyjątkiem kodu odpowiedzialnego za selektora daty.UIDate Picker valueechanged nie aktualizuje pierwszego wirowania, ale robi każdy spin po .. iOS

Używam Date Picker jako odliczanie timera

więc to niby wszystko, z wyjątkiem niektórych zwykłych punktach i Vars:

override func viewDidLoad() { 
    super.viewDidLoad() 

    // tfName.delegate = self 
    // tfDescription.delegate = self 
    // 

    datePicker.countDownDuration = 60 

    // pickerValueChanged(self) 

} 


@IBAction func pickerValueChanged(sender: AnyObject) { 

    seconds = Int(datePicker.countDownDuration) 
    hours = seconds/3600 
    if hours == 0{ 
     minutes = seconds/60 
    } else{ 
     minutes = seconds % 3600/60 
    } 
    labelDuration.text = "\(hours) hours \(minutes) minutes" 
} 

Pierwszy raz zmieniłyby wartość z selektora, zmieniona wartość nie uruchamia się wcale, ale spiny po niej nie kończą się niepowodzeniem.

Próbowałem wywołać to w viewDidLoad, z pickerValueChanged(self) i działa, ale nie rozwiązuje problemu. Poza tym skomentowałem każdą linię kodu w funkcji pickerValueChanged i viewDidLoad, ale nadal nie uruchomiłem pierwszego obrotu.

Dziękuję za poświęcony czas!

Aktualizacja: Dodano zdjęcia

Po pierwszym spinie, pickerValueChanged nie sprawdzony: First spin

Z drugiej spinu i poza nią, zdarzenie zostanie wywołany, a etykieta jest aktualizowany: Second spin

Tried:

Wykonywanie: datePicker.setDate(NSDate(), animated: true w viewDidLoad() rozwiązuje problem polegający na tym, że zdarzenie nie zostaje wywołane przy pierwszym obrocie, ale powoduje ustawienie początkowego stanu Selektora dat na bieżący czas. Ponieważ używam tej kontrolki, aby ustawić czas trwania zdarzenia, chcę pozwolić, aby zaczął od 0 godzin i 1 minuty. Można to zrobić za pomocą datePicker.countDownDuration = 60, ale po tym problem główny znów się pojawia. Rozwiązaniem może być ustawienie DatePicker z NSDate na 1 minutę, ale jak to zrobić?

Rozwiązanie:

var dateComp : NSDateComponents = NSDateComponents() 
dateComp.hour = 0 
dateComp.minute = 1 
dateComp.timeZone = NSTimeZone.systemTimeZone() 
var calendar : NSCalendar = NSCalendar(calendarIdentifier: NSGregorianCalendar)! 
var date : NSDate = calendar.dateFromComponents(dateComp)! 

datePicker.setDate(date, animated: true) 

Odpowiedz

5

wymyśliłem następujące rozwiązanie aby zainicjować komponentu datepicker (w trybie czasomierza) z 0 godzin i 1 minutę i reaguje bezpośrednio na pierwszą spin.Ponieważ wydaje się, że błąd i jest bardzo frustrujące jeśli chcesz textlabel zaktualizować swoją wartość, gdy datepicker ulega zmianie i nie na pierwszym Go:

var dateComp : NSDateComponents = NSDateComponents() 
dateComp.hour = 0 
dateComp.minute = 1 
dateComp.timeZone = NSTimeZone.systemTimeZone() 
var calendar : NSCalendar = NSCalendar(calendarIdentifier: NSGregorianCalendar)! 
var date : NSDate = calendar.dateFromComponents(dateComp)! 

datePicker.setDate(date, animated: true) 

Komponent stref czasowych nie jest naprawdę potrzebne do tego pracować dla mojej implementacji.

+0

To działa, dopóki DatePicker nie zniknie (na przykład, jeśli mam komórkę tabeli, która ją odkrywa lub ukrywa). Jeśli otworzę komórkę, w której znajduje się DatePicker, problem pojawi się ponownie i nawet ustawienie Date of DatePicker nie pomoże. To całkiem szalone ... – Dareon

0

nie wiem, czy mam problem, ale Data kompletacji działa przy użyciu wzoru docelowego działania i wywołuje ten mechanizm po zmianie wartości.
Jeśli więc problem jest pierwszą wyświetloną wartością, należy zainicjować zmienną, przyjmując ją jako wartość "domyślną".

+0

Co się dzieje, jest po raz pierwszy daję Date Picker a * Swing”to kręci jakąś wartość, ale nie wywoła Wartość Zmienione zdarzenie w ogóle. Ale drugi swing i wszystko po nim wywołuje zdarzenie. Nawet wyzwalanie zdarzenia z viewDidLoad nie zmienia zachowania problemu. –

1

Myślę, że powinieneś spróbować wdrożyć ten delegata zamiast

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component 
+0

Próbowałem wcześniej ustawić delegata do selektora dat, ale ta kontrolka nie ma delegata, tak jak ma to w PickerView, ponieważ Andrea tłumaczy również –

+1

Och, rozumiem. Czy widzisz ten post: http: //stackoverflow.com/questions/19251803/objective-c-uidatepicker-uicontroleventvaluechanged-only-fired-on-second-select – dminones

+0

Wygląda na to, że błąd, o którym mówią, nadal istnieje. ustawienie datePicker.setDate (NSDate(), animowane: true) w viewDidLoad rozwiązuje problem częściowo. DatePicker teraz aktualizuje wartość przy pierwszym obrocie teraz, ale synchronizuje godziny i minuty z czasem lokalnym. I chcę, aby zaczynało się od 1 minuty, co zrobiłem z datePicker.countDownDuration = 60, ale to ponownie zepsuło funkcję: D. Więc muszę zainicjować selektor ze stałą NSDate z (0h), 1 minutą. Ale nie mam pojęcia, jak to archiwizować. –

1

Wygląda na to, że ma coś wspólnego z animowanym parametrem. Trzeba tylko tę linię:

datePicker.setDate(date, animated: true) 
+0

To wydawało się być problemem dla mnie. Kiedyś ustawiałem datę za pomocą 'animated: false', zmieniając ją na' true', dzięki czemu moja akcja docelowa została wywołana również przy pierwszej zmianie wartości. – Marijn

1

czas temu znalazłem kolejny problem, który w jakiś sposób przypomina ten jeden. Chodziło o przedstawienie kontrolera widoku z poziomu tableView:didSelectRowAtIndexPath: i problem polegał na tym, że zajęło to dużo czasu, aby nowy kontroler rzeczywiście się pojawił. Jedno z obejść okazało się być w głównej kolejce za pomocą dispatch_async. To samo dla mnie zadziałało w tym przypadku.

w moim viewDidLoad, ja asynchronicznie wysłany kod instalacyjny do kompletacji na głównej kolejki i, w moim przypadku, zaczęło reagować na zdarzenia valueChanged nawet na pierwszym pick:

DispatchQueue.main.async { 
    self.pickerView.datePickerMode = .countDownTimer 
    self.pickerView.minuteInterval = 5 
    self.pickerView.countDownDuration = 15 
} 
2

Oto @ Henk- rozwiązanie Martijn za aktualizowane & uproszczone dla Swift 3:

let calendar = Calendar(identifier: .gregorian) 
let date = DateComponents(calendar: calendar, hour: 1, minute: 30).date! 
datePicker.setDate(date, animated: true) 

Użyj powyższy kod zamiast coś takiego:

datePicker.countDownDuration = 5_400 
Powiązane problemy