Domanda

Come posso fare per trovare il rect (CGRect) del contenuto di una vista visualizzata che in realtà è visibile sullo schermo.

myScrollView.bounds

Il codice precedente funziona quando non c'è lo zoom, ma non appena si permettono lo zoom, si rompe a scale di zoom diverso da 1.

Per chiarire, io voglio un CGRect che contiene l'area visibile del contenuto della vista di scorrimento, relativa al contenuto. (Es. Se si tratta di una scala di zoom 2, le dimensioni del rettangolo sarà la metà delle dimensioni del vista di scorrimento, se è in scala di zoom 0.5, sarà doppio.)

È stato utile?

Soluzione 2

Rispondendo alla mia domanda, per lo più grazie alla risposta di Jim Dovey, che non riusciva a fare il trucco, ma mi ha dato la base per la mia risposta:

CGRect visibleRect;
visibleRect.origin = scrollView.contentOffset;
visibleRect.size = scrollView.bounds.size;

float theScale = 1.0 / scale;
visibleRect.origin.x *= theScale;
visibleRect.origin.y *= theScale;
visibleRect.size.width *= theScale;
visibleRect.size.height *= theScale;

La differenza principale è che la dimensione del visibleRect dovrebbe essere scrollView.bounds.size, piuttosto che scrollView.contentSize, che è la dimensione della vista contenuto. Inoltre semplificato la matematica un po ', e non riusciva a vedere l'uso per il isless() che rompere il codice ogni volta che è maggiore.

Altri suggerimenti

Oppure si potrebbe semplicemente fare

CGRect visibleRect = [scrollView convertRect:scrollView.bounds toView:zoomedSubview];

Swift

let visibleRect = scrollView.convert(scrollView.bounds, to: zoomedSubview)

Si deve calcolare utilizzando le proprietà contentOffset e contentSize di UIScrollView, in questo modo:

CGRect visibleRect;
visibleRect.origin = scrollView.contentOffset;
visibleRect.size = scrollView.contentSize;

È possibile quindi accedere per sanity-test:

NSLog( @"Visible rect: %@", NSStringFromCGRect(visibleRect) );

Per tenere conto di zoom (se non è già stato fatto dalla proprietà contentSize) si avrebbe bisogno di dividere ogni coordinata dal zoomScale, o per migliorare le prestazioni che ci si moltiplica per 1,0 / zoomScale:

CGFloat scale = (CGFloat) 1.0 / scrollView.zoomScale;
if ( isless(scale, 1.0) )      // you need to #include <math.h> for isless()
{
    visibleRect.origin.x *= scale;
    visibleRect.origin.y *= scale;
    visibleRect.size.width *= scale;
    visibleRect.size.height *= scale;
}

A parte: io uso isless (), isgreater (), IsEqual (), ecc da math.h perché questi saranno (presumibilmente) fare la cosa giusta per quanto riguarda in virgola mobile di confronto i risultati 'non ordinati' e altri architecture- strano & meraviglioso specifici casi FP.


Modifica: È necessario utilizzare bounds.size invece di contentSize nel calcolo visibleRect.size

.

versione più breve:

CGRect visibleRect = CGRectApplyAffineTransform(scrollView.bounds, CGAffineTransformMakeScale(1.0 / scrollView.zoomScale, 1.0 / scrollView.zoomScale));

Non sono sicuro se questo viene definito comportamento, ma quasi tutte le sottoclassi UIView avere l'origine della loro bounds impostato su (0,0). UIScrollViews, tuttavia, hanno il set di origine contentOffset.

un po 'di soluzione più generale potrebbe essere:

 [scrollView convertRect:scrollView.bounds
                             toView:[scrollView.delegate viewForZoomingInScrollView:scrollView]];
CGRect visibleRect;
visibleRect.origin = scrollView.contentOffset;
visibleRect.size = scrollView.frame.size;

Non credo che un UIScrollView ti dà direttamente che il rettangolo, ma penso di avere tutti gli elementi necessari per calcolarlo.

Una combinazione dei limiti, il contentOffset e la zoomScale dovrebbe essere tutto il necessario per creare il rettangolo che si sta cercando.

Swift 4.0:

La mia risposta adatta risposta di Trenskow per Swift 4.0:

let visible = scrollView.convert(scrollView.bounds, to: subView)

dove scrollView è la vista della chiocciola, e subView è la vista all'interno <=> che è stradale e contiene tutti i contenuti all'interno del rotolo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top