简体   繁体   English

NSMutableArray快速枚举问题

[英]NSMutableArray fast enumeration issue

Newbie obj-c question. 新手obj-c问题。

I have a custom tableview with four custom cells. 我有四个自定义单元格的自定义tableview。 In every cell is a editable textfield for customer info. 每个单元格中都有一个用于客户信息的可编辑文本字段。 I need to improve switching between textfields by Input Accessory View. 我需要通过输入附件视图改进文本字段之间的切换。 http://uaimage.com/image/62f08045 http://uaimage.com/image/62f08045

I created an NSMutableArray with capacity 4. I tagged textfields and added them in this array in text field delegate method: 我创建了一个容量为4的NSMutableArray。我标记了文本字段,并将其添加到文本字段委托方法的此数组中:

- (BOOL) textFieldShouldReturn:(UITextField *)textField {
    FDTextFieldCell *cell = (FDTextFieldCell *)[textField superview];
    NSIndexPath *indexPath = [[self tableView] indexPathForCell:cell];

    if ([indexPath section] == 0) {
        if ([indexPath row] == 0) {
            [[FDProfile sharedProfile] setName:[textField text]];
            [textField setTag:1];
            [textFieldsArray insertObject:textField atIndex:0];
        } else if ([indexPath row] == 1) {
            [[FDProfile sharedProfile] setSurname:[textField text]];
            [textField setTag:2];
            [textFieldsArray insertObject:textField atIndex:1];
        } else if ([indexPath row] == 2) {
            [[FDProfile sharedProfile] setNickname:[textField text]];
            [textField setTag:3];
            [textFieldsArray insertObject:textField atIndex:2];
        } else if ([indexPath row] == 3) {
            [[FDProfile sharedProfile] setEmail:[textField text]];
            [textField setTag:4];
            [textFieldsArray insertObject:textField atIndex:3];
            [textField resignFirstResponder];
        }
    }

    [[self tableView] reloadData];
    return YES;
}

Now i try to improve functionality of button "Next": 现在,我尝试改善按钮“下一步”的功能:

- (void) inputAccessoryViewDidSelectNext:(FDInputAccessoryView *)view {
    for (UITextField *textField in [self textFieldsArray]) {
        if ([textField isFirstResponder]) {
     textField = [[self textFieldsArray] objectAtIndex:textField.tag + 1];
            [textField becomeFirstResponder];
        }

    }
}

But this code doesn't works. 但是此代码不起作用。 I think there is an issue with using fast enumeration? 我认为使用快速枚举有问题吗?

Can somebody help with this? 有人可以帮忙吗? Thanks, Alex. 谢谢,亚历克斯。


Some ideas to solving from c-had: 从c-had解决的一些想法:

  1. Why are you setting up your textFieldsArray in textFieldShouldReturn:? 为什么要在textFieldShouldReturn:中设置textFieldsArray? Shouldn't this be done somewhere where initialization is done (eg viewDidLoad of the view controller)? 难道不应该在完成初始化的地方(例如,视图控制器的viewDidLoad)完成此操作吗? The problem might be that your array is never actually set up, or is only partly set up. 问题可能是您的阵列从未真正设置过,或者只是部分设置了。 Also, putting the setup here means it will be called over and over, mutating your array each time and screwing things up. 同样,将设置放在此处意味着将一遍又一遍地调用它,每次都会更改您的数组并弄乱它们。
  2. Your tags are off by one. 您的标签偏离了一个。 You should be assigning them starting at 0, not 1 (or accounting for the difference in inputAccessoryViewDidSelectNext:). 您应该从0而不是1开始分配它们(或考虑inputAccessoryViewDidSelectNext:中的差异)。 If your code was working, it would skip 2 text fields, as the first field would return tag 1, and you'd skip to objectAtIndex:2, which is the 3rd field. 如果您的代码在工作,它将跳过2个文本字段,因为第一个字段将返回标记1,并且您将跳至objectAtIndex:2,即第三个字段。
  3. You don't account for going off the end. 您无需考虑到底。 If you're at the last field, incrementing will not go back to the beginning. 如果您位于最后一个字段,则递增不会回到开头。

