Jak Mogę automatycznie rozmiar UIScrollView dopasować zawartość
Czy istnieje sposób na automatyczne dopasowanie UIScrollView
do wysokości (lub szerokości) przewijanej zawartości?
Coś w stylu:
[scrollView setContentSize:(CGSizeMake(320, content.height))];
20 answers
Najlepsza metoda, jaką kiedykolwiek spotkałem, aby zaktualizować Rozmiar zawartości UIScrollView
w oparciu o zawarte w niej podviews:
ObjC
CGRect contentRect = CGRectZero;
for (UIView *view in self.scrollView.subviews) {
contentRect = CGRectUnion(contentRect, view.frame);
}
self.scrollView.contentSize = contentRect.size;
Swift
var contentRect = CGRect.zero
for view in mainScrollView.subviews {
contentRect = contentRect.union(view.frame)
}
mainScrollView.contentSize = contentRect.size
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-12-05 06:03:09
UIScrollView nie zna wysokości swojej zawartości automatycznie. Musisz obliczyć wysokość i szerokość dla siebie
Zrób to z czymś takim
CGFloat scrollViewHeight = 0.0f;
for (UIView* view in scrollView.subviews)
{
scrollViewHeight += view.frame.size.height;
}
[scrollView setContentSize:(CGSizeMake(320, scrollViewHeight))];
Ale to działa tylko wtedy, gdy widoki są JEDEN poniżej drugiego. Jeśli masz widok obok siebie, musisz tylko dodać jego wysokość, jeśli nie chcesz, aby zawartość przewijarki była większa niż w rzeczywistości.
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
2010-06-18 13:56:05
Dodałem to do odpowiedzi Espuz i JCC. Używa pozycji y podwidywań i nie zawiera pasków przewijania. Edit używa dołu najniższego widoku podrzędnego, który jest widoczny.
+ (CGFloat) bottomOfLowestContent:(UIView*) view
{
CGFloat lowestPoint = 0.0;
BOOL restoreHorizontal = NO;
BOOL restoreVertical = NO;
if ([view respondsToSelector:@selector(setShowsHorizontalScrollIndicator:)] && [view respondsToSelector:@selector(setShowsVerticalScrollIndicator:)])
{
if ([(UIScrollView*)view showsHorizontalScrollIndicator])
{
restoreHorizontal = YES;
[(UIScrollView*)view setShowsHorizontalScrollIndicator:NO];
}
if ([(UIScrollView*)view showsVerticalScrollIndicator])
{
restoreVertical = YES;
[(UIScrollView*)view setShowsVerticalScrollIndicator:NO];
}
}
for (UIView *subView in view.subviews)
{
if (!subView.hidden)
{
CGFloat maxY = CGRectGetMaxY(subView.frame);
if (maxY > lowestPoint)
{
lowestPoint = maxY;
}
}
}
if ([view respondsToSelector:@selector(setShowsHorizontalScrollIndicator:)] && [view respondsToSelector:@selector(setShowsVerticalScrollIndicator:)])
{
if (restoreHorizontal)
{
[(UIScrollView*)view setShowsHorizontalScrollIndicator:YES];
}
if (restoreVertical)
{
[(UIScrollView*)view setShowsVerticalScrollIndicator:YES];
}
}
return lowestPoint;
}
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-02-25 23:01:54
Rozwiązanie jeśli używasz układu auto:
Ustaw
translatesAutoresizingMaskIntoConstraints
NaNO
dla wszystkich widoków.Umieść i rozmiar widoku przewijania z ograniczeniami zewnętrznymi do widoku przewijania.
Używaj ograniczeń, aby rozłożyć podwinięcia w widoku przewijania, upewniając się, że ograniczenia są powiązane ze wszystkimi czterema krawędziami widoku przewijania i nie polegają na widoku przewijania, aby uzyskać ich rozmiar.
Źródło: https://developer.apple.com/library/ios/technotes/tn2154/_index.html
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-27 22:17:59
Oto zaakceptowana odpowiedź w języku swift dla każdego, kto jest zbyt leniwy, aby ją nawrócić:)
var contentRect = CGRectZero
for view in self.scrollView.subviews {
contentRect = CGRectUnion(contentRect, view.frame)
}
self.scrollView.contentSize = contentRect.size
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-16 07:33:47
Dalsze rozszerzenie byłoby pomocne w Swift .
extension UIScrollView{
func setContentViewSize(offset:CGFloat = 0.0) {
// dont show scroll indicators
showsHorizontalScrollIndicator = false
showsVerticalScrollIndicator = false
var maxHeight : CGFloat = 0
for view in subviews {
if view.hidden {
continue
}
let newHeight = view.frame.origin.y + view.frame.height
if newHeight > maxHeight {
maxHeight = newHeight
}
}
// set content size
contentSize = CGSize(width: contentSize.width, height: maxHeight + offset)
// show scroll indicators
showsHorizontalScrollIndicator = true
showsVerticalScrollIndicator = true
}
}
Logika jest taka sama z udzielonymi odpowiedziami. Pomija jednak ukryte widoki w UIScrollView
, A obliczenia są wykonywane po ustawieniu ukrytych wskaźników przewijania.
Istnieje również opcjonalny parametr funkcji i możesz dodać wartość offsetu, przekazując parametr do funkcji.
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-05-10 19:54:50
Świetne i najlepsze rozwiązanie od @ Lewiatan. Tłumaczenie na język swift z wykorzystaniem podejścia FP (functional programming).
self.scrollView.contentSize = self.scrollView.subviews.reduce(CGRect(), {
CGRectUnion($0, $1.frame)
}.size
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-11-27 14:11:33
Oto szybka 3 adaptacja odpowiedzi @ leviatan:
Rozszerzenie
import UIKit
extension UIScrollView {
func resizeScrollViewContentSize() {
var contentRect = CGRect.zero
for view in self.subviews {
contentRect = contentRect.union(view.frame)
}
self.contentSize = contentRect.size
}
}
Użycie
scrollView.resizeScrollViewContentSize()
Bardzo łatwy w użyciu !
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-07-08 23:52:15
Możesz uzyskać wysokość zawartości wewnątrz UIScrollView, obliczając, które dziecko "osiąga dalej". Aby to obliczyć, musisz wziąć pod uwagę pochodzenie Y (początek) i Wysokość elementu.
float maxHeight = 0;
for (UIView *child in scrollView.subviews) {
float childHeight = child.frame.origin.y + child.frame.size.height;
//if child spans more than current maxHeight then make it a new maxHeight
if (childHeight > maxHeight)
maxHeight = childHeight;
}
//set content size
[scrollView setContentSize:(CGSizeMake(320, maxHeight))];
W ten sposób elementy (podwidywacze)nie muszą być układane jeden pod drugim.
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-05-21 18:43:15
Wymyśliłem inne rozwiązanie oparte na rozwiązaniu @ emenegro
NSInteger maxY = 0;
for (UIView* subview in scrollView.subviews)
{
if (CGRectGetMaxY(subview.frame) > maxY)
{
maxY = CGRectGetMaxY(subview.frame);
}
}
maxY += 10;
[scrollView setContentSize:CGSizeMake(scrollView.frame.size.width, maxY)];
W zasadzie, możemy dowiedzieć się, który element jest najdalej w dół w widoku i dodaje padding 10px do dołu
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-04-05 16:12:53
Ponieważ widok przewijania może mieć inne widoki przewijania lub inne drzewo podwidywalne, preferowane jest wykonywanie w głębi rekurencyjnie.
Swift 2
extension UIScrollView {
//it will block the mainThread
func recalculateVerticalContentSize_synchronous () {
let unionCalculatedTotalRect = recursiveUnionInDepthFor(self)
self.contentSize = CGRectMake(0, 0, self.frame.width, unionCalculatedTotalRect.height).size;
}
private func recursiveUnionInDepthFor (view: UIView) -> CGRect {
var totalRect = CGRectZero
//calculate recursevly for every subView
for subView in view.subviews {
totalRect = CGRectUnion(totalRect, recursiveUnionInDepthFor(subView))
}
//return the totalCalculated for all in depth subViews.
return CGRectUnion(totalRect, view.frame)
}
}
Użycie
scrollView.recalculateVerticalContentSize_synchronous()
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-03-22 17:02:51
Lub po prostu zrób:
int y = CGRectGetMaxY(((UIView*)[_scrollView.subviews lastObject]).frame); [_scrollView setContentSize:(CGSizeMake(CGRectGetWidth(_scrollView.frame), y))];
(To rozwiązanie zostało dodane przeze mnie jako komentarz na tej stronie. Po zdobyciu 19 głosów za tym komentarzem, postanowiłem dodać To rozwiązanie jako formalną odpowiedź na korzyść społeczności!)
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-12-15 08:21:44
Rozmiar zależy od zawartości załadowanej wewnątrz i opcji przycinania. Jeśli jest to textview, to zależy również od zawijania, ile wierszy tekstu, rozmiaru czcionki, i tak dalej i dalej. Prawie niemożliwe dla Ciebie obliczenie siebie. Dobrą wiadomością jest to, że jest on obliczany po załadowaniu widoku i w viewWillAppear. Wcześniej wszystko jest nieznane, a rozmiar zawartości będzie taki sam jak rozmiar klatki. Ale w metodzie viewWillAppear i po (np. viewdidappear) zawartość rozmiar będzie rzeczywisty.
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-05-27 03:25:51
Owijając Kod Richy ' ego stworzyłem własną klasę UIScrollView, która automatyzuje zmiana rozmiaru treści całkowicie!
SBScrollView.h
@interface SBScrollView : UIScrollView
@end
SBScrollView.m:
@implementation SBScrollView
- (void) layoutSubviews
{
CGFloat scrollViewHeight = 0.0f;
self.showsHorizontalScrollIndicator = NO;
self.showsVerticalScrollIndicator = NO;
for (UIView* view in self.subviews)
{
if (!view.hidden)
{
CGFloat y = view.frame.origin.y;
CGFloat h = view.frame.size.height;
if (y + h > scrollViewHeight)
{
scrollViewHeight = h + y;
}
}
}
self.showsHorizontalScrollIndicator = YES;
self.showsVerticalScrollIndicator = YES;
[self setContentSize:(CGSizeMake(self.frame.size.width, scrollViewHeight))];
}
@end
Jak używać:
Wystarczy zaimportować .plik h do kontrolera widoku i
deklaruje wystąpienie sbscrollview zamiast zwykłego UIScrollView.
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-02-19 20:15:26
Ustaw dynamiczny Rozmiar zawartości w ten sposób.
self.scroll_view.contentSize = CGSizeMake(screen_width,CGRectGetMaxY(self.controlname.frame)+20);
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-16 08:03:23
To zależy od treści naprawdę: treść.rama.wzrost może dać ci to, czego chcesz ? Zależy, czy treść jest pojedynczą rzeczą, czy zbiorem rzeczy.
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
2010-05-31 15:12:46
Znalazłem też odpowiedź Lewiatana na najlepszą. Obliczał jednak dziwną wysokość. Jeśli przewijanie jest ustawione na wyświetlanie wskaźników przewijania podczas przewijania, będą one znajdować się w tablicy podglądów. W takim przypadku rozwiązaniem jest tymczasowe wyłączenie wskaźników przewijania przed zapętleniem, a następnie przywrócenie ich poprzedniego ustawienia widoczności.
-(void)adjustContentSizeToFit
jest publiczną metodą na niestandardowej podklasie UIScrollView.
-(void)awakeFromNib {
dispatch_async(dispatch_get_main_queue(), ^{
[self adjustContentSizeToFit];
});
}
-(void)adjustContentSizeToFit {
BOOL showsVerticalScrollIndicator = self.showsVerticalScrollIndicator;
BOOL showsHorizontalScrollIndicator = self.showsHorizontalScrollIndicator;
self.showsVerticalScrollIndicator = NO;
self.showsHorizontalScrollIndicator = NO;
CGRect contentRect = CGRectZero;
for (UIView *view in self.subviews) {
contentRect = CGRectUnion(contentRect, view.frame);
}
self.contentSize = contentRect.size;
self.showsVerticalScrollIndicator = showsVerticalScrollIndicator;
self.showsHorizontalScrollIndicator = showsHorizontalScrollIndicator;
}
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-01-14 17:23:53
Myślę, że może to być zgrabny sposób aktualizacji rozmiaru widoku zawartości UIScrollView.
extension UIScrollView {
func updateContentViewSize() {
var newHeight: CGFloat = 0
for view in subviews {
let ref = view.frame.origin.y + view.frame.height
if ref > newHeight {
newHeight = ref
}
}
let oldSize = contentSize
let newSize = CGSize(width: oldSize.width, height: newHeight + 20)
contentSize = newSize
}
}
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-12 11:50:44
Dlaczego nie jedna linijka kodu??
_yourScrollView.contentSize = CGSizeMake(0, _lastView.frame.origin.y + _lastView.frame.size.height);
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-03-29 08:12:21
Dla swift4 z redukcją:
self.scrollView.contentSize = self.scrollView.subviews.reduce(CGRect.zero, {
return $0.union($1.frame)
}).size
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-05-22 12:26:48