Подтвердить что ты не робот

SizeToFit для размера содержимого UIScrollView

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

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

4b9b3361

Ответ 1

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

CGRect contentRect = CGRectZero;
for (UIView *view in self.subviews)
    contentRect = CGRectUnion(contentRect, view.frame);
self.contentSize = contentRect.size;

Ответ 2

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

- (void)didAddSubview:(UIView *)subview {
    CGRect tmp;
    tmp.origin = CGPointZero;
    tmp.size = self.contentSize;
    tmp = CGRectUnion(tmp,subview.frame);
    self.contentSize = tmp.size;
}

Ответ 3

Найденное решение здесь 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

Ответ 4

Я сделал одну функцию для настройки размера содержимого 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% уверен, что он будет работать.........

Ответ 5

Вот ответ для 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)")
}

Ответ 6

В то время как ответ Уильяма был очень полезен, он не работал отлично, поскольку полосы прокрутки также являются областями прокрутки. Оказывается, трюк заключается в том, чтобы скрыть их перед вычислением размера содержимого. Здесь будет выглядеть код 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
    }
}

Ответ 7

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

Ответ 8

В 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

}

Ответ 9

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

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

введите описание изображения здесь

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

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

Ответ 10

Расширение 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

    }

}