2013-04-26 3 views
3

Я пытаюсь создать копию приложения Any.DO. tableHeaderView - это вид «NewTaskCell», который содержит a с UITextField. По какой-то причине таблицаView не может прокручиваться до конца после появления клавиатуры. Вот что я пытался:UITableView не может прокручивать нижнюю границу после отклонения клавиатуры

  1. Изменение кадра Tableview
  2. Изменение границы в Tableview
  3. Изменение contentSize в Tableview
  4. Обновление вид колонтитулов после клавиатуры увольняет

Это должно быть связано с клавиатурой или текстовым полем, потому что это происходит только при появлении клавиатуры.

В приведенной ниже анимации вы можете увидеть, что если я нажму кнопку «плюс» и покажу клавиатуру, то tableView не сможет прокрутить вниз. После этого, если я нажму кнопку плюс, а не будет показать клавиатуру, то она может прокрутить до нижнего штрафа.

Вот исходный код для всего проекта: Any.DO

Это то, что в моем методе viewDidLoad.

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    [[self tableView] setAllowsSelection: YES]; 
    [[self tableView] setShowsVerticalScrollIndicator: NO]; 

    // Make sure there aren't any empty cells showing at the bottom 
    // Caused initial error [[self tableView] setTableFooterView: [UIView new]]; 

    // Fixes error at first, until the keyboard shows up 
    UIView *footer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 45)]; 
footer.backgroundColor = [UIColor clearColor]; 
self.tableView.tableFooterView = footer; 

    // Make the separators look right 
    [[self tableView] setSeparatorStyle: UITableViewCellSeparatorStyleSingleLine]; 
    [[self tableView] setSeparatorColor: [UIColor colorWithWhite: 0.95 alpha: 1]]; 

    UINib *nibTwo = [UINib nibWithNibName: @"TaskCell" bundle: nil]; 
    [[self tableView] registerNib: nibTwo forCellReuseIdentifier: @"TaskCell"]; 

    // Create the new task cell to go above the tableView 
    // -------------------------------------------------- 
    NewTaskCell *myNewTaskCell = [[NewTaskCell alloc] init]; 

    // Need to access it later to show the keyboard 
    [self setTheNewTaskCell: myNewTaskCell]; 

    [[theNewTaskCell view] setFrame: CGRectMake(0, 0, 320, 44)]; 
    [[[theNewTaskCell reminderButton] layer] setOpacity: 0]; 
    [[[theNewTaskCell locationButton] layer] setOpacity: 0]; 
    [[[theNewTaskCell addTaskButton] layer] setOpacity: 0]; 

    // Assign a method for each button 
    [[theNewTaskCell reminderButton] addTarget:self action:@selector(addReminder)  forControlEvents: UIControlEventTouchUpInside]; 
    [[theNewTaskCell locationButton] addTarget:self action:@selector(addLocationReminder) forControlEvents: UIControlEventTouchUpInside]; 
    [[theNewTaskCell addTaskButton] addTarget:self action:@selector(addTaskToList) forControlEvents: UIControlEventTouchUpInside]; 

    // Separator view 
    UIView *separatorView = [[UIView alloc] initWithFrame: CGRectMake(0, 43, 320, 1)]; 
    [separatorView setBackgroundColor: [UIColor colorWithWhite: 0.5 alpha: 0.2]]; 
    [[theNewTaskCell view] addSubview: separatorView]; 

    [[self tableView] setTableHeaderView: [theNewTaskCell view]]; 
    [[self tableView] setContentInset: UIEdgeInsetsMake(-44, 0, 0, 0)]; 
    // --------------------------------------------------- 
    // For Reordering 
    [[self tableView] setEditing: YES]; 

    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget: self action: @selector(longPress:)]; 
    [longPress setMinimumPressDuration: 0.3]; 
    [longPress setDelaysTouchesBegan: YES]; 

    [self setLongPressGesture: longPress]; 
    [[self tableView] addGestureRecognizer: longPress]; 
} 

код, когда кнопка + нажата

