iphone – UITableView在编辑嵌入式UITextView时滚动太远

我已经成功地在UITableViewCell中嵌入了一个UITextView,并且大部分表工作正常.但是,当我在UITextView上启用编辑并开始编辑时,表格会向上移动太远,使光标模糊不清.有没有办法控制tableview滚动的距离?手动将视图滚动到单元格可以正常工作,但在向下滚动并进入视图之前,视图仍会向上滚动.

这是我的意思的一个例子:
编辑UITextField – 该字段整齐地放置在键盘正上方.
http://imageshack.us/photo/my-images/13/textfield.png/

编辑UITextView – 该字段位于键盘上方,从键盘上移除工具栏不会影响任何内容)
http://imageshack.us/photo/my-images/809/textview.png/

这是与UITableViewController对象中的UITextView相关的所有代码:

- (void)viewDidLoad
{
    [super viewDidLoad];    

    self.navigationItem.rightBarButtonItem = self.editButtonItem;

    [[NSNotificationCenter defaultCenter] addObserver: self
                                             selector: @selector(keyboardWillShow:) 
                                                 name: UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver: self
                                             selector: @selector(keyboardWillHide:) 
                                                 name: UIKeyboardWillHideNotification object:nil];
}

- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
    viewTargetedForEditing = (UIView *)textView;
    return YES;
}

- (void)textViewDidBeginEditing:(UITextView *)textView
{
    [self.navigationController setNavigationBarHidden:YES animated:YES];


    // shrink the textView to fit on-screen
    originalTextViewFrame = textView.frame;
    CGRect keyboardRect = [[keyboardUserinfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    CGFloat keyboardHeight = keyboardRect.size.height;


    CGRect newViewFrame = textView.frame;
    CGFloat spaceAboveKeyboard = self.containerView.frame.size.height - keyboardHeight;
    newViewFrame.size.height = (spaceAboveKeyboard < textView.frame.size.height) ? spaceAboveKeyboard : textView.frame.size.height;


    /* animate the calculations */

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:[[keyboardUserinfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];

    textView.frame = newViewFrame;

    [UIView commitAnimations];



    // recalculate the keyboard height, in case we aren't in portrait mode
    CGFloat toolbarHeight;
    if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) {
        toolbarHeight = 44.0;
    } else {
        toolbarHeight = 32.0;
    }

    CGRect frame = textView.inputAccessoryView.frame;
    frame.size.height = toolbarHeight;
}

- (void)endTextViewEditing
{
    [viewTargetedForEditing resignFirstResponder];
}

- (void)textViewDidEndEditing:(UITextView *)textView
{
    [self.navigationController setNavigationBarHidden:NO animated:YES];
}

#pragma mark - Keyboard Notifications

- (void)keyboardWillShow:(NSNotification *)notification
{
    [keyboardUserinfo release];
    keyboardUserinfo = [[notification userInfo] retain];
    [self viewDidBeginEditing:viewTargetedForEditing];
}
- (void)keyboardWillHide:(NSNotification *)notification
{
    [keyboardUserinfo release];
    keyboardUserinfo = [[notification userInfo] retain];
    [self viewDidEndEditing:viewTargetedForEditing];
}

- (void)viewDidBeginEditing:(id)aView
{
    // called 2nd

    UITableViewCell *cell = (UITableViewCell *)[aView superview];
    [self.tableView scrollToRowAtIndexPath:[self.tableView indexPathForCell:cell] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
- (void)viewDidEndEditing:(id)aView
{   
    NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)[viewTargetedForEditing superview]];

    gallupAppDelegate *appDelegate = (gallupAppDelegate *)[[UIApplication sharedApplication] delegate];

    switch (indexPath.section) {
        case SectionDescription:
            if (![[(UITextField *)aView text] isEqualToString:self.plan.Description]) {
                self.plan.Description = [(UITextField *)aView text];
                [appDelegate saveManagedContext];
            }
            break;

        case SectionNotes:
            if (![[(UITextView *)aView text] isEqualToString:self.plan.Notes]) {
                self.plan.Notes = [(UITextView *)aView text];
                [appDelegate saveManagedContext];
            }
            break;

        case SectionLocation:
            if (![[(UITextField *)aView text] isEqualToString:self.plan.Location]) {
                self.plan.Location = [(UITextField *)aView text];
                [appDelegate saveManagedContext];
            }
            break;
    }
}

TextViewCell是UITableViewCell的子类,它是给我滚动问题的单元格.这是实现:

@implementation TextViewCell

@synthesize contents=_contents;

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        _contents = [[UITextView alloc] initWithFrame:CGRectZero];
        [self addSubview:_contents];
        self.contents.font = [UIFont systemFontOfSize:17];
        self.contents.dataDetectorTypes = UIDataDetectorTypeAll;


        CGRect frame = CGRectMake(0, 0, self.window.frame.size.width, 44.0);
        UIBarButtonItem *spacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
        UIBarButtonItem *done = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(endTextViewEditing)];
        UIToolbar *textViewToolbar = [[UIToolbar alloc] initWithFrame:frame];
        textViewToolbar.barStyle = UIBarStyleBlackOpaque;
        [textViewToolbar setItems:[NSArray arrayWithObjects:spacer, done, nil]];

        self.contents.inputAccessoryView = textViewToolbar;
    }
    return self;
}

- (void)endTextViewEditing
{
    [self.contents resignFirstResponder];
}

#define LEFT_MARGIN 15
#define TOP_MARGIN 5
- (void)layoutSubviews
{
    [super layoutSubviews];

    CGFloat width = self.frame.size.width - (LEFT_MARGIN *2);
    CGFloat height = self.frame.size.height - (TOP_MARGIN *2);
    self.contents.frame = CGRectMake(LEFT_MARGIN, TOP_MARGIN, width, height);
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    //[super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

- (void)dealloc
{
    [super dealloc];
}

@end

最佳答案 事实证明,继承UITableView并实现以下解决了以下问题:

- (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated
{
    [super setContentOffset:contentOffset animated:animated];
    return;



    static int i = 0;
    if (0 == i) {
        i++;
    } else {
        i = 0;
        [super setContentOffset:contentOffset animated:animated];
    }
    return;
}

显然,-setContentOffset:animated:message被发送了2x,如果第一次允许第二次运行,则不能正常工作.

有没有人有任何问题,为什么这将解决问题?

点赞