当数据源没有数据时,自定义UIPickerView崩溃

G怀特

我有一个包含两个文本字段(类别,子类别)的屏幕,每个文本字段都连接到自定义UIPickerView。子类别视图中显示的选项取决于选择作为第一个字段的值的类别。

如果用户尚未选择类别,则选择子类别字段将弹出标准键盘(此行为很好)。

如果用户选择一个类别,然后与子类别字段进行交互,则一切正常。

当用户放入一个类别,调出子类别选择器,然后返回并清除类别字段时,就会发生问题。此时,如果用户选择子类别字段,则选择器将出现,但没有任何数据,并且与之交互将导致应用程序崩溃。

错误文字:

*** Assertion failure in -[UITableViewRowData rectForRow:inSection:], /SourceCache/UIKit_Sim/UIKit-2380.17/UITableViewRowData.m:1630
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'request for rect at invalid index path (<NSIndexPath 0x719eb60> 2 indexes [0, 0])'
*** First throw call stack:
(0x1cc3012 0x1100e7e 0x1cc2e78 0xb96665 0x22df20 0xf12de 0x481086 0x480f7a 0xa440d 0xa69eb 0x30f85a 0x30e99b 0x3100df 0x312d2d 0x312cac 0x30aa28 0x77972 0x77e53 0x55d4a 0x47698 0x1c1edf9 0x1c1ead0 0x1c38bf5 0x1c38962 0x1c69bb6 0x1c68f44 0x1c68e1b 0x1c1d7e3 0x1c1d668 0x44ffc 0x2acd 0x29f5)
libc++abi.dylib: terminate called throwing an exception

这是我的代码:

- (IBAction)showYourPicker:(id)sender {
        isCategoryPicker = true;
        // create a UIPicker view as a custom keyboard view
        UIPickerView* pickerView = [[UIPickerView alloc] init];
        [pickerView sizeToFit];
        pickerView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
        pickerView.delegate = self;
        pickerView.dataSource = self;
        pickerView.showsSelectionIndicator = YES;
        self.catPickView = pickerView;  //UIPickerView

        categoryField.inputView = pickerView;

        // create a done view + done button, attach to it a doneClicked action, and place it in a toolbar as an accessory input view...
        // Prepare done button
        UIToolbar* keyboardDoneButtonView = [[UIToolbar alloc] init];
        keyboardDoneButtonView.barStyle = UIBarStyleBlack;
        keyboardDoneButtonView.translucent = YES;
        keyboardDoneButtonView.tintColor = nil;
        [keyboardDoneButtonView sizeToFit];

        UIBarButtonItem* doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done"
                                                                        style:UIBarButtonItemStyleBordered target:self
                                                                       action:@selector(pickerDoneClicked:)];

        [keyboardDoneButtonView setItems:[NSArray arrayWithObjects:doneButton, nil]];

        // Plug the keyboardDoneButtonView into the text field...
        categoryField.inputAccessoryView = keyboardDoneButtonView;
    }

    - (IBAction)showYourSubPicker:(id)sender {
        isCategoryPicker = false;
        WCSharedCache *sharedManager = [WCSharedCache sharedManager];
        BOOL iLLAllowIt = false;
        for(int i = 0; i < [sharedManager.categories count]; i++) {
            if([[[sharedManager categories] objectAtIndex:i] isEqualToString:[categoryField text]]) {
                iLLAllowIt = true;
            }
        }
        if(!iLLAllowIt) {
            return;
        }
        // create a UIPicker view as a custom keyboard view
        UIPickerView* pickerView = [[UIPickerView alloc] init];
        [pickerView sizeToFit];
        pickerView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
        pickerView.delegate = self;
        pickerView.dataSource = self;
        pickerView.showsSelectionIndicator = YES;
        self.subCatPickView = pickerView;  //UIPickerView

        subcategoryField.inputView = pickerView;

        // create a done view + done button, attach to it a doneClicked action, and place it in a toolbar as an accessory input view...
        // Prepare done button
        UIToolbar* keyboardDoneButtonView = [[UIToolbar alloc] init];
        keyboardDoneButtonView.barStyle = UIBarStyleBlack;
        keyboardDoneButtonView.translucent = YES;
        keyboardDoneButtonView.tintColor = nil;
        [keyboardDoneButtonView sizeToFit];

        UIBarButtonItem* doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done"
                                                                       style:UIBarButtonItemStyleBordered target:self
                                                                      action:@selector(pickerDoneClicked:)];

        [keyboardDoneButtonView setItems:[NSArray arrayWithObjects:doneButton, nil]];

        // Plug the keyboardDoneButtonView into the text field...
        subcategoryField.inputAccessoryView = keyboardDoneButtonView;
    }

    - (void) pickerDoneClicked: (id) picker {
        if(isCategoryPicker) {
            [categoryField resignFirstResponder];
        } else {
            [subcategoryField resignFirstResponder];
        }
    }

    - (void) pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
        WCSharedCache *sharedManager = [WCSharedCache sharedManager];
        if(isCategoryPicker) {
            [categoryField setText:[[sharedManager categories] objectAtIndex:row]];
        } else {
            @try {
                int idx = 0;
                for(int i = 0; i < [sharedManager.categories count]; i++) {
                    if([[[sharedManager categories] objectAtIndex:i] isEqualToString:[categoryField text]]) {
                        idx = i;
                        break;
                    }
                }
                [subcategoryField setText:[[[sharedManager subcategories]objectAtIndex:idx] objectAtIndex:row]];
            } @catch (NSException *e) {
                NSLog(@"Exception: %@",e);
               [subcategoryField setText:@"" ];
            }
        }
    }

    - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
    {
        return 1;
    }

    - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
    {
        WCSharedCache *sharedManager = [WCSharedCache sharedManager];
        if(isCategoryPicker) {
            return [[sharedManager categories]count];
        } else {
            for(int i = 0; i < [sharedManager.categories count]; i++) {
                if([[[sharedManager categories] objectAtIndex:i] isEqualToString:[categoryField text]]) {
                    return [[[sharedManager subcategories] objectAtIndex:i] count];
                }
            }
        }
        return 0;
    }

    - (NSString *)pickerView: (UIPickerView *)pickerView titleForRow: (NSInteger)row forComponent:(NSInteger)component
    {
        WCSharedCache *sharedManager = [WCSharedCache sharedManager];
        if(isCategoryPicker) {
            return [[sharedManager categories] objectAtIndex:row];
        } else {
            for(int i = 0; i < [sharedManager.categories count]; i++) {
                if([[[sharedManager categories] objectAtIndex:i] isEqualToString:[categoryField text]]) {
                    return [[[sharedManager subcategories] objectAtIndex:i] objectAtIndex:row];
                }
            }
        }
        return @"";
    }

有没有什么我可以实现的方法,还是可以尝试使用的方法,还是可以恢复原始键盘的功能,或者在没有任何数据可以使用的情况下,可以阻止用户点击此字段的方法。类别的数据在NSArray中。子类别的数据位于二维NSArray中,该阵列从关联类别的索引开始索引。

G怀特

如果通过更改默认值来解决此问题:

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
    {
        WCSharedCache *sharedManager = [WCSharedCache sharedManager];
        if(isCategoryPicker) {
            return [[sharedManager categories]count];
        } else {
            for(int i = 0; i < [sharedManager.categories count]; i++) {
                if([[[sharedManager categories] objectAtIndex:i] isEqualToString:[categoryField text]]) {
                    return [[[sharedManager subcategories] objectAtIndex:i] count];
                }
            }
        }
        return 1;
    }

从零到一。显然,如果组件中的行数为0,则UIPickerView(至少在上述实现中)无法处理滚动而不会引发异常。这很好奇,因为根据Apple的UIPickerView类的文档,此方法默认值为0。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

没有数据源的Jasperreport

来自分类Dev

在UIVIewController,自定义UITableViewCell和实用程序类之间管理UIPickerView数据源

来自分类Dev

Angular MatTable中没有数据源检测

来自分类Dev

没有数据源的FormView插入,编辑,更新

来自分类Dev

在没有数据源的Wildfly中启动.war

来自分类Dev

RDLC文件中的自定义数据源