-(void)makeNewTask 
{ 
    // Create the fromPosition and toPosition of the label animation 
    CGRect fromPosition; 
    CGRect toPosition = CGRectMake(todayDayLabel.frame.origin.x +  todayDayLabel.superview.frame.origin.x, todayDayLabel.frame.origin.y + todayDayLabel.superview.frame.origin.y, todayDayLabel.frame.size.width, todayDayLabel.frame.size.height); 

    if ([self dayType] == TaskDayTypeToday) 
     fromPosition = toPosition; 
    else if ([self dayType] == TaskDayTypeTomorrow) 
     fromPosition = CGRectMake(tomorrowDayLabel.frame.origin.x + tomorrowDayLabel.superview.frame.origin.x, tomorrowDayLabel.frame.origin.y + tomorrowDayLabel.superview.frame.origin.y, tomorrowDayLabel.frame.size.width, tomorrowDayLabel.frame.size.height); 
    else if ([self dayType] == TaskDayTypeUpcoming) 
     fromPosition = CGRectMake(upcomingDayLabel.frame.origin.x + upcomingDayLabel.superview.frame.origin.x, upcomingDayLabel.frame.origin.y + upcomingDayLabel.superview.frame.origin.y, upcomingDayLabel.frame.size.width, upcomingDayLabel.frame.size.height); 
    else 
     fromPosition = CGRectMake(somedayDayLabel.frame.origin.x + somedayDayLabel.superview.frame.origin.x, somedayDayLabel.frame.origin.y + somedayDayLabel.superview.frame.origin.y, somedayDayLabel.frame.size.width, somedayDayLabel.frame.size.height); 
    // ------------------------------------------------------------- 

    isLoading = YES; 

    [[self tableView] reloadData]; 

    // Make sure the scroller doesn't show up on the side 
    [[self tableView] setShowsVerticalScrollIndicator: NO]; 

    // Create the label and animate it ------------------------- 
    UILabel *lbl = [[[[[NSBundle mainBundle] loadNibNamed: @"DayCell" owner: self options:nil] objectAtIndex: 0] subviews] objectAtIndex: 0]; 

    if ([self dayType] == TaskDayTypeToday) 
     [lbl setText: @"TODAY"]; 
    if ([self dayType] == TaskDayTypeTomorrow) 
     [lbl setText: @"TOMORROW"]; 
    if ([self dayType] == TaskDayTypeUpcoming) 
     [lbl setText: @"UPCOMING"]; 
    if ([self dayType] == TaskDayTypeSomeday) 
     [lbl setText: @"SOMEDAY"]; 

    [self setTheDayLabel: lbl]; 
    [theDayLabel setFrame: fromPosition]; 

    [theDayLabel setTranslatesAutoresizingMaskIntoConstraints: YES]; 
    [[self tableView] addSubview: theDayLabel]; 

    // animate it moving to the right position 
    if (!animateContentInset) { 
     [[self tableView] setContentInset: UIEdgeInsetsMake(0, 0, 0, 0)]; 
     [[self tableView] setScrollEnabled: NO]; 
    } 
    else { 
     [UIView animateWithDuration: 0.4 delay: 0 options: UIViewAnimationOptionCurveEaseOut animations: ^{ 
      [[self tableView] setContentInset: UIEdgeInsetsMake(0, 0, 0, 0)]; 
      [theDayLabel setFrame: toPosition]; 
     } completion: ^(BOOL done){ 
      [[self tableView] setScrollEnabled: NO]; 
     }]; 
    } 
    // ---------------------------------------------------------- 
    // Create the UIButton to get back to the tableView 
    UIButton *backToTableView = [UIButton buttonWithType: UIButtonTypeCustom]; 
    [backToTableView setFrame: CGRectMake(1, 45, 320, 480)]; 
    [backToTableView addTarget: self action: @selector(showTableView) forControlEvents: UIControlEventTouchUpInside]; 

    [[self tableView] addSubview: backToTableView]; 

    // Show the keyboard 
    [[theNewTaskCell theNewTaskTextField] setDelegate: self]; 
    //[[theNewTaskCell theNewTaskTextField] becomeFirstResponder]; 
} 

код для кнопки backToTableView

-(void)showTableView 
{ 
    [theDayLabel setHidden: YES]; 

    [[self tableView] setScrollEnabled: YES]; 

    [UIView animateWithDuration: 0.4 animations:^{ 
     // self.tableView.contentInset = UIEdgeInsetsZero; 
     [[self tableView] setContentInset: UIEdgeInsetsMake(-REFRESH_HEADER_HEIGHT, 0, 0, 0)]; 

     // Get the newTaskCell view, then get the textfield from that view 
     [[theNewTaskCell theNewTaskTextField] setText: @""]; 
     [[theNewTaskCell addTaskButton] setAlpha: 0]; 
     [[theNewTaskCell reminderButton] setAlpha: 0]; 
     [[theNewTaskCell locationButton] setAlpha: 0]; 

     [[theNewTaskCell theNewTaskTextField] resignFirstResponder]; 

     // Remove the button to go back to the tableView 
     for (UIView *v in [[self tableView] subviews]) { 
      if (v.frame.origin.x == 1) 
       [v removeFromSuperview]; 
     } 

     isLoading = NO; 

     [[self tableView] reloadData]; 
    }]; 
} 

