实际上,之前我曾问过同样的问题,但我还没有办法解决它,所以我又来了。
我的情况:
我有一个带有2个相关组件的UIPickerView
,第二个或右侧组件中行的数量和内容随着第一个或左侧组件中当前选定的行而变化,这是非常常见且有用的UIPickerView
的功能。
现在,如果我使用2个拇指将两个组件一起滚动,我的应用程序很快就会崩溃,很快就会有以下信息:
*** Terminating app due to uncaught exception of class '_NSZombie_NSException'
libc++abi.dylib: terminate called throwing an exception
具有讽刺意味的是,我无法调试它。
实际上,如果我在pickerView:didSelectRow:inComponent
方法中添加断点,我甚至无法快速滚动两个组件,因为每次我将手指放在屏幕上时它都会在断点处停止。 / p>
我只能猜测原因是当滚动第一个组件时,第二个组件中假定的行数不断变化,但同时,UIPickerView
要求第二个组件的标题和编号然后就崩溃了。
但我没有找到任何可用于判断组件是否正在滚动的方法。因此,我无法找到正确的时间来拒绝pickerView
的{{1}}和delegate
对第二个组件的请求。
有没有人遇到类似的情况?
感谢您的帮助!我非常感激!
在我的代码中,错误与dataSource
有关,因此我删除了与typePicker
无关的所有其他代码。
此处,typePicker
和type
是核心数据中的两个实体,名为detailTypes
的多对多关系从details
到type
。
例如,如果类型为“Nations”,detailsTypes
将是“美国”,“法国”,“中国”等。
因此在detailTypes
中,第一个或左侧组件显示所有类型实体,第二个或右侧组件根据第一个组件中当前选择的类型显示相应的typePicker
个实体。
detailTypes
中的两个组件的第一行始终为“无”,以允许用户不选择特定类型,这就是代码中有许多“+1”的原因。
typePicker
答案 0 :(得分:6)
崩溃是由于你的代表中的这一行
NSUInteger majorTypeRow = [self.typePicker selectedRowInComponent:0] - 1;
正如其他人指出的那样,你需要保留两个单独的数组或对象,它们可以为各个组件提供dataSource。
您有一个majorType和detailType。您可以拥有majorTypes
和selectedMajorType
的数组。保留额外的selectedMajorType无需使用selectedRowInComponent:
,也不会再崩溃该应用。
#pragma mark - UIPickerViewDataSource
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 2;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
NSInteger rows = 0;
if (component) {
rows = [self.selectedMajorType.minorTypes count];
}else{
rows = [self.majorTypes count];
}
return rows+1;
}
UIPickerViewDelegate实施
- (NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
{
row--;
NSString *title = @"None";
if (component) {
NSArray *minorTypes = [self.selectedMajorType.minorTypes allObjects];
if (row >= 0 && row < [minorTypes count]) {
MinorType *minorType = minorTypes[row];
title = minorType.name;
}
}else{
if(row>=0 && row < [self.majorTypes count]){
MajorType *majorType = self.majorTypes[row];
title = majorType.name;
}
}
return title;
}
- (void)pickerView:(UIPickerView *)pickerView
didSelectRow:(NSInteger)row
inComponent:(NSInteger)component
{
row--;
if (component==0) {
if (row >= 0 && row < [self.majorTypes count]) {
self.selectedMajorType = self.majorTypes[row];
}else {
self.selectedMajorType = nil;
}
[pickerView reloadComponent:1];
}
}
答案 1 :(得分:1)
好的,我想我明白了这个问题:
将两个组件一起滚动的问题在于,由于您使用数据关系创建的依赖性,UIPickerView数据源可能会发生变化。我认为您需要创建两个分别代表左右的数组,并根据您更改的组件重新填充!
通过查看类似问题可以找到解决方案! UIPickerView with two components crashes when scrolling both
此外,关于检查您的UIPickerView是否正在滚动,您只需设置一个计时器。这里有一个有用的链接:Determining if UIPickerWheel is scrolling!通过检查当前行是否匹配,您可以(在短时间内)判断用户是否已移动轮子!
我希望这是明确和有用的!