iPhone TableView with TextFields - 接下来,上一个按钮问题

时间:2013-02-25 09:29:56

标签: objective-c xcode uitableview

我有一个表视图,其中包含用于创建表单的大量单元格。我创建了一个自定义的TableViewCell。此单元格包含标签和文本字段,因此,例如,每行看起来都像这样

enter image description here

我还有一个包含标签和文本视图的自定义表格单元格,看起来与上面的图像相同,只是单元格更大,以便为textview提供空间。

现在,每个文本字段和文本视图都添加了一个工具栏,因此当文本字段成为第一个响应者时,会显示一个工具栏,其中包含按钮,完成,上一个和下一个按钮。

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

        UIBarButtonItem *nextButton = [[UIBarButtonItem alloc]initWithTitle:@"Next" style:UIBarButtonItemStyleDone target:self action:@selector(nextTableTextField:)];

        UIBarButtonItem *previousButton = [[UIBarButtonItem alloc]initWithTitle:@"Previous" style:UIBarButtonItemStyleDone target:self action:@selector(previousTableTextField:)];


        UIToolbar *numberToolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 50)];
        numberToolbar.barStyle = UIBarStyleBlackTranslucent;
        numberToolbar.items = [NSArray arrayWithObjects:
                               previousButton,
                               nextButton,
                               [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
                               doneButton,
                               nil];

        [numberToolbar sizeToFit];

        field.inputAccessoryView = numberToolbar;

我遇到的问题是,假设我有10个这样的表行,屏幕只能显示大约5个完整行和第6行的一些内容。我应该添加我还将代码添加到文本字段委托,以便当文本字段成为第一响应者时,屏幕滚动以允许完全显示文本字段。有关代码,请参阅我的旧帖子here

因此,当屏幕加载时,我按下第一个单元格,然后单击下一步,工作正常,移动到下一个单元格中的第二个文本字段。然后我再次点击下一个按钮,然后进入第3个单元格,然后是第4个单元格,然后是第5个单元格。此时此问题就出现了。当我在第5个单元格上,然后单击下一个,第6个文本字段成为第一个响应者,但屏幕由于某种原因不滚动。现在更大的问题是,当我再次点击下一步时,它不会移动到第7个文本字段,因为第7个单元格不在内存中,因为它在屏幕上不可见。因此,如果我点击下一步,它将不会执行任何操作,文本字段6将保留为第一响应者。所以我需要先向下滚动一下,所以在下一个按钮工作之前,单元格7是可见的,并使下一个文本字段成为第一个响应者。

点击上一个按钮时出现同样的问题,如果点击上一个按钮而前一个单元格不在屏幕上,那么在屏幕上显示该单元格之前,它将不会执行任何操作。

这让我非常头疼,似乎无法找到解决方法。还有其他人有类似的问题吗?对这个问题有好的解决方法吗?

提前致谢

编辑:

我还应该添加这使得保存数据成为一个问题,因为我说有一个按钮,当点击循环遍历每个表格单元并将数据保存在每个字段中时,它只会循环显示在屏幕上可见的表格单元格并忽略其余的。

2 个答案:

答案 0 :(得分:1)

它适用于我,我正在使用块,当按下键盘上的“完成”按钮将焦点移动到下一个文本屏幕单元格时触发:

FRTextFieldTableViewCell *textFieldCell = [tableView_ dequeueReusableCellWithIdentifier:[FRTextFieldTableViewCell reuseIdentifier]];
        if(textFieldCell == nil) {
            textFieldCell = [[FRTextFieldTableViewCell alloc] initWithStyle:
                             UITableViewCellStyleDefault reuseIdentifier:[FRTextFieldTableViewCell reuseIdentifier]];
        }

        [textFieldCell.textField initialize];
        textFieldCell.textField.secureTextEntry = (indexPath.row == 3);

        __weak FRSignUpViewController *self_ = self;
        __weak FRTextFieldTableViewCell *textFieldCell_ = textFieldCell;
        if(indexPath.row == 1) {
            textFieldCell.textField.placeholder = NSLocalizedString(@"name", @"");
            textFieldCell.object = self.regUser.name;
            textFieldCell.didChangedValueAction = ^(NSString *object) {
                [self_ setName:object];
            };
            textFieldCell.didEndOnExitAction = ^{
                [self_ setName:textFieldCell_.object];
                FRTextFieldTableViewCell *nextCell = (FRTextFieldTableViewCell *)[self_.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:0]];
                [nextCell.textField becomeFirstResponder];
            };
        }
        if(indexPath.row == 2) {
            textFieldCell.textField.placeholder = NSLocalizedString(@"email", @"");
            textFieldCell.didChangedValueAction = ^(NSString *object) {
                [self_ setLoginString:object];
            };
            textFieldCell.didEndOnExitAction = ^{
                [self_ setLoginString:textFieldCell_.object];
                FRTextFieldTableViewCell *nextCell = (FRTextFieldTableViewCell *)[self_.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:3 inSection:0]];
                [nextCell.textField becomeFirstResponder];
            };
        }
        if(indexPath.row == 3) {
            textFieldCell.textField.placeholder = NSLocalizedString(@"password", @"");
            textFieldCell.didChangedValueAction = ^(NSString *object) {
                [self_ setPasswordString:object];
            };
            textFieldCell.didEndOnExitAction = ^{
                [self_ setPasswordString:textFieldCell_.object];
                [self_ signUp];
            };
        }
        [textFieldCell reloadData];
        return textFieldCell;

