Uiscrollview przewiń programowo do dołu

Jak mogę wykonać UIScrollView przewinięcie na dół w moim kodzie? Lub w bardziej ogólny sposób, do dowolnego punktu subview?

Author: Leo Dabus, 2009-06-04

24 answers

Możesz użyć funkcji UIScrollView setContentOffset:animated:, aby przewijać do dowolnej części widoku zawartości. Oto kod, który przewija się do dołu, zakładając, że twój scrollView to self.scrollView:

CGPoint bottomOffset = CGPointMake(0, self.scrollView.contentSize.height - self.scrollView.bounds.size.height);
[self.scrollView setContentOffset:bottomOffset animated:YES];
Mam nadzieję, że to pomoże!
 574
Author: Ben Gotow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-24 04:27:44

Szybka wersja zaakceptowanej odpowiedzi do łatwego wklejania kopii:

let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.size.height)
scrollView.setContentOffset(bottomOffset, animated: true)
 75
Author: Esqarrouth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-11 16:04:08

Najprostsze Rozwiązanie:

[scrollview scrollRectToVisible:CGRectMake(scrollview.contentSize.width - 1,scrollview.contentSize.height - 1, 1, 1) animated:YES];
 48
Author: Hai Hw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-07 08:41:02

Tylko ulepszenie istniejącej odpowiedzi.

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

Zajmuje się również dolną wstawką (w przypadku, gdy używasz jej do dostosowywania widoku przewijania, gdy klawiatura jest widoczna)

 23
Author: vivek241,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-06 11:33:51

Ustawienie przesunięcia zawartości na wysokość rozmiaru zawartości jest błędne: przewija dół zawartości do góry widoku przewijania, a tym samym poza pole widzenia.

Poprawnym rozwiązaniem jest przewinięcie dołu zawartości do dołu widoku przewijania, tak jak to (sv jest UIScrollView):

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];
}
 19
Author: matt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-11 17:32:57

Rozwiązanie Swift 2.2 z uwzględnieniem contentInset

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

To powinno być w rozszerzeniu

extension UIScrollView {

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

Pamiętaj, że możesz sprawdzić, czy bottomOffset.y > 0 przed przewijaniem

