Üste kaydırmak için UIScrollView alın


Yanıtlar:


316

İOS 7 İÇİN GÜNCELLEME

[self.scrollView setContentOffset:
    CGPointMake(0, -self.scrollView.contentInset.top) animated:YES];

ORİJİNAL

[self.scrollView setContentOffset:CGPointZero animated:YES];

veya yatay kaydırma konumunu korumak ve sadece dikey konumu sıfırlamak istiyorsanız:

[self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, 0)
    animated:YES];

50
Bunu iOS 7 için yapıyorsanız UIScrollView contentInset, maalesef dikkate almanız gerekebilir . [self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.scrollView.contentInset.top) animated:YES];benim için iş yapar
runmad

11
Gezinme ve durum çubuğunun hemen altında en üste kayabildim. [scrollView setContentOffset:CGPointMake(0, -scrollView.contentInset.top) animated:YES];
İOS

Bu benim için işe yaramadı, çünkü muhtemelen sprite kitinde ters bir bakışla çılgın bir şey yapıyorum. Ama başka biri benim kadar [scrollView setContentOffset:CGPointMake(0, scrollView.contentSize.height-scrollView.frame.size.height) animated:YES];
çılgınsa

Günün Sonu Yorumu: İşletim sistemi sürümüne bakılmaksızın içerik ekini ayarlamanız gerekir. iOS 7, durum çubuğunun altında kaydırma içeriğine izin vermek için kullanıyor ancak her zaman bir özellik olarak gösterildi, bu nedenle her zaman biri tarafından potansiyel olarak kullanıldı.
Tommy

2
İOS 11+ için Jakub Truhlář'nın, adjustContentInset'i kullanmanın aşağıdaki cevabı yardımcı oldu, en azından benim durumumda.
tnev

61

İşte bunu kolaylaştıran bir Swift uzantısı:

extension UIScrollView {
    func scrollToTop() {
        let desiredOffset = CGPoint(x: 0, y: -contentInset.top)
        setContentOffset(desiredOffset, animated: true)
   }
}

Kullanımı:

myScrollView.scrollToTop()

40

iOS 11 ve üstü

yeni ile çalışmaya çalışın adjustedContentInset.

Örneğin (yukarı kaydırın):

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)

Kullanmak bile prefersLargeTitles, safe areavb



23

kullanım setContentOffset:animated:

[scrollView setContentOffset:CGPointZero animated:YES];

17

Swift 2.0 / 3.0 / 4.0 ve iOS 7+ için cevap:

let desiredOffset = CGPoint(x: 0, y: -self.scrollView.contentInset.top)
self.scrollView.setContentOffset(desiredOffset, animated: true)

8

İOS7'de, iOS6'da çalışan belirli bir kaydırma görüntüsünü almakta sorun yaşadım ve bunu kaydırma görüntüsünü en üste gidecek şekilde ayarlamak için kullandım.

[self.myScroller scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO];

İOS7'de de aynı sorun var. Herkes bunu bir UITableView için etkinleştirmeyi biliyor mu?
DZenBot

1
Animasyon HAYIR olduğunda bunun nasıl çalıştığı komik, ancak animasyon YES olduğunda değil. EVET ise, o zaman neredeyse en üste kaydırır devm16
Matt Becker


2

Durum çubuğunu scrollToTop davranışını tam olarak çoğaltmak için sadece contentOffset'i ayarlamakla kalmıyor, aynı zamanda scrollIndicators öğesinin görüntülendiğinden de emin olmak istiyoruz. Aksi takdirde kullanıcı hızlı bir şekilde kaybolabilir.

Bunu başarmanın tek yolu yöntemdir flashScrollIndicators. Ne yazık ki, contentOffset'i ayarladıktan sonra bir kez çağırmanın bir etkisi yoktur, çünkü hemen sıfırlanır. Her seferinde flaş yaparken işe yaradığını gördüm 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'inizde (veya UITable / UICollectionViewDelegate) bunu uygulayın:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (scrollView.tag == SCROLLVIEW_IS_SCROLLING_TO_TOP_TAG) {
        [scrollView flashScrollIndicators];
    }
}

