Pergunta

Eu tenho um UIScrollView que tem uma UIImageView. Quero mostrar pinos nesta imageView. Quando eu adicionar pinos como subviews do ImageView, tudo é grande, exceto para quando você aumenta o zoom a transformação escala acontece nos pinos também. Eu não quero que este comportamento e quero que meus pinos para permanecer o mesmo.

Então eu optar por adicionar os pinos para outra vista que fica no topo do ImageView e também é um subexibição do UIScrollView. A idéia aqui se você vai imaginar é ter uma camada que paira sobre o mapa e não escala ainda mostram pinos de mais de onde eu traçar-los.

O pino quando adicionado à camada de vista não se cale as escalas ImageView. No entanto, a questão torna-se então a posição dos pinos não coincide com o original origem x / y como o ImageView teve transformar uma escala.

Basicamente, este é um mapa personalizado de um lugar com Pins. Eu estou tentando ter os pinos flutuar sobre e não zoom in e out sobre minha ImageView ainda me lembro onde coloquei-los quando o zoom acontece.

Alguns código:

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

código para adicionar Pin, mais tarde, algum evento.

[iconsView addSubview:pinIcon];

Eu estou preso ao tentar figura tp para fora como para obter os meus pinos de pairar no mapa sem se mover quando a escala acontece.

Foi útil?

Solução

Eu gosto da sua ideia de manter todos os pinos em uma exibição dedicada aos pinos (iconsView), mas eu decidi apenas adicioná-los como subviews do que você chamou imageViewMap.

Importar o arquivo QuartzCore.framework ao seu projeto.

Ligue para o seu MyViewController controlador de vista.

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

// e assim por diante

@implementation MyViewController

@synthesize scrollView;
@synthesize imageView;

Eu vou assumir que você tem uma visão pino ou um controlador de vista chamado DropPinViewController. Se você estiver usando apenas uma imagem, que pode ser um UIImageView, mas meus pinos têm rótulos, então eu usei um xib. O pino deve apontar para o centro inferior da xib porque nós estamos indo para colocar um ponto lá âncora.

Em seu viewDidLoad do seu MyViewController, adicionar os seus pontos de vista pin como subviews de imageView. Adicione o imageView como um subexibição ao scrollView. Defina o tamanho do conteúdo de scrollView.

scrollView.delegate = self;

Utilize estes métodos de delegado:

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

Outras dicas

Assim, uma coisa que eu implementaram que não tenha resolvido o meu problema, mas eu acho que é o caminho certo é a partir deste artigo.

Anchor um UIView

Eu tenho a minha hierarquia de vista da seguinte forma.

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

O próximo passo que eu preciso para resolver é manter meus pinos adicionado ao IconsView ancorada no mesmo local quando o UIImageView está sendo ampliada ou reduzida.

Eu tinha um loop for que passou por todos os meus pinos que são subvisualizações de IconsView e atualiza o seu Origem X e Y. Isso foi em método UIScrollView das delegados scrollViewDidScroll.

O problema era esta técnica tem um desempenho horrível no dispositivo como quando há um grande número de pinos no mapa há muito processamento que precisa acontecer.

Algumas recomendações:

1) Você vai notar na aplicação Google Maps que limita o número de pinos que ele tenta mostrar por padrão. Ele só vai mostrar os resultados mais próximos do ponto central, mesmo se houver mais combinações possíveis.

2) Você podia esconder brevemente os pinos durante qualquer deslocamento ou beliscar ação para que a interface continua a responder e redesenhá-los no momento da visualização da imagem pára de se mover.

3) Se você deve exibir um grande número de pinos e animá-los, você também pode olhar em usar CABasicAnimations para animar os pinos e o pano de fundo, ao mesmo tempo, transformando a posição pinos usando a mesma matemática que escala transforma os cenários . Isso pode suavizar a exibição espalhando animações de forma mais suave e executá-los em um nível bastante baixo, mas introduz outros desafios e limitações.

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

Barney

Eu tenho o mesmo problema e eu acho a idéia de corrigir manualmente a localização do pino não muito bonita. Então, eu prefiro chamar meus pinos para a exibição retornado na função viewForZoomingInScrollView: delegado e atualizar o subexibição (marcadores) tamanho depois de ter aproximado foi concluída.

No entanto, isso me aborrece que isso é possível no Google Maps App, mas não posso recriá-lo.

Mais uma coisa: Alguém pode explicar-me o exhibitet comportamento quando eu adiciono subviews à UIScrollView que não são o 'viewForZoomingInScrollView' ..? Por exemplo:

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

Este parece funcionar bem para a vista inicial e ao deslocar. Quando o zoom, essas subviews não são redimensionadas, que na verdade é o que estamos buscando, mas o problema é que a origem quadro UIView é movido através da exibição da rolagem de alguma forma bastante estranha. Parece que, se um zooms em, a marker.frame.size.origin está sempre se movendo em direção ao canto superior esquerdo (do superview (0,0)), criando a impressão de que estamos realmente zoom out. Este também é estranho, porque o "centro zoom" deve estar sempre no centro da tela, não? Bem, eu não entendo por agora.

galo. ;)

Graças a David Braun. Seu código funciona, exceto por uma linha que eu tinha que comentar. Meu projeto envolveu a ter um UIScrollView, em seguida, um UIImageView no topo que mostra um mapa, em seguida, por último, alfinetes (botões) que as posições de código após a detecção de um gesto de tocar duas vezes. Seu código me ajudou a explicar a escala de zoom. A limitação embora foi que quando eu beliscar para ampliar, cada pino não "pau" para a parte específica do desenho onde eu dupla aproveitado. Eu tropecei na solução quando eu comentei esta linha:

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

Eu não tenho a compreensão completa, mas meu código agora funciona! Espero que outros se beneficiar da minha experiência. Graças David!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top