 14
Author: onmyway133,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-07 12:19:41

Przewiń Do Góry

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

Przewiń Do Dołu

- CGPoint bottomOffset = CGPointMake(0, scrollView.contentSize.height - self.scrollView.bounds.size.height);
 - [scrollView setContentOffset:bottomOffset animated:YES];
 13
Author: Waseem,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-30 15:05:23

Szybka realizacja:

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

Wywołujesz rozszerzenie w ten sposób:

yourScrollview.scrollToBottom(animated: true)
 10
Author: duan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-15 15:58:55

Co jeśli contentSize jest niższe niż bounds?

Dla Swift jest to:

scrollView.setContentOffset(CGPointMake(0, max(scrollView.contentSize.height - scrollView.bounds.size.height, 0) ), animated: true)
 9
Author: Bartłomiej Semańczyk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-16 19:56:25

Znalazłem również inny przydatny sposób na zrobienie tego w przypadku, gdy używasz UITableview (który jest podklasą UIScrollView):

[(UITableView *)self.view scrollToRowAtIndexPath:scrollIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
 7
Author: nico,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-11 00:16:41

Używanie funkcji UIScrollView setContentOffset:animated: do przewijania do dołu w języku Swift.

let bottomOffset : CGPoint = CGPointMake(0, scrollView.contentSize.height - scrollView.bounds.size.height + scrollView.contentInset.bottom)
scrollView.setContentOffset(bottomOffset, animated: true)
 6
Author: Kim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-15 15:15:03

Z (opcjonalnym) widokiem stopki i contentInset rozwiązaniem jest:

CGPoint bottomOffset = CGPointMake(0, _tableView.contentSize.height - tableView.frame.size.height + _tableView.contentInset.bottom);
if (bottomOffset.y > 0) [_tableView setContentOffset: bottomOffset animated: YES];
 5
Author: Pieter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-28 19:59:30

Valdyr, mam nadzieję, że to ci pomoże:

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

if (bottomOffset.y > 0)
 [textView setContentOffset: bottomOffset animated: YES];
 3
Author: Misha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-11 00:17:06

Kategoria na ratunek!

Dodaj to gdzieś do nagłówka współdzielonego narzędzia:

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

A następnie do tej implementacji narzędzia:

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

Następnie zaimplementuj go tam, gdzie chcesz, na przykład:

[[myWebView scrollView] scrollToBottomAnimated:YES];
 2
Author: BadPirate,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-14 19:18:49

Dobrym sposobem, aby upewnić się, że dno Twojej treści jest widoczne, jest użycie formuły:

contentOffsetY = MIN(0, contentHeight - boundsHeight)

Zapewnia to, że dolna krawędź zawartości jest zawsze na dolnej krawędzi widoku lub powyżej niej. MIN(0, ...) jest wymagane, ponieważ UITableView (i prawdopodobnie UIScrollView) zapewnia contentOffsetY >= 0, gdy użytkownik próbuje przewijać przez widoczne przyciągnięcie contentOffsetY = 0. To wygląda dość dziwnie dla użytkownika.

Kod do wdrożenia to:

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
Author: jjrscott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-27 08:34:05

Jeśli nie potrzebujesz animacji, to działa:

[self.scrollView setContentOffset:CGPointMake(0, CGFLOAT_MAX) animated:NO];
 1
Author: Krys Jurgowski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-16 15:44:28

Podczas Gdy Matt rozwiązanie wydaje mi się poprawne, musisz wziąć pod uwagę również wstawkę widoku kolekcji, jeśli istnieje taki, który został skonfigurowany.

Dostosowany kod będzie brzmiał:

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
Author: tiguero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-17 14:09:27

Rozwiązanie do przewinięcia do ostatniej pozycji widoku tabeli:

Swift 3:

if self.items.count > 0 {
        self.tableView.scrollToRow(at:  IndexPath.init(row: self.items.count - 1, section: 0), at: UITableViewScrollPosition.bottom, animated: true)
}
 1
Author: MarionFlex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-28 20:18:11

Nie zadziałało u mnie, gdy próbowałem go użyć w UITableViewController na self.tableView (iOS 4.1), Po dodaniu footerView. Przewija się poza granice, pokazując czarny ekran.

Alternatywne rozwiązanie:

 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
Author: valdyr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-08 09:14:35
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
Author: 8suhas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-31 08:23:08

Odkryłem, że contentSize nie odzwierciedla rzeczywistego rozmiaru tekstu, więc przy próbie przewinięcia do dołu będzie on trochę wyłączony. Najlepszym sposobem na określenie rzeczywistego rozmiaru zawartości jest użycie metody NSLayoutManager ' s usedRectForTextContainer::

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

Aby określić, ile tekstu rzeczywiście jest wyświetlany w UITextView, można go obliczyć, odejmując wstawki kontenera tekstowego od wysokości ramki.

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

Potem staje się łatwe do przewijania:

// 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;

Niektóre liczby dla odniesienie do tego, co reprezentują różne rozmiary dla pustej 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
Author: mikeho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-26 22:00:14

W języku swift:

   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)
    }
 0
Author: Ponja,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-24 20:37:06

Xamarin.iOS {[3] } wersja zaakceptowanej odpowiedzi

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

scrollView.SetContentOffset (bottomOffset, false);
 0
Author: Abdur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-10 07:49:43

Xamarin.iOS wersja dla UICollectionView zaakceptowanej odpowiedzi dla ułatwienia w kopiowaniu i wklejaniu

var bottomOffset = new CGPoint (0, CollectionView.ContentSize.Height - CollectionView.Frame.Size.Height + CollectionView.ContentInset.Bottom);          
CollectionView.SetContentOffset (bottomOffset, false);
 0
Author: Abdur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-03 10:10:39