Это то, что этот вопрос выглядит следующим образом:

issue

+0

Можете ли вы выслать мне исходный код? Проверьте мой адрес электронной почты в своем профиле. Grts – Foo

+0

Не удалось найти свой адрес электронной почты в своем профиле, но вот исходный код: [Any.DO] (https://dl.dropboxusercontent.com/s/th5lpkw16eicaxf/Any.DO.zip?token_hash=AAH953gA5iOL4O6T8PxRsKYjncVC7EjZyKxNGaYuCDsPUA&dl=1) – bbraunj

ответ

1

Я решил эту проблему, добавив этот код в метод showTableView:

[[self tableView] setContentInset: UIEdgeInsetsMake(REFRESH_HEADER_HEIGHT, 0, 0, 0)]; 
[[self tableView] setContentInset: UIEdgeInsetsMake(0, 0, 0, 0)]; 
+0

Это похоже на исправление, которое работает для меня (см. Мой ответ). Однако почему две строки, так как вторая строка кода просто отменяет первый? Вам не нужно только это: [[self tableView] setContentInset: UIEdgeInsetsMake (0, 0, 0, 0)]; ? – stonedauwg

-1

Вы можете настроить рамку tableView на весь экран, который также включает строку состояния. Уменьшить высоту вашего Tableview к 20px

[[self tableView] setFrame:CGRectOffset(self.tableView.frame, 0, -20)]; 

или установить рамки для self.view.frame

+1

Возможно УМЕНЬШЕНИЕ высоты будет вернее? –

+0

отредактировал его! благодаря! –

2

Похоже, ваш UITableView это компенсируется 20px в строке состояния. Вы должны уменьшить высоту вашего UITableView на 20 пикселей, и он будет исправлен.

0

Если это смещение является проблемой - один из вариантов решения этой проблемы - переход к полноэкранному экрану для всего использования всего лишь для этого ViewController.

Этот вопрос ответ вы как - Is this the right way to make an iPad app full screen?

1

не могли бы понять, что вы пытаетесь сделать в коде.

Но, глядя на анимацию, я думаю, вам просто нужно уменьшить высоту вашего стола. Посмотрите на 10-20 баллов.

Это поведение обычно наблюдается, когда высота кадров & больше, чем видимая область.установив высоту кадра в соответствии с высотой рамки, которая будет отображаться в прокрутке таблицы.

+0

Я частично исправил его, но он по-прежнему не может прокручиваться до нижней части клавиатуры. Плохой код был '[[self tableView] setTableFooterView: [UIView new]];' Можете ли вы проверить обновленный вопрос/анимацию? – bbraunj

+0

Я попытался бы выяснить, что происходит, проверяя высоту кадра tableView перед нажатием кнопки «плюс», когда вы показываете клавиатуру и после того, как вы отменили FirstResponder. Я все еще думаю, что к этому приводят неправильные значения фреймов. (высота рамки таблицы больше, чем видимая область после скрытия клавиатуры) –

+0

Я решил проблему, вызвав методы makeNewTask и showTableView очень быстро после отклонения клавиатуры. Я до сих пор не знаю, почему это работает, но это так. Рамка не меняется, когда клавиатура появляется вверх и вниз. – bbraunj

0

В будущем на iOS7 кто испытывает аналогичные проблемы могли бы сделать что-то вроде этого

[[self tableView] setContentInset: UIEdgeInsetsMake(0, 0, self.bottomLayoutGuide.length, 0)]; 

topLayoutGuide и bottomLayoutGuide является частью автоматического макета, и length доступен и для обоих, и для отличной функции.

0

Если бы подобную проблему и решить ее путем удаления кода в viewWillLayoutSubviews, который устанавливающих contentInset в TableVC так:

UIEdgeInsets insets = UIEdgeInsetsMake([self.topLayoutGuide length], 0, 0, 0); 
[myTableViewController.view setContentInset:insets]; 

Thing Я не понимаю, почему установка будет врезки на всех, особенно когда не устанавливаете нижнюю, как показано выше, не делаете разницы? Поэтому, не устанавливая их вообще, предположительно оставляя вставки, установленные по умолчанию UIEdgeInsetsZero, это как-то исправляет эту проблему. Возможно, это может быть ошибка iOS. Я замечаю, что я получаю эту проблему только с 32-разрядными устройствами.

Смежные вопросы