UIScrollView kaydırma programlı olarak alta


299

UIScrollViewKodumun alt kısmına nasıl kaydırma yapabilirim ? Veya daha genel bir şekilde, bir alt görünümün herhangi bir noktasına?

Yanıtlar:


627

setContentOffset:animated:İçerik görünümünün herhangi bir bölümüne gitmek için UIScrollView işlevini kullanabilirsiniz. ScrollView öğenizin self.scrollView:

CGPoint bottomOffset = CGPointMake(0, self.scrollView.contentSize.height - self.scrollView.bounds.size.height + self.scrollView.contentInset.bottom);
[self.scrollView setContentOffset:bottomOffset animated:YES];

Umarım yardımcı olur!


25
kaydırma görünümü yerine aşağı doğru kaydırmak için aşağıdakileri yapmak isteyebilirsiniz: CGPoint bottomOffset = CGPointMake (0, [self.scrollView contentSize] .height - self.scrollView.frame.size.height);
Grantland

70
İç metinleri dikkate almıyorsunuz. Bence bu alt tercih etmelisinizOfset:CGPoint bottomOffset = CGPointMake(0, self.scrollView.contentSize.height - self.scrollView.bounds.size.height + self.scrollView.contentInset.bottom);
Martin

1
bu Manzara modunda çalışmaz! tamamen alta kaydırma
Mo Farhand

1
Bu takdirde düzgün çalışmaz wil contentSizedaha düşüktür bounds. Yani şöyle olmalı:scrollView.setContentOffset(CGPointMake(0, max(scrollView.contentSize.height - scrollView.bounds.size.height, 0) ), animated: true)
Bartłomiej Semańczyk

1
Bu, alt iç kısmı ele alır ve let bottomOffsetY = max(collectionView.contentSize.height - collectionView.bounds.height + collectionView.contentInset.bottom, 0)
0'ın

137

Kolay kopya yapıştırma için kabul edilen yanıtın hızlı sürümü:

let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.size.height)
scrollView.setContentOffset(bottomOffset, animated: true)

3
bottomOffset izin vermeli ve örneğinizde değişmemelidir.
15'te Tige Hobbes

doğru, değişti. swift2 stuff :)
Esqarrouth

9
scrollView.contentSize.height - scrollView.bounds.size.height> 0 olup olmadığını kontrol etmeniz gerekir - aksi takdirde garip sonuçlar elde edersiniz
iluvatar_GR

2
Yeni gezinme çubuğunuz olduğunda bu çözüm mükemmel değildir.
Swift Tavşan

@Josh, SO gününü hala bekliyor
Alexandre G

53

En Basit Çözüm:

[scrollview scrollRectToVisible:CGRectMake(scrollview.contentSize.width - 1,scrollview.contentSize.height - 1, 1, 1) animated:YES];

Teşekkürler. Kaydırma görünümümü bir UITableView olarak değiştirdim ve bu kod da bir UITableView, FYI için çalıştı.
LevinsonTechnologies

1
Neden sadece: [scrollview scrollRectToVisible: CGRectMake (0, scrollview.contentSize.height, 1, 1) animated: YES];
Johannes

29

Sadece mevcut cevapta bir gelişme.

CGPoint bottomOffset = CGPointMake(0, self.scrollView.contentSize.height - self.scrollView.bounds.size.height + self.scrollView.contentInset.bottom);
[self.scrollView setContentOffset:bottomOffset animated:YES];

Alt iç metinle de ilgilenir (klavye görünürken kaydırma görünümünüzü ayarlamak için kullanıyorsanız)


Bu doğru cevap olmalı ... klavyesi açılırsa kırılacak olanlar değil.
Ben Guild

20

Hızlı bir uygulama:

extension UIScrollView {
   func scrollToBottom(animated: Bool) {
     if self.contentSize.height < self.bounds.size.height { return }
     let bottomOffset = CGPoint(x: 0, y: self.contentSize.height - self.bounds.size.height)
     self.setContentOffset(bottomOffset, animated: animated)
  }
}

kullanın:

yourScrollview.scrollToBottom(animated: true)

19

İçerik ofsetini içerik boyutunun yüksekliğine ayarlamak yanlıştır: içeriğin altını kaydırma görünümünün üstüne kaydırır ve böylece gözden kaçar.

Doğru çözüm, içeriğin alt kısmını aşağıdaki gibi kaydırma görünümünün altına kaydırmaktır ( svUIScrollView):

