2016-04-15 6 views
0

Ich brauche picker programmatisch von Code zu starten, nachdem er einige Array von Server-AntwortWie starte ich UIPickerView manuell aus dem Code?

Empfang I-Code nach der Verwendung

_locationsPickerData = [NSArray arrayWithArray:offeredLocations]; 
UIPickerView *pickerView = [[UIPickerView alloc] init]; 
UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.frame), 44)]; 
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(locationsPickerDoneAction:)]; 
UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; 
[toolbar setItems:@[flexibleSpace, doneButton]]; 
toolbar.translucent = YES; 

pickerView.delegate = self; 
pickerView.dataSource = self; 
pickerView.accessibilityIdentifier = @"locationsPicker"; 

[_locationTextField setInputView:pickerView]; 
[_locationTextField setInputAccessoryView:toolbar]; 

Ich versuchte Picker Ansicht von [_locationTextField becomeFirstResponder]; zu starten - aber Anwendung abstürzt in einem solchen Fall.

Und ja, ich habe UIPickerViewDataSource, UIPickerViewDelegate abonniert. Und ich implementierten Methoden von Protokollen

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { 
    // the number of columns of data 
    return 1; 
} 

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { 
    // the number of rows of data 
    return _locationsPickerData.count; 
} 

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component { 
    // the data to return for the row and component (column) that's being passed in 
    return _locationsPickerData[row]; 
} 

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { 
    _locationTextField.text = _locationsPickerData[row]; 
} 

Wie Picker Ansicht manuell von Code starten?

AKTUALISIERT

wenn Aufruf becomeFirstResponder für Textfield - folgende Fehler angezeigt (app stürzt ab):

*** Assertion failure in void _UIPerformResizeOfTextViewForTextContainer(NSLayoutManager *, UIView<NSTextContainerView> *, NSTextContainer *, NSUInteger)(), /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIFoundation/UIFoundation-432.1/UIFoundation/TextSystem/NSLayoutManager_Private.m:1551 
2016-04-15 20:01:10.587 Weather-My-Way[5909:2305576] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Only run on the main thread!' 
*** First throw call stack: 
(0x181d7ee38 0x1813e3f80 0x181d7ed08 0x182704190 0x186df6570 0x186df6250 0x186e28fcc 0x186e4d0a4 0x186e4c7a0 0x186ee44a8 0x186ee3b18 0x186fda090 0x186f5159c 0x186f51a1c 0x186fd8b34 0x1000cdc20 0x1000bae90 0x18236b53c 0x18237e0bc 0x182738510 0x18268a900 0x18267aed8 0x18273a904 0x10018da3c 0x10019a554 0x10019172c 0x10019c66c 0x10019c364 0x1819e1470 0x1819e1020) 
libc++abi.dylib: terminating with uncaught exception of type NSException 
+0

Aktualisieren Sie Ihre Frage mit Details über den Absturz. Was ist die vollständige Fehlermeldung? Welche Codezeile verursacht tatsächlich den Absturz? – rmaddy

+0

aktualisierte Frage –

Antwort

2

Der Fehler sagt Ihnen das Problem. Sie versuchen, UI-Tasks für einen anderen Thread als den Hauptthread auszuführen.

Am wahrscheinlichsten (und richtig) Sie downloaden die Daten vom Server auf einem Hintergrundthread. Das ist gut.

Das Problem ist, dass Sie wahrscheinlich auch versuchen, [_locationTextField becomeFirstResponder]; auf dem gleichen Hintergrund-Thread aufzurufen. Das muss im Hauptthread erledigt werden.

Wrap diese Zeile (und alle anderen, die auch auf der Haupt-Thread sein müssen) mit diesem:

dispatch_async(dispatch_get_main_queue(), ^{ 
    [_locationTextField becomeFirstResponder]; 
}); 
+0

vielen Dank, du hast Recht. Ich habe diesen Fehler vorher gemacht und habe es vergessen –

0

Sie benötigen UI Arbeit auf dem Haupt-Thread zu tun.

dispatch_sync(dispatch_get_main_queue(), ^{ 
    /* Do UI work here */ 
});