2017-12-20 16 views
0

UITableViewCellの中にUITextViewがあります。ユーザーがUITextViewテキストを編集すると、UITextViewのサイズを変更し、UITableViewCellのサイズを変更する必要があります。また、UITableViewCellが常にキーボードの上にあることを確認する必要があります。私は次のことをやっていると、それだけで正常に動作キーボードを解雇せずにUITableViewCellのサイズを変更するにはキーボードを外すことなくスムーズにサイズ変更して移動する

[tableView beginUpdates]; 
[tableView endUpdates]; 

アップのtableViewを移動し、私は次のことをやっているキーボードの上にセルが見えるようにするにして

[tableView setContentOffset:CGPointMake(0, myDesiredScrollOffset) animated:YES]; 

私の問題は、UITableViewCellをサイズ変更してスムーズに動かすことができないということです。このような何かが動作しません。

[tableView beginUpdates]; 
[tableView endUpdates]; 
[tableView setContentOffset:CGPointMake(0, myDesiredScrollOffset) animated:YES]; 

私はそれを行う場合は、電池が正しく代わりにすべての方法ダウンサイズを変更したがのtableViewがスクロールされます。 このようにUITableViewCellのサイズを変更する方法は非同期で動作するため、setContentOffsetの呼び出しがiOSによって処理されるテーブルビューのセルのサイズ変更の途中でsetContentOffsetが処理されているためです。

私は以下を試してみましたが、テーブルビューは目的の場所にスクロールして終了します。しかし、ユーザーがのtableViewが上下に行くと見ることができますし、それは奇妙に見える:

[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搭載のデバイスで行われており、結果は同じです。

ありがとうございます。

答えて

0

私は見つけることができたそれを行う方法をアウト! 3つの非常に重要な詳細があります:

  1. キーボードを閉じずにセルのサイズを変更する方法。 (通常のリロードはキーボードを隠すでしょう)。
  2. セルの高さを設定するのは、コンテンツオフセットアニメーションが完了した後でなければなりません。 (そうでなければ、setContentOffsetは無視されます)。
  3. tableViewの下側のインセットを設定します。 (そうでなければ、セルのサイズを調整することで、テーブルの上をスクロールして、キーボードの上に表示したいセルを隠すことができます。)

このソリューションは、実際のiPhoneでiOS10とiOS11でテストされています。トリックの第2の部分はスクロールアニメーションが終了した後にのみ、セルサイズを調整するに産む

- (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]; 
}];} 

ここ

は、方法(すべてのコードは、のViewControllerに実装され)ています非常に重要:キーボードを閉じた後、テーブルビューのスクロールをスムーズに再調整します(必要な場合):

- (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;} 

ユーザーはまた、キーボードを閉じずに、別のセル内の別のセル内の1つのテキストフィールドまたはのTextViewから直接編集をジャンプして:すべてが始まりどのよう。これは考慮に入れて処理する必要があります。

のTextViewのテキストの変更が原因の場合には、そのサイズ、したがって、セルのサイズも変更する必要があるたびスクロール方式とも呼ばれるべきである。

また
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; 

私はこれがbになることを望みます使用のe。

0

お上から下へ適切にセル内の制約もheightForRowAtIndexpathその後、

データソース内の

tableView.estimatedRowHeight = 200; 

tableView.rowHeight = UITableViewAutomaticDimension; 

のviewDidLoad

を実装していないフック

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 

} 
+0

申し訳ありません...このself.tableViewBottomcon.constantは何ですか? – Mig70

+0

tableViewの下部制約はIBOutletとしてドラッグします –

+0

私のテーブルビューはプログラムによって作成されました。私はIBOutletがここでは動作しないと信じています... – Mig70

関連する問題