CGSize csz = sv.contentSize;
CGSize bsz = sv.bounds.size;
if (sv.contentOffset.y + bsz.height > csz.height) {
    [sv setContentOffset:CGPointMake(sv.contentOffset.x, 
                                     csz.height - bsz.height) 
                animated:YES];
}

1
Olmamalı mı if (sv.contentOffset.y + csz.height > bsz.height) {?
i_am_jorf

@jeffamaphone - Sorduğunuz için teşekkürler. Aslında bu noktada durumun hangi amaca hizmet etmesi gerektiğinden bile emin değilim! setContentOffset:Önemli olan emirdir.
matt

Ben onun bir şey yapmayacaksa setContentOffset çağrısını önlemek için varsayalım?
i_am_jorf

@jeffamaphone - Eskiden cihaz döndürüldükten sonra bir kaydırma görünümünün içeriği alt çerçevenin altından daha yüksek olacak şekilde sona erebilirdi (çünkü bir kaydırma görünümünü döndürürsek, içerik ofseti sabit kalır, ancak kaydırma görünümü yüksekliği nedeniyle büyümüş olabilir otomatikleştirmeye). Durum şöyle diyor: Bu olursa, içeriği alttan çerçevenin altına geri koyun. Ama koda yapıştırdığımda durumu dahil etmek aptalcaydı. Durum , test ettiği şey için doğru bir şekilde test ediyor.
matt

15

contentInsetDikkate alan Swift 2.2 çözümü

let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.size.height + scrollView.contentInset.bottom)
scrollView.setContentOffset(bottomOffset, animated: true)

Bu bir uzantıda olmalıdır

extension UIScrollView {

  func scrollToBottom() {
    let bottomOffset = CGPoint(x: 0, y: contentSize.height - bounds.size.height + contentInset.bottom)
    setContentOffset(bottomOffset, animated: true)
  }
}

bottomOffset.y > 0Kaydırma işleminden önce kontrol etmek isteyebileceğinizi unutmayın


14

Ya contentSizedaha düşükse bounds?

Swift için:

scrollView.setContentOffset(CGPointMake(0, max(scrollView.contentSize.height - scrollView.bounds.size.height, 0) ), animated: true)

13

Başa Dön

- CGPoint topOffset = CGPointMake(0, 0);
- [scrollView setContentOffset:topOffset animated:YES];

En Alta Kaydır

- CGPoint bottomOffset = CGPointMake(0, scrollView.contentSize.height - self.scrollView.bounds.size.height);
 - [scrollView setContentOffset:bottomOffset animated:YES];

7

Ayrıca bir UITableview (UIScrollView bir alt sınıf olan) kullanıyorsanız durumunda bunu yapmak için başka bir yararlı yol buldum:

[(UITableView *)self.view scrollToRowAtIndexPath:scrollIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];

FYI, bu sadece bir UITableView özelliği
31'de OhadM

7

setContentOffset:animated:Swift'te en alta kaydırmak için UIScrollView işlevini kullanma .

let bottomOffset : CGPoint = CGPointMake(0, scrollView.contentSize.height - scrollView.bounds.size.height + scrollView.contentInset.bottom)
scrollView.setContentOffset(bottomOffset, animated: true)

5

Buradaki tüm cevapların güvenli alanı dikkate almadığı anlaşılıyor. İOS 11'den bu yana, iPhone X güvenli bir alana sahipti. Bu scrollView'leri etkileyebilir contentInset.

İOS 11 ve üstü için, içerik eki eklenmiş olarak en alta kaydırmak için. Bunun adjustedContentInsetyerine kullanmalısınız contentInset. Bu kodu kontrol edin:

  • Swift:
let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.height + scrollView.adjustedContentInset.bottom)
scrollView.setContentOffset(bottomOffset, animated: true)
  • Objective-C
CGPoint bottomOffset = CGPointMake(0, self.scrollView.contentSize.height - self.scrollView.bounds.size.height + self.scrollView.adjustedContentInset.bottom);
[self.scrollView setContentOffset:bottomOffset animated:YES];
  • Swift uzantısı (orijinali tutar contentOffset.x):
extension UIScrollView {
    func scrollsToBottom(animated: Bool) {
        let bottomOffset = CGPoint(x: contentOffset.x,
                                   y: contentSize.height - bounds.height + adjustedContentInset.bottom)
        setContentOffset(bottomOffset, animated: animated)
    }
}

Referanslar:


5

Bir (isteğe bağlı) footerViewve contentInsetile çözüm:

CGPoint bottomOffset = CGPointMake(0, _tableView.contentSize.height - tableView.frame.size.height + _tableView.contentInset.bottom);
if (bottomOffset.y > 0) [_tableView setContentOffset: bottomOffset animated: YES];

4

Swift:

Bunun gibi bir uzantı kullanabilirsiniz:

extension UIScrollView {
    func scrollsToBottom(animated: Bool) {
        let bottomOffset = CGPoint(x: 0, y: contentSize.height - bounds.size.height)
        setContentOffset(bottomOffset, animated: animated)
    }
}

kullanın:

scrollView.scrollsToBottom(animated: true)

3

Valdyr, umarım bu sana yardımcı olur:

CGPoint bottomOffset = CGPointMake(0, [textView contentSize].height - textView.frame.size.height);

if (bottomOffset.y > 0)
 [textView setContentOffset: bottomOffset animated: YES];

2

Kurtarma için kategori!

Bunu paylaşılan bir yardımcı program başlığına bir yere ekleyin:

@interface UIScrollView (ScrollToBottom)
- (void)scrollToBottomAnimated:(BOOL)animated;
@end

Ve sonra bu yardımcı uygulamaya:

@implementation UIScrollView(ScrollToBottom)
- (void)scrollToBottomAnimated:(BOOL)animated
{
     CGPoint bottomOffset = CGPointMake(0, self.contentSize.height - self.bounds.size.height);
     [self setContentOffset:bottomOffset animated:animated];
}
@end

Ardından, istediğiniz yere uygulayın, örneğin:

[[myWebView scrollView] scrollToBottomAnimated:YES];

Her zaman, her zaman, her zaman, her zaman kategorileri kullanın! Mükemmel :)
Fattie

2

Yatay Kaydırma Görünümü için

Benim gibi bir Yatay ScrollView varsa ve sonuna (benim durumumda en sağında) kaydırmak istiyorsanız, kabul edilen cevabın bazı bölümlerini değiştirmeniz gerekir:

Objective-C

CGPoint rightOffset = CGPointMake(self.scrollView.contentSize.width - self.scrollView.bounds.size.width + self.scrollView.contentInset.right, 0 );
[self.scrollView setContentOffset:rightOffset animated:YES];

hızlı

let rightOffset: CGPoint = CGPoint(x: self.scrollView.contentSize.width - self.scrollView.bounds.size.width + self.scrollView.contentInset.right, y: 0)
self.scrollView.setContentOffset(rightOffset, animated: true)

2

ScrollView contentSize öğesini bir şekilde değiştirirseniz (ör. ScrollView içindeki stackView öğesine bir şey ekleyin)scrollView.layoutIfNeeded() kaydırma yapmadan önce , aksi takdirde hiçbir şey yapmaz.

Misal:

scrollView.layoutIfNeeded()
let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.size.height + scrollView.contentInset.bottom)
if(bottomOffset.y > 0) {
    scrollView.setContentOffset(bottomOffset, animated: true)
}

1

İçeriğinizin alt kısmının görünür olmasını sağlamanın iyi bir yolu formülü kullanmaktır:

contentOffsetY = MIN(0, contentHeight - boundsHeight)

Bu, içeriğinizin alt kenarının her zaman görünümün alt kenarında veya üstünde olmasını sağlar. MIN(0, ...)Çünkü gereklidir UITableView(ve muhtemelen UIScrollView) sağlayan contentOffsetY >= 0kullanıcı çalışır gözle görülür yakalamaya tarafından kaydırmak için zaman contentOffsetY = 0. Bu kullanıcı için oldukça garip görünüyor.

Bunu uygulamak için kod:

UIScrollView scrollView = ...;
CGSize contentSize = scrollView.contentSize;
CGSize boundsSize = scrollView.bounds.size;
if (contentSize.height > boundsSize.height)
{
    CGPoint contentOffset = scrollView.contentOffset;
    contentOffset.y = contentSize.height - boundsSize.height;
    [scrollView setContentOffset:contentOffset animated:YES];
}

1

Animasyona ihtiyacınız yoksa, bu işe yarar:

[self.scrollView setContentOffset:CGPointMake(0, CGFLOAT_MAX) animated:NO];

1

İken Mattçözümü kurulum olmuştur varsa hesapta da toplama görünümü iç metnini almak gerekir bana doğru görünüyor.

Uyarlanmış kod:

CGSize csz = sv.contentSize;
CGSize bsz = sv.bounds.size;
NSInteger bottomInset = sv.contentInset.bottom;
if (sv.contentOffset.y + bsz.height + bottomInset > csz.height) {
    [sv setContentOffset:CGPointMake(sv.contentOffset.x, 
                                     csz.height - bsz.height + bottomInset) 
                animated:YES];
}

