답변:
가장 좋은 방법은 화면 하단에있는 지점을 테스트하고 사용자가 스크롤 할 때마다이 메서드 호출을 사용하는 것입니다 ( scrollViewDidScroll
).
- (NSIndexPath *)indexPathForRowAtPoint:(CGPoint)point
화면 하단 근처의 지점을 테스트 한 다음 반환되는 indexPath를 사용하여 해당 indexPath가 마지막 행인지 확인한 다음 해당하는 경우 행을 추가합니다.
tableview 대리자에서 다음과 같이하십시오.
ObjC :
- (void)scrollViewDidScroll:(UIScrollView *)aScrollView {
CGPoint offset = aScrollView.contentOffset;
CGRect bounds = aScrollView.bounds;
CGSize size = aScrollView.contentSize;
UIEdgeInsets inset = aScrollView.contentInset;
float y = offset.y + bounds.size.height - inset.bottom;
float h = size.height;
// NSLog(@"offset: %f", offset.y);
// NSLog(@"content.height: %f", size.height);
// NSLog(@"bounds.height: %f", bounds.size.height);
// NSLog(@"inset.top: %f", inset.top);
// NSLog(@"inset.bottom: %f", inset.bottom);
// NSLog(@"pos: %f of %f", y, h);
float reload_distance = 10;
if(y > h + reload_distance) {
NSLog(@"load more rows");
}
}
빠른:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let offset = scrollView.contentOffset
let bounds = scrollView.bounds
let size = scrollView.contentSize
let inset = scrollView.contentInset
let y = offset.y + bounds.size.height - inset.bottom
let h = size.height
let reload_distance:CGFloat = 10.0
if y > (h + reload_distance) {
print("load more rows")
}
}
수정 된 neoneyes가 약간 대답합니다.
이 답변 은 손가락을 뗄 때 마다 이벤트가 한 번만 트리거되기를 원하는 사용자를 대상 으로합니다 .
일부 콘텐츠 제공 업체 (웹 서비스, 핵심 데이터 등)에서 더 많은 콘텐츠를로드 할 때 적합합니다. 이 접근 방식은 웹 서비스의 응답 시간을 고려하지 않습니다.
- (void)scrollViewDidEndDragging:(UIScrollView *)aScrollView
willDecelerate:(BOOL)decelerate
{
CGPoint offset = aScrollView.contentOffset;
CGRect bounds = aScrollView.bounds;
CGSize size = aScrollView.contentSize;
UIEdgeInsets inset = aScrollView.contentInset;
float y = offset.y + bounds.size.height - inset.bottom;
float h = size.height;
float reload_distance = 50;
if(y > h + reload_distance) {
NSLog(@"load more rows");
}
}
이 메서드를에 추가하십시오 UITableViewDelegate
.
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat height = scrollView.frame.size.height;
CGFloat contentYoffset = scrollView.contentOffset.y;
CGFloat distanceFromBottom = scrollView.contentSize.height - contentYoffset;
if(distanceFromBottom < height)
{
NSLog(@"end of the table");
}
}
위의 답변 중 어느 것도 도움이되지 않았으므로 이것을 생각해 냈습니다.
- (void)scrollViewDidEndDecelerating:(UIScrollView *)aScrollView
{
NSArray *visibleRows = [self.tableView visibleCells];
UITableViewCell *lastVisibleCell = [visibleRows lastObject];
NSIndexPath *path = [self.tableView indexPathForCell:lastVisibleCell];
if(path.section == lastSection && path.row == lastRow)
{
// Do something here
}
}
사용 – tableView:willDisplayCell:forRowAtIndexPath:
( UITableViewDelegate
방법)
indexPath
데이터 배열의 항목 (또는 테이블보기에 사용하는 데이터 소스)과 간단히 비교하여 마지막 요소가 표시되는지 확인하십시오.
UITableView
(A)의 서브 클래스 UIScrollView
, 및 UITableViewDelegate
을 준수합니다 UIScrollViewDelegate
. 따라서 테이블 뷰에 연결하는 델리게이트는와 같은 이벤트를 가져 scrollViewDidScroll:
오고 contentOffset
테이블 뷰 와 같은 메서드를 호출 하여 스크롤 위치를 찾을 수 있습니다.
NSLog(@"%f / %f",tableView.contentOffset.y, tableView.contentSize.height - tableView.frame.size.height);
if (tableView.contentOffset.y == tableView.contentSize.height - tableView.frame.size.height)
[self doSomething];
멋지고 간단
에서 Swift
이 같은 작업을 수행 할 수 있습니다. tableview 끝에 도달 할 때마다 다음 조건이 참입니다.
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if indexPath.row+1 == postArray.count {
println("came to last row")
}
}
println("came to last row")
코드가 실행됩니다!
@Jay Mayu의 답변을 바탕으로 작성하면 더 나은 솔루션 중 하나라고 느꼈습니다.
목표 -C
// UITableViewDelegate
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
// Need to call the service & update the array
if(indexPath.row + 1 == self.sourceArray.count) {
DLog(@"Displayed the last row!");
}
}
스위프트 2.x
// UITableViewDelegate
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if (indexPath.row + 1) == sourceArray.count {
print("Displayed the last row!")
}
}
나는 일반적으로 마지막 셀이 표시를 시작할 때 더 많은 데이터를로드하는 데 사용합니다.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == myDataArray.count-1) {
NSLog(@"load more");
}
}
촬영 neoneye 우수 답변 있지만, 신속, 그리고 변수의 이름을 변경 ..
기본적으로 yOffsetAtBottom
테이블 내용 높이를 초과 하면 테이블 뷰의 맨 아래에 도달 한 것 입니다.
func isTableViewScrolledToBottom() -> Bool {
let tableHeight = tableView.bounds.size.height
let contentHeight = tableView.contentSize.height
let insetHeight = tableView.contentInset.bottom
let yOffset = tableView.contentOffset.y
let yOffsetAtBottom = yOffset + tableHeight - insetHeight
return yOffsetAtBottom > contentHeight
}
다음은 신속한 3.0 버전 코드입니다.
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let offset = scrollView.contentOffset
let bounds = scrollView.bounds
let size = scrollView.contentSize
let inset = scrollView.contentInset
let y: Float = Float(offset.y) + Float(bounds.size.height) + Float(inset.bottom)
let height: Float = Float(size.height)
let distance: Float = 10
if y > height + distance {
// load more data
}
}
내 해결책은 tableview가 예상 오프셋에서 감속하기 전에 셀을 추가하는 것입니다. 속도로 예측할 수 있습니다.
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)offset {
NSLog(@"offset: %f", offset->y+scrollView.frame.size.height);
NSLog(@"Scroll view content size: %f", scrollView.contentSize.height);
if (offset->y+scrollView.frame.size.height > scrollView.contentSize.height - 300) {
NSLog(@"Load new rows when reaches 300px before end of content");
[[DataManager shared] fetchRecordsNextPage];
}
}
Swift 3 업데이트
Neoneye의 답변은 Objective C에서 가장 잘 작동했으며 Swift 3의 답변과 동일합니다.
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
let offset: CGPoint = scrollView.contentOffset
let bounds: CGRect = scrollView.bounds
let size: CGSize = scrollView.contentSize
let inset: UIEdgeInsets = scrollView.contentInset
let y: CGFloat = offset.y + bounds.size.height - inset.bottom
let h: CGFloat = size.height
// print("offset: %f", offset.y)
// print("content.height: %f", size.height)
// print("bounds.height: %f", bounds.size.height)
// print("inset.top: %f", inset.top)
// print("inset.bottom: %f", inset.bottom)
// print("position: %f of %f", y, h)
let reloadDistance: CGFloat = 10
if (y > h + reloadDistance) {
print("load more rows")
}
}
1 개의 전체 Tableviewcell에서 몇 가지 작업을 수행하고 싶습니다.
따라서 코드는 다음과 같습니다.
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
NSArray* cells = self.tableView.visibleCells;
NSIndexPath *indexPath = nil ;
for (int aIntCount = 0; aIntCount < [cells count]; aIntCount++)
{
UITableViewCell *cell = [cells objectAtIndex:aIntCount];
CGRect cellRect = [self.tableView convertRect:cell.frame toView:self.tableView.superview];
if (CGRectContainsRect(self.tableView.frame, cellRect))
{
indexPath = [self.tableView indexPathForCell:cell];
// remain logic
}
}
}
이것이 누군가에게 도움이되기를 바랍니다.
@neoneye의 답변이 저에게 효과적이었습니다. 여기 Swift 4 버전이 있습니다.
let offset = scrollView.contentOffset
let bounds = scrollView.bounds
let size = scrollView.contentSize
let insets = scrollView.contentInset
let y = offset.y + bounds.size.height - insets.bottom
let h = size.height
let reloadDistance = CGFloat(10)
if y > h + reloadDistance {
//load more rows
}