I'd actually recommend not using tags at all. 我实际上建议完全不使用标签。 Instead, at setup time, just loop through the fields adding them in order to your array. 相反,在设置时,只需遍历字段即可将它们添加到阵列中。 Then, in inputAccessoryViewDidSelectNext:, use a counter instead of fast enumeration to figure out where you are. 然后,在inputAccessoryViewDidSelectNext:中,使用计数器而不是快速枚举来确定您的位置。

  1. Why are you setting up your textFieldsArray in textFieldShouldReturn: ? 为什么要设置您textFieldsArraytextFieldShouldReturn: Shouldn't this be done somewhere where initialization is done (eg viewDidLoad of the view controller)? 难道不应该在完成初始化的地方(例如,视图控制器的viewDidLoad )完成此操作吗? The problem might be that your array is never actually set up, or is only partly set up. 问题可能是您的阵列从未真正设置过,或者只是部分设置了。 Also, putting the setup here means it will be called over and over, mutating your array each time and screwing things up. 同样,将设置放在此处意味着将一遍又一遍地调用它,每次都会更改您的数组并弄乱它们。
  2. Your tags are off by one. 您的标签偏离了一个。 You should be assigning them starting at 0, not 1 (or accounting for the difference in inputAccessoryViewDidSelectNext: ). 您应该从0开始分配它们,而不是从1开始(或考虑inputAccessoryViewDidSelectNext:的差异)。 If your code was working, it would skip 2 text fields, as the first field would return tag 1, and you'd skip to objectAtIndex:2, which is the 3rd field. 如果您的代码在工作,它将跳过2个文本字段,因为第一个字段将返回标记1,并且您将跳至objectAtIndex:2,即第三个字段。
  3. You don't account for going off the end. 您无需考虑到底。 If you're at the last field, incrementing will not go back to the beginning. 如果您位于最后一个字段,则递增不会回到开头。

I'd actually recommend not using tags at all. 我实际上建议完全不使用标签。 Instead, at setup time, just loop through the fields adding them in order to your array. 相反,在设置时,只需遍历字段即可将它们添加到阵列中。 Then, in inputAccessoryViewDidSelectNext: , use a counter instead of fast enumeration to figure out where you are. 然后,在inputAccessoryViewDidSelectNext: ,使用计数器而不是快速枚举来确定您的位置。

I suggest do not use any array to have textFields, instead get the textFields from the cells of the tableView. 我建议不要使用任何具有textFields的数组,而应从tableView的单元格中获取textFields。

You can do in this way, 你可以这样

Set your textFields tag with the indexPath of cell in which it is. 使用所在单元格的indexPath设置textFields标记。

Then use textFieldDidEnd delegate, from the tag get the cell of the next textfield later from cell get the textfield and make it first responder. 然后使用textFieldDidEnd委托,从标记中获取下一个文本字段的单元格,稍后从cell中获取文本字段,并将其设为第一响应者。

If you can get the cell from FDInputAccessoryView in below method, you can also do it here.. 如果可以通过以下方法从FDInputAccessoryView获取单元格,则也可以在此处进行操作。

- (void) inputAccessoryViewDidSelectNext:(FDInputAccessoryView *)view`

According to the documentation, "[Fast] Enumeration is “safe”—the enumerator has a mutation guard so that if you attempt to modify the collection during enumeration, an exception is raised." 根据文档,“ [快速]枚举是“安全的”-枚举器具有突变防护,因此,如果您尝试在枚举期间修改集合,则会引发异常。 That's probably why it doesn't work. 这可能就是为什么它不起作用的原因。 You could probably accomplish the same thing with an ordinary while loop. 您可以使用普通的while循环完成相同的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM