2012-05-09 21 views
19

Ho ricevuto una domanda su UIScrollview.Come impostare dinamicamente la dimensione del contenuto di UIScrollView

La storia è che ho un ChartsView denominato UIView che lo ridisegno da solo con il metodo di sovrascrittura drawRect(). Il contenuto del disegno è stato generato dinamicamente. Quindi non conosco le sue dimensioni fino al runtime. La domanda è: come/dove posso impostare dinamicamente la dimensione del contenuto della vista super (scrollView)? Qualche idea al riguardo?

- (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]; 

    } 

risposta

1

provare questo

- (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

ancora senza fortuna. Cerco di trovare una soluzione alternativa, impostare la dimensione del contenuto di scrollview in visualizzazione Grafici quando si esegue il disegno. Ora la domanda è quale tipo di API posso usare per ottenere una dimensione reale dei graficiView ((UIScrollView *) [self superview]). ContentSize = CGSizeMake (320, 480); –

54

più Un modo semplice

- (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

bel trucco. Può essere usato per qualsiasi 'UIScrollView'. +1 per quello. –

+0

Vorrei solo aggiungere una cosa. Alcuni di voi potrebbero voler inserire questo codice in viwDidAppear: perché il vostro UIView può essere disegnato prima di viewDidAppear ma dopo che viene chiamato viewDidLoad; Ciò ti consentirà di accedere alla più recente altezza della vista. – mvb

+10

lastObject restituisce l'ultimo oggetto indicizzato nella matrice di sottoview, non la sottoview più in basso sullo schermo. infatti, lastObject non ha nulla a che fare con la posizione della vista e usarlo è sbagliato. – AmitP

5

rapida (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 

} 

Sopra naturalmente è quando basta una correzione quantità di visualizzazioni sulla tua scrollview. Il metodo IOS Rocks è disponibile ma non mi ha fatto bene, ha creato più spazio di cui avevo bisogno.

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

Grazie a IOS Rocks e CularBytes per i lead su questo. Ho trovato due problemi (per me) con le soluzioni di cui sopra:

  1. ho sempre un UIView contenitore come l'unico figlio della mia UIScrollView, così ho dovuto aggiornare il mio modo di guardare l'ultima vista in quel bambino UIView (vedi sotto)
  2. sto offset'ing mio contenuto nel UIScrollView e come tale necessarie per calcolare la posizione assoluta di quell'ultimo UIView (così, rispetto alla finestra non vista primaria)

anche io sto usando l'autolayout per bloccare i lati di UIScrollView, quindi non devo preoccuparmi della larghezza (come è CularBytes).

Ecco cosa mi è venuta e di lavori (nel 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 
} 

Io chiamo questo nel mio metodo viewDidAppear().

1

Prova questo -

- (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

Non è garantito che l'ultimo oggetto in ordine di scrollView.subviews tornerà il più alto oggetto y-origine nella vista di scorrimento 100%. L'array di sottoview è organizzato da Z-Index (cioè l'ultimo oggetto nella matrice di sottoview sarà l'oggetto impilato il più alto e sarà la sottoview più in alto nelle sottoview della vista a scorrimento.Invece è più preciso usare una funzione di ordinamento di base per scorrere le sottoview e ottenere l'oggetto con l'origine Y più alta.

Ecco una funzione di base in rapida 3, che che può fare così:

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 (in viewDidLayoutSubviews o ogni volta che gli aggiornamenti di dimensioni contenuti):

scrollView.contentSize = calculateContentSize(scrollView: scrollView) 

AGGIORNAMENTO SWIFT 4

Ecco una versione più consace in swift 4

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

Usage:

myScrollView.updateContentView() 
0

Si tratta di un'estensione scritto su 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 
    } 
} 
Problemi correlati