1

Hızlı:

   if self.mainScroll.contentSize.height > self.mainScroll.bounds.size.height {
        let bottomOffset = CGPointMake(0, self.mainScroll.contentSize.height - self.mainScroll.bounds.size.height);
        self.mainScroll.setContentOffset(bottomOffset, animated: true)
    }

1

Bir tablonun son öğesine kaydırma çözümü Görünüm:

Hızlı 3:

if self.items.count > 0 {
        self.tableView.scrollToRow(at:  IndexPath.init(row: self.items.count - 1, section: 0), at: UITableViewScrollPosition.bottom, animated: true)
}

0

Ben bunu kullanmaya çalıştım, benim için çalışmıyor muydu UITableViewControllerüzerine self.tableView (iOS 4.1)ekledikten sonra,footerView . Siyah ekranı gösteren kenarlıkların dışına kayar.

Alternatif çözüm:

 CGFloat height = self.tableView.contentSize.height; 

 [self.tableView setTableFooterView: myFooterView];
 [self.tableView reloadData];

 CGFloat delta = self.tableView.contentSize.height - height;
 CGPoint offset = [self.tableView contentOffset];
 offset.y += delta;

 [self.tableView setContentOffset: offset animated: YES];

0
CGFloat yOffset = scrollView.contentOffset.y;

CGFloat height = scrollView.frame.size.height;

CGFloat contentHeight = scrollView.contentSize.height;

CGFloat distance = (contentHeight  - height) - yOffset;

if(distance < 0)
{
    return ;
}

CGPoint offset = scrollView.contentOffset;

offset.y += distance;

[scrollView setContentOffset:offset animated:YES];

0

Bunun contentSizemetnin gerçek boyutunu gerçekten yansıtmadığını fark ettim , bu yüzden aşağı kaydırmaya çalışırken biraz kapalı olacak. Gerçek içerik boyutunu belirlemenin en iyi yolu aslında NSLayoutManager' usedRectForTextContainer:yöntemini kullanmaktır:

UITextView *textView;
CGSize textSize = [textView.layoutManager usedRectForTextContainer:textView.textContainer].size;

Metnin gerçekte ne kadar gösterileceğini belirlemek için UITextView, metin kabı iç metinlerini çerçeve yüksekliğinden çıkararak hesaplayabilirsiniz.

UITextView *textView;
UIEdgeInsets textInsets = textView.textContainerInset;
CGFloat textViewHeight = textView.frame.size.height - textInsets.top - textInsets.bottom;

Sonra kaydırmak kolaylaşır:

// if you want scroll animation, use contentOffset
UITextView *textView;
textView.contentOffset = CGPointMake(textView.contentOffset.x, textSize - textViewHeight);

// if you don't want scroll animation
CGRect scrollBounds = textView.bounds;
scrollBounds.origin = CGPointMake(textView.contentOffset.x, textSize - textViewHeight);
textView.bounds = scrollBounds;

Bir boş için farklı boyutların neyi temsil ettiğine ilişkin referans için bazı sayılar UITextView.

textView.frame.size = (width=246, height=50)
textSize = (width=10, height=16.701999999999998)
textView.contentSize = (width=246, height=33)
textView.textContainerInset = (top=8, left=0, bottom=8, right=0)

0

ScrollToBottom yöntemi eklemek için UIScrollView öğesini genişletin:

extension UIScrollView {
    func scrollToBottom(animated:Bool) {
        let offset = self.contentSize.height - self.visibleSize.height
        if offset > self.contentOffset.y {
            self.setContentOffset(CGPoint(x: 0, y: offset), animated: animated)
        }
    }
}

Bu mevcut cevaplara ne katıyor?
greybeard

-1

Xamarin.iOS kabul edilen cevap sürümü

var bottomOffset = new CGPoint (0,
     scrollView.ContentSize.Height - scrollView.Frame.Size.Height
     + scrollView.ContentInset.Bottom);

scrollView.SetContentOffset (bottomOffset, false);

-1

UICollectionViewKopyalama ve yapıştırma kolaylığı için kabul edilen yanıtın Xamarin.iOS sürümü

var bottomOffset = new CGPoint (0, CollectionView.ContentSize.Height - CollectionView.Frame.Size.Height + CollectionView.ContentInset.Bottom);          
CollectionView.SetContentOffset (bottomOffset, false);
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.