Domanda

Ho un UIScrollView che ha un UIImageView. Voglio mostrare i pin su questo imageView. Quando aggiungo i pin come sottoview di ImageView, tutto è fantastico tranne che quando si ingrandisce la trasformazione della scala avviene anche sui pin. Non voglio questo comportamento e voglio che le mie spille rimangano le stesse.

Quindi scelgo di aggiungere i Pin a un'altra vista che si trova sopra ImageView ed è anche una sottoview di <=>. L'idea qui se immaginerai è quella di avere un livello che si libra sulla mappa e non si ridimensiona ancora mostrando i pin su dove li ho tracciati.

Il pin quando aggiunto alla vista di livello non cale se <=> si ridimensiona. Tuttavia, il problema diventa quindi la posizione dei pin non corrispondente all'origine originale x / y poiché <=> ha subito una trasformazione di scala.

Fondamentalmente questa è una mappa personalizzata di un luogo con Pin. Sto cercando di far fluttuare i Pin e non ingrandire e rimpicciolire il mio ImageView, ma ricordo dove li ho posizionati quando si verifica lo zoom.

Alcuni codici:

scrollView = [[UIScrollView alloc] initWithFrame:viewRect];

scrollView.delegate = self;
scrollView.pagingEnabled = NO;
scrollView.scrollsToTop = NO;
[scrollView setBackgroundColor:[UIColor clearColor]];
scrollView.clipsToBounds = YES; // default is NO, we want to restrict drawing within our scrollview
scrollView.bounces = YES;
scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;

imageViewMap = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"image.png"]];

imageViewMap.userInteractionEnabled = YES;

viewRect = CGRectMake(0,0,imageViewMap.image.size.width,imageViewMap.image.size.height);

//viewRect = CGRectMake(0,0,2976,3928);

[scrollView addSubview:imageViewMap];

[scrollView setContentSize:CGSizeMake(viewRect.size.width, viewRect.size.height)];

iconsView = [[UIView alloc] initWithFrame:imageViewMap.frame];

[scrollView addSubview:iconsView];

Codice per aggiungere Pin in seguito in alcuni eventi.

[iconsView addSubview:pinIcon];

Sono bloccato nel provare a capire come fare in modo che i miei spilli si librino sulla mappa senza spostarsi quando si verifica la scala.

È stato utile?

Soluzione

Mi piace la tua idea di mantenere tutti i pin in una vista dedicata ai pin (iconsView), ma ho deciso di aggiungerli come sottoview di quello che hai chiamato imageViewMap.

Importa il file QuartzCore.framework nel tuo progetto.

Chiama il tuo view controller MyViewController.

#import <QuartzCore/QuartzCore.h>
@interface MyViewController : UIViewController <UIScrollViewDelegate>
@property (retain) UIScrollView *scrollView;
@property (retain) UIImageView *imageView;

// e così via

@implementation MyViewController

@synthesize scrollView;
@synthesize imageView;

Suppongo che tu abbia una vista pin o un controller vista chiamato DropPinViewController. Se stai solo usando un'immagine, può essere un UIImageView, ma i miei pin hanno etichette, quindi ho usato un xib. Il perno dovrebbe puntare al centro in basso di xib perché metteremo un punto di ancoraggio lì.

Nella viewDidLoad di MyViewController, aggiungi le visualizzazioni dei pin come sottoview di imageView. Aggiungi imageView come sottoview a scrollView. Imposta la dimensione del contenuto di scrollView.

scrollView.delegate = self;

Usa questi metodi delegati:

- (void)scrollViewDidZoom:(UIScrollView *)aScrollView
{   
    for (UIView *dropPinView in imageView.subviews) {       
    CGRect oldFrame = dropPinView.frame;
    // 0.5 means the anchor is centered on the x axis. 1 means the anchor is at the bottom of the view. If you comment out this line, the pin's center will stay where it is regardless of how much you zoom. I have it so that the bottom of the pin stays fixed. This should help user RomeoF.
   [dropPinView.layer setAnchorPoint:CGPointMake(0.5, 1)];
    dropPinView.frame = oldFrame;
    // When you zoom in on scrollView, it gets a larger zoom scale value.
    // You transform the pin by scaling it by the inverse of this value.
    dropPinView.transform = CGAffineTransformMakeScale(1.0/scrollView.zoomScale, 1.0/scrollView.zoomScale);
}

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
    return imageView;
}

