Ответ 1
На данный момент это лучшее, что у меня есть:
CGRect contentRect = CGRectZero;
for (UIView *view in self.subviews)
contentRect = CGRectUnion(contentRect, view.frame);
self.contentSize = contentRect.size;
У UIView есть метод SizeToFit, который сделает UIView подходящим для всех его подзонов. Есть ли что-то подобное, которое просто вернет размер, который он вычисляет и не изменяет какой-либо кадр представления.
У меня есть несколько subviews в UIScrollView, и я хочу сделать SizeToFit в прокрутке view contentSize, а не в кадре. Я должен сделать это в contentSize, потому что я не хочу увеличивать "реальный" размер UIScrollView, и содержимое загружается динамически и асинхронно, поэтому я не могу сделать это вручную, когда добавляю subviews в UIScrollView.
На данный момент это лучшее, что у меня есть:
CGRect contentRect = CGRectZero;
for (UIView *view in self.subviews)
contentRect = CGRectUnion(contentRect, view.frame);
self.contentSize = contentRect.size;
Если ваша функция вызывается часто, вы не хотите каждый раз перебирать подзоны. Вместо этого, всякий раз, когда добавляется 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;
}
Найденное решение здесь 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
Я сделал одну функцию для настройки размера содержимого 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% уверен, что он будет работать.........
Вот ответ для 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)")
}
В то время как ответ Уильяма был очень полезен, он не работал отлично, поскольку полосы прокрутки также являются областями прокрутки. Оказывается, трюк заключается в том, чтобы скрыть их перед вычислением размера содержимого. Здесь будет выглядеть код 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
}
}
Поместите UIView в UIScrollView с одинаковой шириной и высотой и добавьте все подпрограммы в ИТ, а не в scrollview. Затем установите для свойства clipToBounds значение scrollview значение TRUE и вызовите sizeToFit в вашем UIView. Вы также можете установить непрозрачность фона UIView на 0, делая его невидимым, но все еще отображая его подпункты.
В 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
}
Недостаточно, чтобы размеры кадра объединения вычисляли размер содержимого. Потому что иногда ваш подзаголовок должен перекрываться, и иногда у вас есть поля между подзонами. Вы должны знать и рассчитать происхождение 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)
}
}
Расширение 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
}
}