BlocksTypedefs:

/* type defenition for blocks, can be used by any app class */
typedef void (^CompletionBlock)(id, NSError *);
typedef void (^SimpleBlock)(void);
typedef void (^InfoBlock)(id);
typedef void (^ConfirmationBlock)(BOOL);

TableViewCell代码:

.h文件:

#import "FRTableViewCell.h"
#import "BlocksTypedefs.h"
#import "FRTextFieldWithPadding.h"

@interface FRTextFieldTableViewCell : FRTableViewCell <UITextFieldDelegate>

@property (nonatomic, copy) SimpleBlock didEndOnExitAction;
@property (nonatomic, copy) SimpleBlock didEndEditingAction;
@property (nonatomic, copy) InfoBlock didChangedValueAction;
@property (nonatomic, strong) IBOutlet FRTextFieldWithPadding *textField;

@end

的.m:

    #import "FRTextFieldTableViewCell.h"

@implementation FRTextFieldTableViewCell

- (void)awakeFromNib {
    [super awakeFromNib];
    self.backgroundColor = [UIColor clearColor];
}

- (void)reloadData {
    self.textField.text = self.object;
}

- (IBAction)textFieldValueDidChanged:(UITextField *)sender {
    self.object = sender.text;
    if (self.didChangedValueAction) {
        self.didChangedValueAction(self.object);
    }
}

- (IBAction)textFieldDidEndOnExit:(UITextField *)sender {
    self.object = sender.text;
    if (self.didEndOnExitAction) {
        self.didEndOnExitAction();
    }
}

#pragma mark - UITextFieldDelegate

- (void)textFieldDidEndEditing:(UITextField *)textField {
    self.object = textField.text;
    if (self.didEndEditingAction) {
        self.didEndEditingAction();
    }
}

@end

答案 1 :(得分:0)

CGRect frame = CGRectMake(0.0, self.view.bounds.size.height, self.view.bounds.size.width, 44.0);
fieldAccessoryView = [[UIToolbar alloc] initWithFrame:frame];
fieldAccessoryView.barStyle = UIBarStyleBlackOpaque;
fieldAccessoryView.tag = 200;

[fieldAccessoryView setBarStyle:UIBarStyleBlack];

UIBarButtonItem *spaceButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone  target:self action:@selector(done:)];

UISegmentedControl* segmentedControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:NSLocalizedString(@"Previous", @""), NSLocalizedString(@"Next", @""), nil]];
[segmentedControl addTarget:self action:@selector(segmentAction:) forControlEvents:UIControlEventValueChanged];
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
[segmentedControl setMomentary:YES];
UIBarButtonItem *segmentButton = [[UIBarButtonItem alloc] initWithCustomView:segmentedControl];

[fieldAccessoryView setItems:[NSArray arrayWithObjects:segmentButton, spaceButton, doneButton, nil] animated:NO];
[segmentButton release];
[spaceButton release];
[doneButton release];
[segmentedControl release];