Как мне автоматически изменить размер UIScrollView, чтобы соответствовать его содержимому - PullRequest
121 голосов
/ 31 мая 2010

Есть ли способ автоматически настроить UIScrollView на высоту (или ширину) прокручиваемого содержимого?

Что-то вроде:

[scrollView setContentSize:(CGSizeMake(320, content.height))];

Ответы [ 20 ]

3 голосов
/ 22 марта 2017

Поскольку scrollView может иметь другие scrollViews или другое дерево подпунктов inDepth, рекурсивный запуск в глубину предпочтителен. enter image description here

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

Использование

scrollView.recalculateVerticalContentSize_synchronous()
2 голосов
/ 15 декабря 2015

Или просто сделайте:

int y = CGRectGetMaxY(((UIView*)[_scrollView.subviews lastObject]).frame); [_scrollView setContentSize:(CGSizeMake(CGRectGetWidth(_scrollView.frame), y))];

(Это решение было добавлено мной в качестве комментария на этой странице. Получив 19 голосов за этот комментарий, я решил добавить это решение в качестве официального ответа в интересах сообщества!)

1 голос
/ 20 февраля 2013

Оборачивая код Ричи, я создал собственный класс UIScrollView, который автоматизирует изменение размера контента полностью!

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

Как использовать:
Просто импортируйте файл .h в свой контроллер представления и объявите экземпляр SBScrollView вместо обычного UIScrollView.

1 голос
/ 27 мая 2011

Размер зависит от содержимого, загруженного в него, и параметров отсечения. Если это текстовое представление, то это также зависит от переноса текста, количества строк текста, размера шрифта и так далее. Почти невозможно для вас вычислить себя. Хорошей новостью является то, что он вычисляется после загрузки представления и в viewWillAppear. До этого все неизвестно и размер контента будет такой же, как и размер кадра. Но в методе viewWillAppear и после (например, viewDidAppear) размер контента будет фактическим.

1 голос
/ 16 июля 2016

Установить динамический размер контента следующим образом.

 self.scroll_view.contentSize = CGSizeMake(screen_width,CGRectGetMaxY(self.controlname.frame)+20);
1 голос
/ 22 мая 2018

Для swift4, используя уменьшить:

self.scrollView.contentSize = self.scrollView.subviews.reduce(CGRect.zero, {
   return $0.union($1.frame)
}).size
0 голосов
/ 04 июня 2014

Я также нашел ответ Левиафана, чтобы работать лучше всего. Тем не менее, он рассчитывал странную высоту. При циклическом просмотре подпредставлений, если для прокрутки установлено отображение индикаторов прокрутки, они будут в массиве подпредставлений. В этом случае решение состоит в том, чтобы временно отключить индикаторы прокрутки перед циклом, а затем восстановить их прежнюю настройку видимости.

-(void)adjustContentSizeToFit - это открытый метод пользовательского подкласса 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;
}
0 голосов
/ 29 марта 2016

почему не одна строка кода ??

_yourScrollView.contentSize = CGSizeMake(0, _lastView.frame.origin.y + _lastView.frame.size.height);
0 голосов
/ 12 сентября 2015

Я думаю, что это может быть аккуратным способом обновления размера представления контента 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
    }
}
0 голосов
/ 31 мая 2010

это зависит от контента на самом деле: content.frame.height может дать вам то, что вы хотите? Зависит от того, является ли контент отдельной вещью или совокупностью вещей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...