我正在尝试创建 Any.DO 应用程序的副本。这tableHeaderView
是一个“NewTaskCell”视图,其中包含一个带有UITextField
. 出于某种原因,在键盘出现后,tableView 无法一直滚动到底部。这是我尝试过的:
- 更改 tableView 的框架
- 更改 tableView 的边界
- 更改 tableView 的 contentSize
- 键盘关闭后更新页脚视图
它必须与键盘或文本字段有关,因为它仅在键盘出现时才会发生。
在下面的动画中,您可以看到如果我单击加号按钮并显示键盘,则 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];
}];
}
这就是问题的样子: