2012-05-09 22 views
19

Tengo una pregunta sobre UIScrollview.Cómo configurar el tamaño de contenido de UIScrollView dinámicamente

La historia es que tengo un UIView llamado ChartsView que lo redibujo yo mismo mediante el método de anulación drawRect(). El contenido del dibujo se generó dinámicamente. Así que no sé su tamaño hasta el tiempo de ejecución. La pregunta es ¿cómo/dónde puedo establecer el tamaño del contenido de su súper vista (scrollView) dinámicamente? ¿Alguna idea sobre eso?

- (void)viewDidLoad 
    { 
     [super viewDidLoad]; 

// not this way. it's fixed size..... 
     ChartsView *chartsView = [[ChartsView alloc]initWithFrame:CGRectMake(0, 0, 320, 800)]; 

     self.scrollView.contentSize = chartsView.frame.size; 

     [self.scrollView addSubview:chartsView]; 

    } 

Respuesta

1

probar este

- (void)viewDidLoad 
     { 
      [super viewDidLoad]; 

    // not this way. it's fixed size..... 
      ChartsView *chartsView = [[ChartsView alloc]initWithFrame:CGRectMake(0, 0, 320, 800)]; 

      self.scrollView.contentSize = chartsView.frame.size; 
      [self.scrollView setNeedsDisplay]; 
      [self.scrollView addSubview:chartsView]; 

    } 
+0

sigue sin suerte. Intento encontrar una solución alternativa, establecer el tamaño del contenido de la vista de desplazamiento en la vista Gráficos cuando finaliza el dibujo. Ahora la pregunta es qué tipo de API puedo usar para obtener el tamaño actual de gráficosView ((UIScrollView *) [autoverview]). ContentSize = CGSizeMake (320, 480); –

54

una forma más fácil

- (void)viewDidLoad 
{ 
    float sizeOfContent = 0; 
    UIView *lLast = [scrollView.subviews lastObject]; 
    NSInteger wd = lLast.frame.origin.y; 
    NSInteger ht = lLast.frame.size.height; 

    sizeOfContent = wd+ht; 

    scrollView.contentSize = CGSizeMake(scrollView.frame.size.width, sizeOfContent); 
} 
+0

buen truco. Se puede usar para cualquier 'UIScrollView'. +1 por eso. –

+0

Solo me gustaría agregar una cosa. Algunos de ustedes pueden poner este código en viwDidAppear: porque su UIView puede dibujarse antes de viewDidAppear pero después de llamar a viewDidLoad; Esto le permitirá tener acceso a la última altura de la vista. – mvb

+10

lastObject devuelve el último objeto indexado en la matriz de subvistas, no la subvista inferior en la pantalla. de hecho, lastObject no tiene nada que ver con la posición de la vista y su uso es incorrecto. – AmitP

5

rápida (2,0)

@IBOutlet weak var btnLatestButton: UIButton! 

override func viewDidLoad() { 
    super.viewDidLoad() 

    let height = btnLatestButton.frame.size.height 
    let pos = btnLatestButton.frame.origin.y 
    let sizeOfContent = height + pos + 10 
    scrollview.contentSize.height = sizeOfContent 

} 

encima supuesto es cuando sólo hay una solución ed cantidad de vistas en su scrollview. El método IOS Rocks está disponible pero no fue bueno para mí, creó más espacio que el que necesitaba.

let lastView : UIView! = scrollview.subviews.last 
    let height = lastView.frame.size.height 
    let pos = lastView.frame.origin.y 
    let sizeOfContent = height + pos + 10 
    scrollview.contentSize.height = sizeOfContent 
3

Gracias a IOS Rocks y CularBytes por los cables en esto. He encontrado dos problemas (para mí) con las soluciones anteriores:

  1. siempre tengo un UIView contenedor que el único hijo de mi UIScrollView, así que tuve que actualizar la manera en que veo hasta la última vista en aquel niño UIView (ver más abajo)
  2. estoy offset'ing mis contenidos en el UIScrollView y como tal es necesario para calcular la posición absoluto de ese último UIView (así, con relación a la ventana no la vista padre)

también me estoy usando el autolayout para fijar los lados del UIScrollView, así que no tengo que preocuparme por el ancho (como es CularBytes).

Esto es lo que se me ocurrió y obras (en Swift 3.0):

func setScrollViewContentSize() { 

    var height: CGFloat 
    let lastView = self.myScrollView.subviews[0].subviews.last! 
    print(lastView.debugDescription) // should be what you expect 

    let lastViewYPos = lastView.convert(lastView.frame.origin, to: nil).y // this is absolute positioning, not relative 
    let lastViewHeight = lastView.frame.size.height 

    // sanity check on these 
    print(lastViewYPos) 
    print(lastViewHeight) 

    height = lastViewYPos + lastViewHeight 

    print("setting scroll height: \(height)") 

    myScrollView.contentSize.height = height 
} 

Yo llamo a esto en mi método viewDidAppear().

1

Prueba esto -

- (void)viewDidLoad 
    { 
     [super viewDidLoad]; 

// not this way. it's fixed size..... 
     ChartsView *chartsView = [[ChartsView alloc]initWithFrame:CGRectMake(0, 0, 320, 800)]; 

     //self.scrollView.contentSize = chartsView.frame.size; 
     [self.scrollView setContentSize:CGSizeMake(chartsView.frame.size.width, chartsView.frame.size.height)]; 
     [self.scrollView addSubview:chartsView]; 

    } 
1

No es 100% garantizado que el último objeto de matriz scrollView.subviews devolverá el objeto más elevado y-origen en la vista de desplazamiento. La matriz de subvistas está organizada por Z-Index (es decir, el último objeto en la matriz de subvistas será el objeto apilado más alto y será la subvista superior en las subvistas de la vista de desplazamiento. En su lugar, es más preciso utilizar una función de clasificación básica iterar a través de las subvistas y obtener el objeto con el origen y más alto.

Aquí es una función básica en Swift 3 que eso puede hacerlo:

func calculateContentSize(scrollView: UIScrollView) -> CGSize { 
    var topPoint = CGFloat() 
    var height = CGFloat() 

    for subview in scrollView.subviews { 
     if subview.frame.origin.y > topPoint { 
      topPoint = subview.frame.origin.y 
      height = subview.frame.size.height 
     } 
    } 
    return CGSize(width: scrollView.frame.size.width, height: height + topPoint) 
} 

Uso (en viewDidLayoutSubviews o cuando sus cambios de tamaño de contenido):

scrollView.contentSize = calculateContentSize(scrollView: scrollView) 

ACTUALIZACIÓN SWIFT 4

Aquí hay una versión más consise en swift 4

extension UIScrollView { 
    func updateContentView() { 
     contentSize.height = subviews.sorted(by: { $0.frame.maxY < $1.frame.maxY }).last?.frame.maxY ?? contentSize.height 
    } 
} 

Uso:

myScrollView.updateContentView() 
0

Ésta es una extensión escrita en Swift 3

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 + 100) 
     contentSize = newSize 
    } 
} 
Cuestiones relacionadas