ฉันจะเลื่อน UIScrollView ไปด้านบนได้อย่างไร
ฉันจะเลื่อน UIScrollView ไปด้านบนได้อย่างไร
คำตอบ:
[self.scrollView setContentOffset:
CGPointMake(0, -self.scrollView.contentInset.top) animated:YES];
[self.scrollView setContentOffset:CGPointZero animated:YES];
หรือถ้าคุณต้องการที่จะรักษาตำแหน่งเลื่อนแนวนอนและเพียงแค่รีเซ็ตตำแหน่งแนวตั้ง:
[self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, 0)
animated:YES];
[scrollView setContentOffset:CGPointMake(0, -scrollView.contentInset.top) animated:YES];
ใช้งานได้ใน iOS 6 และ 7
[scrollView setContentOffset:CGPointMake(0, scrollView.contentSize.height-scrollView.frame.size.height) animated:YES];
นี่คือส่วนขยาย Swift ที่ทำให้ง่าย:
extension UIScrollView {
func scrollToTop() {
let desiredOffset = CGPoint(x: 0, y: -contentInset.top)
setContentOffset(desiredOffset, animated: true)
}
}
การใช้งาน:
myScrollView.scrollToTop()
adjustedContentInset
พยายามที่จะทำงานกับใหม่
ตัวอย่างเช่น (เลื่อนไปด้านบน):
var offset = CGPoint(
x: -scrollView.contentInset.left,
y: -scrollView.contentInset.top)
if #available(iOS 11.0, *) {
offset = CGPoint(
x: -scrollView.adjustedContentInset.left,
y: -scrollView.adjustedContentInset.top)
}
scrollView.setContentOffset(offset, animated: true)
แม้ว่าคุณจะใช้
prefersLargeTitles
,safe area
ฯลฯ
สำหรับ Swift 4
scrollView.setContentOffset(.zero, animated: true)
ใช้ setContentOffset:animated:
[scrollView setContentOffset:CGPointZero animated:YES];
คำตอบสำหรับ Swift 2.0 / 3.0 / 4.0 และ iOS 7+:
let desiredOffset = CGPoint(x: 0, y: -self.scrollView.contentInset.top)
self.scrollView.setContentOffset(desiredOffset, animated: true)
ใน iOS7 ฉันมีปัญหาในการรับ scrollview ที่เฉพาะเจาะจงเพื่อไปด้านบนซึ่งทำงานใน iOS6 และใช้สิ่งนี้เพื่อตั้งค่า scrollview ให้ไปที่ด้านบน
[self.myScroller scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO];
คำตอบของrob mayoffรุ่น Swift 3.0.1 :
self.scrollView.setContentOffset(
CGPoint(x: 0,y: -self.scrollView.contentInset.top),
animated: true)
ในการทำซ้ำแถบสถานะ scrollToTop อย่างสมบูรณ์เราไม่เพียง แต่ต้องตั้งค่า contentOffset แต่ยังต้องการให้แน่ใจว่า scrollIndicators นั้นแสดงขึ้น มิฉะนั้นผู้ใช้สามารถหลงทางได้อย่างรวดเร็ว
flashScrollIndicators
วิธีเดียวของประชาชนที่จะบรรลุนี้คือ น่าเสียดายที่การเรียกมันครั้งเดียวหลังจากตั้ง contentOffset จะไม่มีผลเพราะมันถูกรีเซ็ตทันที scrollViewDidScroll:
ผมพบว่ามันทำงานเมื่อทำแฟลชในแต่ละครั้ง
// define arbitrary tag number in a global constants or in the .pch file
#define SCROLLVIEW_IS_SCROLLING_TO_TOP_TAG 19291
- (void)scrollContentToTop {
[self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.scrollView.contentInset.top) animated:YES];
self.scrollView.tag = SCROLLVIEW_IS_SCROLLING_TO_TOP_TAG;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.scrollView.tag = 0;
});
}
ใน UIScrollViewDelegate ของคุณ (หรือ UITable / UICollectionViewDelegate) ใช้สิ่งนี้:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView.tag == SCROLLVIEW_IS_SCROLLING_TO_TOP_TAG) {
[scrollView flashScrollIndicators];
}
}
ความล่าช้าในการซ่อนนั้นสั้นกว่าเล็กน้อยเมื่อเปรียบเทียบกับแถบสถานะ scrollToTop แต่มันก็ยังดูดีอยู่
โปรดทราบว่าฉันใช้แท็กมุมมองเพื่อสื่อสารสถานะ "isScrollingToTop" ในทางที่ผิดเพราะฉันต้องการสิ่งนี้ในส่วนควบคุมมุมมอง หากคุณกำลังใช้แท็กสำหรับอย่างอื่นคุณอาจต้องการแทนที่ด้วย iVar หรือคุณสมบัติ
ฉันคิดว่าฉันมีคำตอบที่ควรจะเข้ากันได้อย่างสมบูรณ์กับ iOS 11 เช่นเดียวกับรุ่นก่อนหน้า (สำหรับการเลื่อนแนวตั้ง)
สิ่งนี้คำนึงถึงการปรับปรุงใหม่ContentInsetและบัญชีสำหรับออฟเซ็ตเพิ่มเติมที่จำเป็นเมื่อprefersLargeTitlesเปิดใช้งานบนแถบนำทางซึ่งดูเหมือนจะต้องการออฟเซ็ต 52px เพิ่มเติมที่ด้านบนของสิ่งที่เป็นค่าเริ่มต้น
นี่เป็นเรื่องยากเล็กน้อยเพราะการเปลี่ยนแปลงที่ได้รับContContInsetขึ้นอยู่กับสถานะ titleBar (ชื่อเรื่องใหญ่ vs ชื่อเรื่องเล็ก ๆ ) ดังนั้นฉันต้องตรวจสอบและดูว่าความสูงของชื่อเรื่องบาร์คืออะไรและไม่ได้ใช้ออฟเซ็ต 52px ไม่พบวิธีอื่นในการตรวจสอบสถานะของแถบนำทางดังนั้นหากใครมีตัวเลือกที่ดีกว่าดูว่าความสูงเป็น> 44.0 ฉันอยากได้ยิน
func scrollToTop(_ scrollView: UIScrollView, animated: Bool = true) {
if #available(iOS 11.0, *) {
let expandedBar = (navigationController?.navigationBar.frame.height ?? 64.0 > 44.0)
let largeTitles = (navigationController?.navigationBar.prefersLargeTitles) ?? false
let offset: CGFloat = (largeTitles && !expandedBar) ? 52: 0
scrollView.setContentOffset(CGPoint(x: 0, y: -(scrollView.adjustedContentInset.top + offset)), animated: animated)
} else {
scrollView.setContentOffset(CGPoint(x: 0, y: -scrollView.contentInset.top), animated: animated)
}
}
แรงบันดาลใจจากโซลูชันของ Jakub
เป็นเรื่องปกติมากเมื่อแถบนำทางของคุณซ้อนทับส่วนเล็ก ๆ ของเนื้อหา scrollView และดูเหมือนว่าเนื้อหาจะไม่เริ่มจากด้านบน สำหรับการแก้ไขฉันทำ 2 สิ่ง:
เลื่อนไปที่ด้านบนสำหรับUITableViewController
, UICollectionViewController
หรือUIViewController
มีUIScrollView
extension UIViewController {
func scrollToTop(animated: Bool) {
if let tv = self as? UITableViewController {
tv.tableView.setContentOffset(CGPoint.zero, animated: animated)
} else if let cv = self as? UICollectionViewController{
cv.collectionView?.setContentOffset(CGPoint.zero, animated: animated)
} else {
for v in view.subviews {
if let sv = v as? UIScrollView {
sv.setContentOffset(CGPoint.zero, animated: animated)
}
}
}
}
}
ใน SWIFT 5 เพียงตั้งค่าเนื้อหา Offset เป็นศูนย์
scrollView.setContentOffset(CGPoint.zero, animated: true)
ฉันลองทุกวิธี แต่ไม่มีอะไรทำงานให้ฉัน ในที่สุดฉันก็ทำเช่นนี้
ฉันเพิ่มself.view .addSubview(self.scroll)
บรรทัดของรหัสใน viewDidLoad หลังจากเริ่มตั้งค่าเฟรมสำหรับมุมมองเลื่อนและเพิ่มส่วนประกอบในมุมมองเลื่อน
มันใช้งานได้สำหรับฉัน
ให้แน่ใจว่าคุณเพิ่ม self.view .addSubview(self.scroll)
บรรทัดในการเริ่มต้น จากนั้นคุณสามารถเพิ่มองค์ประกอบ UI
UIScrollView
contentInset
โชคไม่ดี[self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.scrollView.contentInset.top) animated:YES];
ทำงานให้ฉันได้ไหม