来自分类Dev

自定义数据源对象未正确创建

来自分类Dev

自定义 UICollectionView 数据源和委托

来自分类Dev

使用自定义类设置 UICollectionView 数据源和委托时的错误消息

来自分类Dev

具有自定义委托或数据源的View Controller的状态保留

来自分类Dev

具有自定义数据源的UITableViewController不显示单元格

来自分类Dev

带有自定义数据源的角度材料复选框和批量选择

来自分类Dev

如何通过管理API获取自定义数据源的自定义维度?

来自分类Dev

使用KendoUI自定义下载(仅包含带有asp.mvc包装器和数据源的网格)时出现“未定义不是函数”错误

来自分类Dev

如何在使用sql数据源时在下拉列表中添加自定义项目

来自分类Dev

在nvd3散点图中自定义没有数据标签

来自分类Dev

自定义QAbstractNetworkCache实现;QAbstractNetworkCache :: insert(QIODevice * device)设备没有数据

来自分类Dev

即使列中没有数据,熊猫也会以自定义列为中心

来自分类Dev

没有数据的AgGrid自定义模板无法正常工作

来自分类Dev

自定义适配器中没有数据

来自分类Dev

数据表AJAX数据源和自定义分页操作

来自分类Dev

数据表AJAX数据源和自定义分页操作

来自分类Dev

从Kendo Grid数据源导出所有数据

来自分类Dev

在没有数据源的情况下将项目添加到Kendo MultiSelect

来自分类Dev

在没有数据源的情况下在ComboBox上设置DisplayMember和ValueMember

来自分类Dev

在没有数据源的情况下创建多个Excel图表的平均值

来自分类Dev

自定义DataGridViewCell不触发数据源更改事件

来自分类Dev

在WebSphere服务器上使用JNDI的Spring自定义数据源连接

来自分类Dev

将自定义数据源添加到Jaspersoft Studio

Related 相关文章

  1. 1

    没有数据源的Jasperreport

  2. 2

    在UIVIewController,自定义UITableViewCell和实用程序类之间管理UIPickerView数据源

  3. 3

    Angular MatTable中没有数据源检测

  4. 4

    没有数据源的FormView插入,编辑,更新

  5. 5

    在没有数据源的Wildfly中启动.war

  6. 6

    RDLC文件中的自定义数据源

  7. 7

    自定义数据源对象未正确创建

  8. 8

    自定义 UICollectionView 数据源和委托

  9. 9

    使用自定义类设置 UICollectionView 数据源和委托时的错误消息

  10. 10

    具有自定义委托或数据源的View Controller的状态保留

  11. 11

    具有自定义数据源的UITableViewController不显示单元格

  12. 12

    带有自定义数据源的角度材料复选框和批量选择

  13. 13

    如何通过管理API获取自定义数据源的自定义维度?

  14. 14

    使用KendoUI自定义下载(仅包含带有asp.mvc包装器和数据源的网格)时出现“未定义不是函数”错误

  15. 15

    如何在使用sql数据源时在下拉列表中添加自定义项目

  16. 16

    在nvd3散点图中自定义没有数据标签

  17. 17

    自定义QAbstractNetworkCache实现;QAbstractNetworkCache :: insert(QIODevice * device)设备没有数据

  18. 18

    即使列中没有数据,熊猫也会以自定义列为中心

  19. 19

    没有数据的AgGrid自定义模板无法正常工作

  20. 20

    自定义适配器中没有数据

  21. 21

    数据表AJAX数据源和自定义分页操作

  22. 22

    数据表AJAX数据源和自定义分页操作

  23. 23

    从Kendo Grid数据源导出所有数据

  24. 24

    在没有数据源的情况下将项目添加到Kendo MultiSelect

  25. 25

    在没有数据源的情况下在ComboBox上设置DisplayMember和ValueMember

  26. 26

    在没有数据源的情况下创建多个Excel图表的平均值

  27. 27

    自定义DataGridViewCell不触发数据源更改事件

  28. 28

    在WebSphere服务器上使用JNDI的Spring自定义数据源连接

  29. 29

    将自定义数据源添加到Jaspersoft Studio

热门标签

归档