Gizleme gecikmesi scrollToTop durum çubuğuna kıyasla biraz daha kısadır, ancak yine de güzel görünüyor.

Görünüm denetleyicileri arasında buna ihtiyacım var çünkü "isScrollingToTop" durumunu iletmek için görünüm etiketini kötüye kullandığımı unutmayın. Etiketleri başka bir şey için kullanıyorsanız, bunu bir iVar veya bir özellikle değiştirmek isteyebilirsiniz.


Test etmedim, ancak bunun yerine sadece DISPATCH_TIME_NOW kullanıyorsanız bir sonraki çalışma döngüsüne atmalıdır. Bu işi yaptığınız için teşekkürler, henüz ihtiyacım olmadığından emin değilim, ama bilmek güzel.
Dan Rosenstark

Bir süre önce ve tam olarak hatırlamıyorum ama bunun işe yaramadığına inanıyorum. Bir sonraki runloop'a ertelemek genellikle bu gibi durumlarda denediğim ilk şeydir.
Ortwin Gentz

2

Önceki sürümlerin yanı sıra iOS 11 ile tam uyumlu olması gereken bir cevabım olduğunu düşünüyorum (dikey kaydırma için)

Bu hesaba yeni sürer adjustedContentInset ve ayrıca hesapları ek gereklidir ofset prefersLargeTitles varsayılan ne olursa olsun üstündeki mahsup fazladan 52px gerektirdiği görülmektedir NavigationBar etkinleştirildiğinde

Bu, biraz zor oldu çünkü adjustmentContentInset titleBar durumuna (büyük başlık vs küçük başlık) bağlı olarak değişir, bu yüzden titleBar yüksekliğinin ne olduğunu kontrol etmek ve görmek için gerekli ve zaten büyük durumda ise 52px ofset uygulamak gerekir. NavigationBar'ın durumunu kontrol etmek için başka bir yöntem bulunamadı, bu nedenle eğer herhangi birinin yükseklik> 44.0 olup olmadığını görmekten daha iyi bir seçeneği varsa, bunu duymak isterim

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'un çözümünden ilham aldı


2

Gezinme çubuğunuz , scrollView içeriğinin küçük bir kısmı ile çakıştığında çok yaygındır ve içerik üstten başlamıyor gibi görünür. Düzeltmek için 2 şey yaptım:

  • Boyut Denetçisi - Kaydırma Görünümü - İçerik Ekleri -> Otomatik'ten Asla Değil'e değiştirin.
  • Boyut Müfettiş - Constraints- "Align Top" (Üst Hizalama kısıtları) - İkinci madde -> Değiştir Superview.Top Güvenli Area.Top için ve 0'a değer (sabit alanı) kümesi

İçerik ekleri - Asla ScrolView.Top'u Güvenli Alan ile hizalayın.


1

Kaydırma için top UITableViewController, UICollectionViewControllerya da herhangi UIViewControllersahipUIScrollView

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)
            }
        }
    }
  }
}

0

SWIFT 5'te Sadece Ofset içeriğini sıfıra ayarlayın

scrollView.setContentOffset(CGPoint.zero, animated: true)

-4

Bütün yolları denedim. Ama benim için hiçbir şey işe yaramadı. Sonunda beğendim.

Ben self.view .addSubview(self.scroll)viewDidLoad kod satırı ekledi . Kaydırma görünümü için çerçeve ayarlama ve kaydırma görünümü için eklenen bileşenler ayarlandıktan sonra.

Benim için çalıştı.

self.view .addSubview(self.scroll)Başlangıçta satır eklediğinizden emin olun . kullanıcı arayüzü öğeleri ekleyebilirsiniz.


Lütfen bunu silin. O zaman kesinlikle mantıklı olsa da, alt görünüm hiyerarşi sorunlarınız bu soru ile ilgili değildir.
Dan Rosenstark

1
@Cristik, kaydırma görünümünüz görünüm hiyerarşisinde değilse veya bilgisayarınız kapalıysa, elbette bunların hiçbiri çalışmaz. Ama OP oldukça dar bir şey sordu
Dan Rosenstark
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.