Làm cách nào để tạo cuộn UIScrollView lên trên cùng?
Làm cách nào để tạo cuộn UIScrollView lên trên cùng?
Câu trả lời:
[self.scrollView setContentOffset:
CGPointMake(0, -self.scrollView.contentInset.top) animated:YES];
[self.scrollView setContentOffset:CGPointZero animated:YES];
hoặc nếu bạn muốn duy trì vị trí cuộn ngang và chỉ cần đặt lại vị trí dọc:
[self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, 0)
animated:YES];
[scrollView setContentOffset:CGPointMake(0, -scrollView.contentInset.top) animated:YES];
Nó hoạt động trong iOS 6 & 7
[scrollView setContentOffset:CGPointMake(0, scrollView.contentSize.height-scrollView.frame.size.height) animated:YES];
Đây là một tiện ích mở rộng Swift giúp dễ dàng:
extension UIScrollView {
func scrollToTop() {
let desiredOffset = CGPoint(x: 0, y: -contentInset.top)
setContentOffset(desiredOffset, animated: true)
}
}
Sử dụng:
myScrollView.scrollToTop()
cố gắng làm việc với các mới adjustedContentInset
.
Ví dụ: (cuộn lên trên cùng):
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)
Ngay cả khi bạn sử dụng
prefersLargeTitles
,safe area
vv
Dành cho Swift 4
scrollView.setContentOffset(.zero, animated: true)
Sử dụng setContentOffset:animated:
[scrollView setContentOffset:CGPointZero animated:YES];
Trong iOS7, tôi gặp khó khăn khi đưa một chế độ xem cụ thể lên đầu, hoạt động trong iOS6 và đã sử dụng tính năng này để đặt chế độ xem cuộn lên trên cùng.
[self.myScroller scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO];
Phiên bản Swift 3.0.1 của câu trả lời của rob mayoff :
self.scrollView.setContentOffset(
CGPoint(x: 0,y: -self.scrollView.contentInset.top),
animated: true)
Để sao chép hoàn toàn hành vi scrollToTop của thanh trạng thái, chúng ta không chỉ phải thiết lập nội dung Offerset mà còn muốn đảm bảo các cuộn cuộn được hiển thị. Nếu không, người dùng có thể nhanh chóng bị lạc.
Phương pháp công khai duy nhất để thực hiện điều này là flashScrollIndicators
. Thật không may, gọi nó một lần sau khi thiết lập nội dung Offerset không có hiệu lực vì nó được đặt lại ngay lập tức. Tôi tìm thấy nó hoạt động khi làm flash mỗi lần trong 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;
});
}
Trong UIScrollViewDelegate của bạn (hoặc UITable / UICollectionViewDelegate) thực hiện điều này:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView.tag == SCROLLVIEW_IS_SCROLLING_TO_TOP_TAG) {
[scrollView flashScrollIndicators];
}
}
Độ trễ ẩn ngắn hơn một chút so với hành vi scrollToTop trên thanh trạng thái nhưng trông vẫn rất đẹp.
Lưu ý rằng tôi đang lạm dụng thẻ xem để giao tiếp trạng thái "isScrollingToTop" vì tôi cần điều này trên các bộ điều khiển xem. Nếu bạn đang sử dụng thẻ cho một thứ khác, bạn có thể muốn thay thế thẻ này bằng iVar hoặc thuộc tính.
Tôi nghĩ rằng tôi có một câu trả lời phải tương thích hoàn toàn với iOS 11 cũng như các phiên bản trước (để cuộn dọc)
Điều này sẽ tính đến điều chỉnhContentInset mới và cũng tính đến phần bù bổ sung cần thiết khi preLaveTitleTitle trên navigationBar, có vẻ như yêu cầu bù thêm 52px ở trên bất kỳ giá trị mặc định nào
Điều này hơi khó khăn vì điều chỉnhContentInset thay đổi tùy thuộc vào trạng thái titleBar (tiêu đề lớn so với tiêu đề nhỏ) vì vậy tôi cần kiểm tra và xem chiều cao của titleBar là gì và không áp dụng bù 52px nếu nó đã ở trạng thái lớn. Không thể tìm thấy bất kỳ phương pháp nào khác để kiểm tra trạng thái của navigationBar vì vậy nếu có ai có tùy chọn tốt hơn là xem chiều cao có> 44.0 tôi muốn nghe không
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)
}
}
Lấy cảm hứng từ giải pháp của Jakub
Điều này rất phổ biến khi thanh điều hướng của bạn chồng lên phần nhỏ của nội dung scrollView và có vẻ như nội dung bắt đầu không phải từ đầu. Để sửa nó, tôi đã làm 2 việc:
Di chuyển đến đầu trang cho UITableViewController
, UICollectionViewController
hoặc bất kỳ UIViewController
có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)
}
}
}
}
}
Trong SWIFT 5 Chỉ cần đặt Offset nội dung về 0
scrollView.setContentOffset(CGPoint.zero, animated: true)
Tôi đã thử tất cả các cách. Nhưng không có gì làm việc cho tôi. Cuối cùng tôi đã làm như thế này.
Tôi đã thêm self.view .addSubview(self.scroll)
dòng mã trong viewDidLoad. Sau khi bắt đầu thiết lập khung cho chế độ xem cuộn và thêm các thành phần vào chế độ xem cuộn.
Nó làm việc cho tôi.
Hãy chắc chắn rằng bạn đã thêm self.view .addSubview(self.scroll)
dòng vào đầu. sau đó bạn có thể thêm các yếu tố UI.
UIScrollView
contentInset
, thật không may , bạn có thể phải tính đến điều đó.[self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.scrollView.contentInset.top) animated:YES];
thực hiện công việc cho tôi