SizeToFit для размера контента UIScrollView - PullRequest
19 голосов
/ 26 октября 2010

UIView имеет метод SizeToFit, который сделает UIView подходящим для всех его подпредставлений.Есть ли что-нибудь подобное, которое будет просто возвращать размер, который он вычисляет, и не изменять фрейм любого представления.

У меня есть несколько подпредставлений в UIScrollView, и я хочу сделать SizeToFit для contentSize представления прокрутки, а не дляРамка.Я должен сделать это на contentSize, потому что я не хочу увеличивать «реальный» размер UIScrollView, а содержимое загружается динамически и асинхронно, поэтому я не могу сделать это вручную, когда я добавляю подпредставления в UIScrollView..

Ответы [ 10 ]

39 голосов
/ 22 ноября 2010

На данный момент это лучшее, что у меня есть:

CGRect contentRect = CGRectZero;
for (UIView *view in self.subviews)
    contentRect = CGRectUnion(contentRect, view.frame);
self.contentSize = contentRect.size;
4 голосов
/ 28 ноября 2010

Если ваша функция вызывается часто, вы не захотите перебирать подпредставления каждый раз. Вместо этого всякий раз, когда добавляется подпредставление, выполняется объединение текущего contentSize и фрейма нового подпредставления.

- (void)didAddSubview:(UIView *)subview {
    CGRect tmp;
    tmp.origin = CGPointZero;
    tmp.size = self.contentSize;
    tmp = CGRectUnion(tmp,subview.frame);
    self.contentSize = tmp.size;
}
2 голосов
/ 26 марта 2012

Найдя решение здесь ScrollView ContentSize , вы сможете найти размеры подпредставлений и найти объединенный размер контента, а также варианты, чтобы указать, расположены ли подпредставления горизонтально или вертикально.

Вот код по ссылке выше:

@interface UIScrollView(auto_size)
- (void) adjustHeightForCurrentSubviews: (int) verticalPadding;
- (void) adjustWidthForCurrentSubviews: (int) horizontalPadding;
- (void) adjustWidth: (bool) changeWidth andHeight: (bool) changeHeight withHorizontalPadding: (int) horizontalPadding andVerticalPadding: (int) verticalPadding;
@end

@implementation UIScrollView(auto_size)
- (void) adjustWidth: (bool) changeWidth andHeight: (bool) changeHeight withHorizontalPadding: (int) horizontalPadding andVerticalPadding: (int) verticalPadding {
    float contentWidth = horizontalPadding;
    float contentHeight = verticalPadding;
    for (UIView* subview in self.subviews) {
        [subview sizeToFit];
        contentWidth += subview.frame.size.width;
        contentHeight += subview.frame.size.height;
    }

    contentWidth = changeWidth ? contentWidth : self.superview.frame.size.width;
    contentHeight = changeHeight ? contentHeight : self.superview.frame.size.height;

    NSLog(@"Adjusting ScrollView size to %fx%f, verticalPadding=%d, horizontalPadding=%d", contentWidth, contentHeight, verticalPadding, horizontalPadding);
    self.contentSize = CGSizeMake(contentWidth, contentHeight);
}

- (void) adjustHeightForCurrentSubviews: (int) verticalPadding {
    [self adjustWidth:NO andHeight:YES withHorizontalPadding:0 andVerticalPadding:verticalPadding];
}

- (void) adjustWidthForCurrentSubviews: (int) horizontalPadding {
    [self adjustWidth:YES andHeight:NO withHorizontalPadding:horizontalPadding andVerticalPadding:0];
}
@end

Также обязательно ознакомьтесь с комментариями на странице блога, поскольку предоставляется альтернативное решение.

-anoop

1 голос
/ 21 марта 2017

Хотя ответ Уильяма был очень полезен, он не работал идеально, поскольку полосы прокрутки также являются подпредставлениями прокрутки. Оказывается, хитрость заключается в том, чтобы скрыть их перед вычислением размера контента. Вот как будет выглядеть код Swift 3:

override func viewDidLayoutSubviews() {
    scrollView.layoutSubviews()

    // disable scrollbars so they don't interfere during resizing
    scrollView.showsVerticalScrollIndicator = false
    scrollView.showsHorizontalScrollIndicator = false

    scrollView.contentSize = scrollView.subViewArea()

    // re-enable the scrollbars
    scrollView.showsVerticalScrollIndicator = true
    scrollView.showsHorizontalScrollIndicator = true
}

