ฉันต้องการทราบว่าเมื่อUITableView
ใดเลื่อนไปด้านล่างเพื่อโหลดและแสดงเนื้อหาเพิ่มเติมบางอย่างเช่นผู้รับมอบสิทธิ์หรืออย่างอื่นเพื่อแจ้งให้ผู้ควบคุมทราบเมื่อตารางเลื่อนไปด้านล่าง
มีใครรู้บ้างโปรดช่วยฉันด้วยขอบคุณล่วงหน้า!
ฉันต้องการทราบว่าเมื่อUITableView
ใดเลื่อนไปด้านล่างเพื่อโหลดและแสดงเนื้อหาเพิ่มเติมบางอย่างเช่นผู้รับมอบสิทธิ์หรืออย่างอื่นเพื่อแจ้งให้ผู้ควบคุมทราบเมื่อตารางเลื่อนไปด้านล่าง
มีใครรู้บ้างโปรดช่วยฉันด้วยขอบคุณล่วงหน้า!
คำตอบ:
วิธีที่ดีที่สุดคือทดสอบจุดที่ด้านล่างของหน้าจอและใช้วิธีนี้เรียกเมื่อผู้ใช้เลื่อน ( scrollViewDidScroll
):
- (NSIndexPath *)indexPathForRowAtPoint:(CGPoint)point
ทดสอบจุดที่อยู่ใกล้ด้านล่างสุดของหน้าจอจากนั้นใช้ indexPath ซึ่งจะส่งกลับให้ตรวจสอบว่า indexPath เป็นแถวสุดท้ายหรือไม่ให้เพิ่มแถว
ใน tableview delegate ทำสิ่งนี้
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")
}
}
นีนีนีย์ดัดแปลงตอบหน่อย
คำตอบนี้มีเป้าหมายที่บรรดาผู้ที่ต้องการเพียงเหตุการณ์ที่จะถูกเรียกครั้งเดียวต่อการเปิดตัวของนิ้วมือ
เหมาะสำหรับการโหลดเนื้อหาเพิ่มเติมจากผู้ให้บริการเนื้อหาบางราย (บริการเว็บข้อมูลหลัก ฯลฯ ) โปรดทราบว่าแนวทางนี้ไม่เคารพเวลาตอบกลับจากบริการบนเว็บของคุณ
- (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
เป็น subclass ของ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")
}
}
ฉันต้องการดำเนินการบางอย่างกับ Tableviewcell 1 ตัวเต็มของฉัน
ดังนั้นรหัสจึงเชื่อมโยง:
-(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
}