我正在使用 UIPickerView 并尝试使用映射到在第一个组件中选择的值的数据来实现加载第二个组件的功能。但是,我的第二个组件始终显示映射到我的第一个组件的第二行的值。
通过断点,我注意到值已正确传递给 - (UIView *)pickerView:(UIPickerView *)iPickerView viewForRow:(NSInteger)iRow forComponent:(NSInteger)iComponent reusingView:(UIView *)iView
方法。
请看我到目前为止做了什么。我错过了什么吗?
#import "ViewController.h"
#import "ZXingObjC.h"
@interface ViewController ()
@property (nonatomic, assign) IBOutlet UITextField *barcodeTextField;
@property (nonatomic, assign) IBOutlet UIImageView *barcodeImageView;
@property (weak, nonatomic) IBOutlet UIScrollView *scrollview;
@property (nonatomic, strong) NSArray *barcodeTypes;
@property (nonatomic, strong) NSDictionary *barcodes;
@property (nonatomic, assign) NSInteger selectedBarcodeType;
@end
typedef enum {
OneDBarcode = 0,
TwoDBarcode
} BarcodeTypes;
@implementation ViewController
- (void)loadView {
[super loadView];
UITapGestureRecognizer *aTapInsideTableView = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
[aTapInsideTableView setCancelsTouchesInView:NO];
[self.view addGestureRecognizer:aTapInsideTableView];
}
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *twoDBarcodes = @[@"Aztec", @"DataMatrix", @"MaxiCode", @"PDF417", @"QRCode", @"RSS14", @"RSSExpanded"];
NSArray *oneDBarcodes = @[@"Codabar", @"Code39", @"Code93", @"Code128", @"Ean8", @"Ean13", @"ITF", @"UPCA", @"UPCE", @"UPCEANExtension"];
self.barcodes = @{@"1D Barcodes": oneDBarcodes, @"2D Barcodes": twoDBarcodes};
self.barcodeTypes = @[@"Aztec", @"Codabar", @"Code39", @"Code93", @"Code128", @"DataMatrix", @"Ean8", @"Ean13", @"ITF", @"MaxiCode", @"PDF417", @"QRCode", @"RSS14", @"RSSExpanded", @"UPCA", @"UPCE", @"UPCE"];
self.selectedBarcodeType = OneDBarcode;
[self.scrollview setScrollEnabled:YES];
[self.scrollview setContentSize:CGSizeMake(320.0, 750.0)];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)generateBarcode:(id)sender {
UIImage *barcodeImage = [self barcodeImageForText:self.barcodeTextField.text];
if (barcodeImage) {
self.barcodeImageView.image = barcodeImage;
}
}
- (IBAction)dismissView:(id)iSender {
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
}
- (UIImage *)barcodeImageForText:(NSString *)iBarcode {
NSError* error = nil;
ZXMultiFormatWriter* writer = [ZXMultiFormatWriter writer];
ZXBitMatrix* result = [writer encode:iBarcode
format:kBarcodeFormatQRCode
width:500
height:500
error:&error];
if (result) {
CGImageRef image = [[ZXImage imageWithMatrix:result] cgimage];
// This CGImageRef image can be placed in a UIImage, NSImage, or written to a file.
return [UIImage imageWithCGImage:image];
} else {
NSString* errorMessage = [error localizedDescription];
NSLog(@"Error: %@", errorMessage);
return nil;
}
}
- (void)handleTap:(UITapGestureRecognizer *)iRecognizer {
if (self.barcodeTextField) {
[self.barcodeTextField resignFirstResponder];
}
}
#pragma mark - UIPickerViewDataSource methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)iPickerView {
return self.barcodes.allKeys.count;
}
- (NSInteger)pickerView:(UIPickerView *)iPickerView numberOfRowsInComponent:(NSInteger)iComponent {
NSArray *barcodeKeys = self.barcodes.allKeys;
NSArray *barcodeValues = self.barcodes[barcodeKeys[iComponent]];
if (iComponent == OneDBarcode) {
return barcodeKeys.count;
}
return barcodeValues.count;
}
#pragma mark - UIPickerViewDelegate methods
- (UIView *)pickerView:(UIPickerView *)iPickerView viewForRow:(NSInteger)iRow forComponent:(NSInteger)iComponent reusingView:(UIView *)iView {
UILabel *label = (UILabel *)iView;
if (!label) {
label = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.view.frame.size.width, 60.0f)];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = NSTextAlignmentCenter;
label.adjustsFontSizeToFitWidth = YES;
}
NSArray *barcodeKeys = self.barcodes.allKeys;
NSArray *barcodeValues = self.barcodes[barcodeKeys[iComponent]];
NSString *labelText;
if (iComponent == OneDBarcode) {
labelText = barcodeKeys[iRow];
} else if (iComponent == TwoDBarcode) {
labelText = barcodeValues[iRow];
}
label.text = labelText;
return label;
}
- (void)pickerView:(UIPickerView *)iPickerView didSelectRow:(NSInteger)iRow inComponent:(NSInteger)iComponent {
[iPickerView reloadComponent:iComponent];
if (iComponent == OneDBarcode) {
self.selectedBarcodeType = OneDBarcode;
} else {
self.selectedBarcodeType = TwoDBarcode;
}
[iPickerView reloadAllComponents];
}
@end
最佳答案
代码有很多错误。当用户在选择器中选择一行时,如果用户在第一个组件中选择了值,则只加载第二个组件。无论如何都不要重新加载。
在 viewForRow
方法中,你有两个问题:
- 字典没有顺序,获取键也没有顺序。但是数组中第一个组件的值,因此您可以通过索引访问它们。
- 您尝试访问
barcodeValues
是基于该组件。它应该基于第一个组件的选定索引。
关于ios - 无法根据 UIPickerview 中第一个组件的值重新加载第二个组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22619754/