Altri suggerimenti

Quindi una cosa che ho implementato che non ha risolto il mio problema ma penso che sia sulla strada giusta è da questo articolo.

Anchor a UIView

Ho la mia gerarchia di visualizzazione come segue.

UIScrollView
 - UIImageView (map image)
 - IconsView (layer image to hold icons)

Il prossimo passo che devo risolvere è mantenere i miei pin aggiunti a IconsView ancorati nello stesso punto quando UIImageView viene ingrandito e ridotto.

Ho avuto un ciclo for che ha attraversato tutti i miei pin che sono Sottovoci di UIScrollView e aggiornato le loro origini X e Y. Questo era nel metodo scrollViewDidScroll dei delegati <=>.

Il problema era che questa tecnica ha prestazioni orribili sul dispositivo poiché quando ci sono molti pin sulla mappa c'è troppa elaborazione che deve accadere.

Alcuni consigli:

1) Nell'applicazione Google Maps noterai che limita il numero di pin che tenta di visualizzare per impostazione predefinita. Mostra solo i risultati più vicini al punto centrale anche se ci sono più corrispondenze possibili.

2) È possibile nascondere brevemente i pin durante qualsiasi azione di scorrimento o pizzico in modo che l'interfaccia rimanga reattiva e li ridisegni nel momento in cui la visualizzazione dell'immagine smette di muoversi.

3) Se è necessario visualizzare un numero elevato di pin e animarli, è possibile esaminare anche l'uso di CABasicAnimations per animare contemporaneamente i pin e lo sfondo, trasformando la posizione dei pin utilizzando la stessa matematica che trasforma la scala dei fondali . Ciò potrebbe rendere più uniforme la visualizzazione diffondendo le animazioni in modo più fluido ed eseguendole a un livello abbastanza basso, ma introduce altre sfide e limitazioni.

http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/Animation_Types_Timing/Articles/PropertyAnimations.html#//apple_ref/doc/uid/TP40006672-SW1 / p>

Barney

Ho lo stesso problema e trovo l'idea di correggere manualmente la posizione del pin non molto carina. Quindi, desidero piuttosto disegnare i miei pin sulla vista restituita nella funzione delegato viewForZoomingInScrollView: e aggiornare le dimensioni della vista secondaria (marker) al termine dello zoom.

Tuttavia, mi dà fastidio che ciò sia possibile nell'app Google Maps, ma non riesco a ricrearlo.

Un'altra cosa: Qualcuno può spiegarmi l'esibizione del comportamento quando aggiungo sottoview a UIScrollView che non sono "viewForZoomingInScrollView" ..? Ad esempio:

UIImageView* marker = [[UIImageView alloc] initWithImage: myMarkerImage];
[marker setCenter: CGPointMake(250,150)];
[myScrollView addSubview: marker];

Questo sembra funzionare bene per la vista iniziale e durante la panoramica. Quando si esegue lo zoom, queste visualizzazioni secondarie non vengono ridimensionate, il che è in realtà ciò a cui stiamo mirando, ma il problema è che l'origine del riquadro UIView viene spostata attraverso la vista di scorrimento in un modo piuttosto strano. Sembra che se uno ingrandisce, marker.frame.size.origin si sposta sempre verso l'angolo in alto a sinistra (superview's (0,0)), creando l'impressione che stiamo effettivamente rimpicciolendo. Anche questo è strano, perché & Quot; zoom center & Quot; dovrebbe essere sempre al centro dello schermo, no? Bene, per ora non capisco.

urto. ;)

Grazie a David Braun. Il tuo codice funziona tranne per una riga che ho dovuto commentare. Il mio progetto prevedeva di avere un UIScrollView, quindi un UIImageView in cima che mostra una mappa, infine i pin (pulsanti) che il codice posiziona dopo aver rilevato un doppio tocco. Il tuo codice mi ha aiutato a tenere conto della scala dello zoom. Il limite era che quando pizzico per ingrandire, ogni pin non & Quot; stick & Quot; alla parte specifica del disegno in cui ho toccato due volte. Mi sono imbattuto nella soluzione quando ho commentato questa riga:

//[dropPinView.layer setAnchorPoint: CGPointMake (0.5, 1)];

Non ho la comprensione completa ma ora il mio codice funziona! Spero che altri trarranno beneficio dalla mia esperienza. Grazie David!

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