본문 바로가기

프로그래밍/iOS,macOS

UITableView , UITextView 동적 크기 변화 및 스크롤

UITextView 를 가진 테이블뷰 셀에서 동적으로 높이가 변경할때 스크롤 관련 문제가 생긴다.

특히 auto-layout 환경은 증상이 좀 심각..textview에서 리턴을 연타하다보면 아래위로 튀는 스크롤~


2줄로 구성된 셀인데, 위는 UILabel로 가변, 아래는 UITextView로 가변.

셀을 생성하고, 각 라인별 뷰를 추가해준다. 패딩 및 추가 처리가 필요한 경우 뷰를 추가해줌.


Cell

  -Content View

     -루트뷰

        -컨텐트뷰

           -상단뷰

           -하단뷰


Content View 는 기본뷰이므로, 사이즈 좌우 확대 걸어주고, 루트뷰는 super뷰에 맞춰준다.

이때 Bottom은 가변이므로, 제약을 999정도로 낮춤.

컨텐트뷰도 super뷰에 맞게 제약을 걸어준다.

컨텐트뷰의 하위제약으로 컨텐트뷰의 서브인 하단뷰의 bottom과 맞춤.

하단뷰안의 uitextview는 하단뷰에 맞춤.


이러면 UITextView가 늘어날때, 하단뷰 bottom 증가->컨텐트뷰 bottom증가 -> 루트뷰 bottom증가 -> 셀의 Content View증가 형태로 크기가 결정된다. 셀의 크기가 정해져 있기에 충돌이 발생할 수 있는데, 초기에 Content View의 bottom 제약이 낮으므로, 증가하는게 우선~


암튼 요렇게 제약 구성하면 당연 그냥늘어나진 않는다.

테이블뷰이므로 아래 코드가 필요~



-(void) textViewDidChange:(UITextView*)textView

{

[self.tableView beginUpdates];

[self.tableView endUpdates];

}


이제 동적으로 늘어나긴 하는데, 스크롤이 춤을 춘다. 그리고, text view의 커서가 화면 아래로 숨어 버린다.

현재 커서 영역이 보여지는 영역을 벗어 났는지 검사해서 해당 크기만큼 스크롤 영역을 조절한다.

여전히 튀는 증상이 보이는데, UITableView는 키보드 여부에 따라서, 스크롤을 조정하기에 생기는 문제인듯 보인다.

이경우 애니메이션을 끄면 튀는 증상은 없어진다.


-(void) textViewDidChange:(UITextView*)textView

{

[UIView setAnimationsEnabled:NO];

[self.tableView beginUpdates];

[self.tableView endUpdates];


CGRect cursorRect = [self.textView caretRectForPosition:self.textView.selectedTextRange.start];

cursorRect = [self.tableView convertRect:cursorRect fromView:self.textView];


CGRect visibleRect;

visibleRect.origin = self.tableView.contentOffset;

visibleRect.origin.y += self.tableView.contentInset.top;

visibleRect.size = self.tableView.bounds.size;

visibleRect.size.height = -= self.tableView.contentInset.top + self.tableView.contentInset.bottom;


if( !CGRectContainsRect( visibleRect, cursorRect ) )

{

cursorRect.size.height += 8;

[self.tableView scrollRectToVisible:cursorRect animated:NO];

}


[UIView setAnimationsEnabled:YES];

}


쩝.. 이리저리 스크롤과 셀간을 옮겨가며 리턴질을 하다보면 약간 매끄럽지 못한 부분도 보이는데...

아쉽다~