Вам также необходимо добавить следующее расширение где-нибудь в вашем проекте:

extension UIScrollView {
    func subViewArea() -> CGSize {
        var rect = CGRect.zero
        for subview in subviews {
            rect = rect.union(subview.frame)
        }

        return rect.size
    }
}
1 голос
/ 05 декабря 2016

Вот ответ для Swift 3.0

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    var contentRect: CGRect = CGRect.zero
    for view in self.scrollView.subviews {
        debugPrint("view frame \(view.frame)")
        contentRect = contentRect.union(view.frame)
        debugPrint("frame \(contentRect)")
    }
    self.scrollView.contentSize = contentRect.size
    debugPrint("content size \(self.scrollView.contentSize)")
}
1 голос
/ 13 марта 2013

Я сделал одну функцию для настройки размера содержимого scrollView, попробуйте и наслаждайтесь

Прежде всего напишите эту функцию ...

-(void)setContentSizeOfScrollView:(UIScrollView*)scroll
{
    CGRect rect = CGRectZero;

    for(UIView * vv in [scroll subviews])
    {
        rect = CGRectUnion(rect, vv.frame);
    }

    [scroll setContentSize:CGSizeMake(rect.size.width, rect.size.height)];
}

, затем после добавления всех элементов просто вызовитефункции и передать ваш вид прокрутки в качестве аргумента .....

[self setContentSizeOfScrollView:self.YourScrollView];

Я на 100% уверен, что он будет работать .........

0 голосов
/ 13 октября 2017

Этого недостаточно, чтобы объединить размеры кадров, чтобы рассчитать размер контента.Потому что иногда ваше подпредставление должно перекрываться, а иногда у вас есть поля между подпредставлениями.Вы должны знать и рассчитать происхождение подпредставлений.

Объединенный подход дает одинаковое количество контента для дизайнов A и B.Но если вы знаете самое большое последнее подпредставление, вы можете рассчитать правильную высоту содержимого:

enter image description here

Это расширение может вычислять реальную высоту содержимого.

extension UIScrollView {

 func adjustContentHeight(bottomPadding: Int = 0) {

    var lastSub: CGRect = .zero
    self.subviews.forEach({
        let sub = $0.frame
        if(sub.maxY > lastSub.maxY) {
            lastSub = sub
        }
    })

    self.contentSize.height = lastSub.maxY + CGFloat(bottomPadding)
 }   
} 
0 голосов
/ 08 апреля 2016

Удлинитель Swift 2:

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

scrollView.contentResize
scrollView.contentWidthResize
scrollView.contentHeightResize

extension UIScrollView {

    ///Will resize content size to fit all subviews.
    func contentResize(){

        var w = CGFloat(0)
        var h = CGFloat(0)

        for view in self.subviews{

            let fw = view.frame.origin.x + view.frame.width
            let fh = view.frame.origin.y + view.frame.height

            w = max(fw, w)
            h = max(fh, h)

        }

        contentSize = CGSize(width: w, height: h)

    }

    ///Will resize content width size to fit all subviews.
    func contentWidthResize(){

        var w = CGFloat(0)

        for view in self.subviews{

            let fw = view.frame.origin.x + view.frame.width

            w = max(fw, w)

        }

        contentSize.width = w

    }

    ///Will resize content height size to fit all subviews.
    func contentHeightResize(){

        var h = CGFloat(0)

        for view in self.subviews{

            let fh = view.frame.origin.y + view.frame.height

            h = max(fh, h)

        }

        contentSize.height = h

    }

}
0 голосов
/ 09 февраля 2016

В swift 2.1 добавьте это в свой контроллер вида:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    let aggregateView = contentView.subviews.reduce(CGRect())
        { aggRect, view in aggRect.union(view.frame) }

    scrollView.contentSize = aggregateView.size

}
0 голосов
/ 28 октября 2010

Поместите UIView в UIScrollView, который имеет ту же ширину и высоту, и добавьте все подпредставления в IT, а не в scrollview.Затем установите свойство clipToBounds в scrollview равным TRUE и вызовите sizeToFit для вашего UIView.Вы также можете установить непрозрачность фона UIView на 0, делая его невидимым, но все равно показывая его подпредставления.

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