我在uitaiteViewCell内部有一个uitextview。当用户编辑UITEXTVIEW文本时,我调整了UITEXTVIEW的大小,我需要调整UaithitViewCell大小,并确保UaithitviewCell始终在键盘上方。
要调整UaiteDviewCell大小,而不会删除键盘,我正在做以下操作,它可以正常工作:
[tableView beginUpdates];
[tableView endUpdates];
要向上移动表格,并在键盘上方可见单元格,我正在执行以下操作,并且效果很好:
[tableView setContentOffset:CGPointMake(0, myDesiredScrollOffset) animated:YES];
我的问题是,我都不能使UitaiteViewCell大小化并顺利进行。像这样的事情将不起作用:
[tableView beginUpdates];
[tableView endUpdates];
[tableView setContentOffset:CGPointMake(0, myDesiredScrollOffset) animated:YES];
如果我这样做,则单元格会正确调整大小,但是桌面滚动滚动一直向下滚动。我知道这种调整UitableViewCell的大小的方式不同步,这就是为什么调用setContentOffset无法正常工作的原因,可能是因为setContentOffset正在处理iOS的" setContentOffset"。
i比尝试以下操作,最终滚动到所需的位置。但是,用户可以看到表观视图上下移动,看起来很奇怪:
[tableView beginUpdates];
[tableView endUpdates];
[self performSelector:@selector(myMethodToScroll) withObject:nil afterDelay:0.01];
...
- (void) myMethodToScroll {
[self.tableView setContentOffset:CGPointMake(0, self.myDesiredScrollOffset) animated:YES];}
我非常感谢这个社区对我的问题的帮助,因为我已经在这个问题上挣扎了几天。这些测试是在带有iOS 10和iOS 11的设备上进行的,结果是相同的。
预先感谢。
我设法找出了如何做!有3个非常重要的细节:
- 在不关闭键盘的情况下调整单元格的方式。(正常的重新加载将隐藏键盘)。
- 仅在内容偏移动画完成后才设置单元高。(否则,可以忽略setContentOffset)。
- 为表视图设置底部插图。(否则,调整单元的尺寸可能会向下滚动,将我们希望在键盘上方看到的单元格隐藏。)
该解决方案已在带有真实iPhone的ios10和ios11中进行了测试。
这是如何(在ViewController中实现所有代码):
- (TableViewScrollDirection) scrollToKeepEditingCellVisibleAboveVerticalPoint:(CGFloat)verticalPoint cellIndexPath:(NSIndexPath*)cellIndexPath anchorsToVerticalPoint:(BOOL)anchorsToVerticalPoint cellHeight:(CGFloat)cellHeight adjustsCellSize:(BOOL)adjustsCellSize {
// Remark: verticalPoint is the desired offset above the tableView bottom. In my case the height of the keyboard covering the bottom of the tableView
CGRect cellFrame = CGRectOffset([self.tableView rectForRowAtIndexPath:cellIndexPath], -self.tableView.contentOffset.x, -self.tableView.contentOffset.y - self.tableView.contentInset.top);
CGFloat cellBottom = adjustsCellSize ? cellFrame.origin.y + cellHeight : cellFrame.origin.y + cellFrame.size.height;
CGFloat offsetNeeded = cellBottom - verticalPoint; // Relative offset
CGFloat brandNewOffset = self.tableView.contentOffset.y + offsetNeeded; // Absolute offset
if ((offsetNeeded > 0) || ((offsetNeeded < 0) && anchorsToVerticalPoint))
{
CGFloat elasticity = self.tableView.frame.size.height - verticalPoint;
if (self.tableView.contentInset.bottom != elasticity)
self.tableView.contentInset = UIEdgeInsetsMake(0, 0, elasticity, 0); // This will make sure the tableview does not scroll down when its content offset elasticity is not enough
if (adjustsCellSize)
[self setContentOffsetAndAdjustCellSizes:brandNewOffset];
else
[self.tableView setContentOffset:CGPointMake(0, brandNewOffset) animated:YES];
if (offsetNeeded > 0)
return TableViewScrollUp;
else if (offsetNeeded < 0)
return TableViewScrollDown;
}
return TableViewScrollNone;}
技巧的第二部分仅在滚动动画结束后调整单元格大小:
- (void) setContentOffsetAndAdjustCellSizes:(CGFloat)contentOffset{
[UIView animateWithDuration:0.5 animations:^
{
[self.tableView setContentOffset:CGPointMake(0, contentOffset) animated:NO];
}
completion:^(BOOL finished)
{
[self.tableView beginUpdates]; // Cell height must be adjusted this way, otherwise the keyboard closes.
[self.tableView endUpdates];
}];}
非常重要:关闭键盘后,平稳调整桌面滚动(如有必要):
- (void) keyboardDidHide:(NSNotification *)notification {
if (self.tableView.contentInset.bottom != 0)
[UIView animateWithDuration:0.5 animations:^ {self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);}];
self.activeKeyboardSize = CGSizeZero; }
一切都开始:
- (void) keyboardDidShow:(NSNotification*)notification {
NSDictionary* info = [notification userInfo];
self.activeKeyboardSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
CGFloat tableViewBottom = self.tableView.frame.origin.y + self.tableView.frame.size.height;
CGFloat keyboardTop = self.view.frame.size.height - self.activeKeyboardSize.height;
CGFloat coveringVerticalSpace = tableViewBottom - keyboardTop;
if (coveringVerticalSpace <= 0)
return;
TableViewScrollDirection scrollDirection = [self scrollToKeepEditingCellVisibleAboveVerticalPoint:self.tableView.frame.size.height - coveringVerticalSpace - UI_MARGIN_DEFAULT anchorsToVerticalPoint:NO];
if (scrollDirection == TableViewScrollUp)
self.textControlCellHadToMoveUpToBeVisibleOverKeyboard = YES;}
用户还可以直接从一个文本字段或一个单元格中的文本视图直接跳到另一个单元格中的文本视图,而无需关闭键盘。这必须考虑到并处理。
每当文本文本更改时,也应调用滚动方法,以防万一,因此单元格的大小也需要更改:
CGFloat tableViewBottom = self.tableView.frame.origin.y + self.tableView.frame.size.height;
CGFloat keyboardTop = self.view.frame.size.height - self.activeKeyboardSize.height;
CGFloat coveringVerticalSpace = tableViewBottom - keyboardTop;
if (coveringVerticalSpace <= 0)
return;
[self scrollToKeepEditingCellVisibleAboveVerticalPoint:self.tableView.frame.size.height - coveringVerticalSpace - UI_MARGIN_DEFAULT anchorsToVerticalPoint:self.textControlCellHadToMoveUpToBeVisibleOverKeyboard cellHeight:staticCellView.frame.size.height adjustsCellSize:adjustsCellSize]; // UI_MARGIN_DEFAULT is 8.0 and it gives a little margin of 8 points over the keyboard.
也有用:
typedef NS_ENUM(NSUInteger, TableViewScrollDirection){
TableViewScrollNone,
TableViewScrollDown,
TableViewScrollUp };
在ViewController中创建的有用属性:
@property (nonatomic) BOOL textControlCellHadToMoveUpToBeVisibleOverKeyboard;
我希望这将被使用。
挂钩您在从上到下正确约束在单元格中也不实现 height foraratIndExpath
然后
在ViewDidload中
tableView.estimatedRowHeight = 200;
tableView.rowHeight = UITableViewAutomaticDimension;
在数据源
中 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier:CellIdentifier1) as! logTableViewCell
// your code here
cell.layoutSubviews()
cell.layoutIfNeeded()
return cell
}