Vra

Ek het 'n Grafiek binne 'n UIScrollView getrek. Dit is een groot UIView met behulp van 'n persoonlike subklas van CATiledLayer as sy laag.

Wanneer ek in en uit die UIScrollView zoom, ek wil die grafiek om die grootte van dinamiese soos dit doen wanneer ek terugkeer die grafiek van viewForZoomingInScrollView. Maar die Graph getekend self by die nuwe zoom vlak, en ek wil weer die transformasie skaal om 1x1 sodat die volgende keer die gebruiker zoomt, die begin transformeer van die huidige aansig. As ek weer die transformasie na identiteit in scrollViewDidEndZooming, dit werk in die simulator, maar gooi 'n EXC_BAD_ACCSES op die toestel.

Dit beteken nie eens op te los die probleem geheel en al op die simulator nie, want die volgende keer die gebruiker zoomt, die transformasie Resets self aan enige zoom vlak dit was op, en so dit lyk, of ek hou zoomde om 2x, byvoorbeeld, is dit skielik by 4x. Toe ek klaar is met die zoom, dit eindig op die korrekte skaal, maar die werklike daad van inzoomen lyk sleg.

So eerste: hoe kan ek toelaat dat die grafiek om self teken by die standaard skaal van 1x1 na inzoomen, en hoe moet ek 'n gladde zoom regdeur

?

Edit: Nuwe bevindings Die fout blyk te wees "[CALayer retainCount]: message sent to deallocated instance"

Ek nooit deallocating enige lae myself. Voordat ek kon nie eens die verwydering van enige sienings of enigiets. Hierdie fout is gegooi op zoom en ook op te draai. daarna as ek die voorwerp voor rotasie en verwyder re-voeg dit, beteken dit nie die uitsondering gooi. Dit is nie 'n opsie vir inzoomen.

Was dit nuttig?

Oplossing

Ek kan jou nie help met die gekraak, behalwe vir jou sê om te kyk en seker te maak dat jy nie per ongeluk autoreleasing die oog of laag iewers binne jou kode. Ek het gesien die simulator hanteer die tydsberekening van autoreleases anders as op die toestel (meestal wanneer drade is betrokke).

Die vertoning skaal is 'n probleem met UIScrollView Ek het loop in, al is. Tydens 'n knippie inzoomen geval, sal UIScrollView die oog wat u verskaf in die viewForZoomingInScrollView: afgevaardigde metode neem en toe te pas 'n te transformeer na dit. Dit transformeer bied 'n gladde skalering van die oog sonder om dit te teken elke raam. Aan die einde van die zoom operasie, sal u afgevaardigde metode scrollViewDidEndZooming:withView:atScale: genoem word en gee jou 'n kans om 'n meer hoë-gehalte lewering van jou siening te doen by die nuwe skaal faktor. Oor die algemeen, is dit voorgestel dat jy weer die transformasie van jou siening te CGAffineTransformIdentity en dan jou oog self met die hand teken by die nuwe grootte skaal.

Maar dit veroorsaak 'n probleem omdat UIScrollView Dit lyk nie asof monitor die inhoud siening te omskep, so op die volgende zoom operasie dit stel die transformasie van die inhoud oog op alles wat die algehele skaal faktor is. Aangesien jy met die hand jou oog het teruggeteken by die laaste skaalfaktor, dit verbindings die skaal, en dit is wat jy sien.

As 'n tydelike oplossing, ek gebruik 'n UIView subklas vir my inhoud vertoning met die volgende metodes gedefinieer:

- (void)setTransformWithoutScaling:(CGAffineTransform)newTransform;
{
    [super setTransform:newTransform];
}

- (void)setTransform:(CGAffineTransform)newValue;
{
    [super setTransform:CGAffineTransformScale(newValue, 1.0f / previousScale, 1.0f / previousScale)];
}

waar previousScale is 'n float byvoorbeeld veranderlike van die oog. Ek implementeer dan die soom afgevaardigde metode soos volg:

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale;
{
    [contentView setTransformWithoutScaling:CGAffineTransformIdentity];
// Code to manually redraw view at new scale here
    contentView.previousScale = scale;
    scrollView.contentSize = contentView.frame.size;
}

Deur dit te doen, die transforms gestuur om die inhoud siening is aangepas op grond van die skaal waarteen die oog was verlede OORGETEKEN. Wanneer die knippie-inzoomen gedoen word, die transformasie is herstel na 'n skaal van 1,0 deur omleiding die aanpassing in die normale setTransform: metode. Dit lyk na die korrekte skaal gedrag te voorsien terwyl die verhuring van jou 'n skerp oog te trek by die voltooiing van 'n zoom.

UPDATE (2010/07/23): iPhone OS 3.2 en hoër het die gedrag van menings boek verander met betrekking tot die soom. Nou, 'n UIScrollView sal die identiteit respekteer transformeer jy aansoek doen om 'n inhoud siening en net die relatiewe skaal faktor in -scrollViewDidEndZooming:withView:atScale:. Daarom is die bogenoemde kode vir 'n UIView subklas is net wat nodig is vir toestelle loop iPhone OS weergawes ouer as 3.2.

Ander wenke

Baie dankie aan al die vorige antwoorde, en hier is my oplossing.
Implementeer UIScrollViewDelegate metodes:

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

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
{
    CGPoint contentOffset = [tmvScrollView contentOffset];   
    CGSize  contentSize   = [tmvScrollView contentSize];
     CGSize  containerSize = [tmv frame].size;

    tmvScrollView.maximumZoomScale = tmvScrollView.maximumZoomScale / scale;
    tmvScrollView.minimumZoomScale = tmvScrollView.minimumZoomScale / scale;

    previousScale *= scale;

    [tmvScrollView setZoomScale:1.0f];

    [tmvScrollView setContentOffset:contentOffset];
    [tmvScrollView setContentSize:contentSize];
    [tmv setFrame:CGRectMake(0, 0, containerSize.width, containerSize.height)];  

    [tmv reloadData];
}
  • TMV is my subklas van UIView
  • tmvScrollView - uitlaat om UIScrollView
  • gestel maximumZoomScale en minimumZoomScale voor
  • skep previousScale byvoorbeeld veranderlike en stel die waarde daarvan om 1.0f

Werk vir my perfek.

BR, Eugene.

Ek was net op soek na herstel op load standaard zoom skaal, want toe ek zoom dit, scrollview is met dieselfde zoom skaal vir volgende keer totdat dit kry deallocated.

-(void) viewWillAppear:(BOOL)animated {
      [self.scrollView setZoomScale:1.0f];
}

verander die spel.

Ek het 'n volledige bespreking van hoe (en hoekom) UIScrollView inzoomen werke by github.com/andreyvit/ScrollingMadness/ .

(Die skakel bevat ook 'n beskrywing van hoe om programmaties zoom UIScrollView, hoe om te leer, Foto Biblioteek-styl blaai + inzoomen + blaai, 'n voorbeeld projek en ZoomScrollView klas wat 'n paar van die inzoomen magic saamvat.)

Quote:

UIScrollView het nie 'n idee van 'n "huidige zoom vlak", want elke subview dit bevat dalk sy eie huidige zoom vlak. Let daarop dat daar geen veld in UIScrollView om die huidige zoom vlak te hou. Maar ons weet dat iemand winkels wat zoom vlak, want as jy knyp-zoom n subview, dan weer sy transformeer na CGAffineTransformIdentity, en dan knyp weer, sal jy agterkom dat die vorige zoom vlak van die subview herstel.

Inderdaad, as jy kyk na die demontage, dit is UIView wat sy eie zoom vlak Stores (binne UIGestureInfo voorwerp het gewys op die veld _gestureInfo). Dit het ook 'n stel van lekker ongedokumenteerde metodes soos zoomScale en setZoomScale:animated:. (Let wel, dit het ook 'n klomp van-rotasie-verwante metodes, miskien is ons om rotasie gebaar ondersteun eendag gou.)

As ons egter 'n nuwe UIView skep net vir inzoomen en voeg ons werklike zoomable oog as sy kind, ons sal altyd begin met zoom vlak 1.0. My implementering van programmatiese inzoomen is gebaseer op hierdie truuk.

'n redelik betroubare benadering, wat geskik is vir iOS 3.2 en 4.0 and later, is soos volg. Jy moet bereid wees om jou skaalbare oog (die hoof subview van die boek die lig) te voorsien in enige versoek skaal wees. Dan in scrollViewDidEndZooming: jy sal die dowwe-skaal omskep weergawe van hierdie siening te verwyder en vervang dit met 'n nuwe siening gevestig op die nuwe skaal.

Jy benodig:

  • 'n Ivar vir die handhawing van die vorige skaal; kom ons noem dit oldScale

  • 'n manier van die identifisering van die skaalbare oog, beide vir viewForZoomingInScrollView: en vir scrollViewDidEndZooming:; hier, ek gaan 'n tag toe te pas (999)

  • 'n metode wat die skaal baar oog, etikette wat dit skep, en voeg dit in die boek die lig (hier is ek sal dit noem addNewScalableViewAtScale:). Onthou, dit moet alles doen volgens skaal -. Dit groottes die oog en sy subviews of tekening en groottes contentSize die boek se siening aan te pas

  • Konstantes vir die minimumZoomScale en maximumZoomScale. Dit is nodig omdat wanneer ons die skaal oog vervang deur die gedetailleerde groter weergawe, die stelsel aan die gang om te dink dat die huidige skaal is 1, so ons moet dit flous om sodat die gebruiker die oog terug af te skaal.

Goed dan. Wanneer jy die boek die lig te skep, jy voeg die skaalbare oog op skaal 1.0. Hierdie dalk wees in jou viewDidLoad, byvoorbeeld (sv is die boek die lig):

[self addNewScalableViewAtScale: 1.0];
sv.minimumZoomScale = MIN;
sv.maximumZoomScale = MAX;
self->oldScale = 1.0;
sv.delegate = self;

Toe ek in jou scrollViewDidEndZooming: doen jy dieselfde ding, maar vergoed vir die verandering in skaal:

UIView* v = [sv viewWithTag:999];
[v removeFromSuperview];
CGFloat newscale = scale * self->oldScale;
self->oldScale = newscale;
[self addNewScalableViewAtScale:newscale];
sv.minimumZoomScale = MIN / newscale;
sv.maximumZoomScale = MAX / newscale;

Let daarop dat die inligting wat deur Brad oplossing het een probleem is egter: as jy hou programmaties inzoomen (kom ons sê op dubbel tap gebeurtenis) en laat gebruiker met die hand (knippie-out) zoom uit, na 'n tyd die verskil tussen die ware omvang en die skaal UIScrollView is die dop sal te groot groei, so die previousScale sal op 'n stadium val uit presisie float se wat sal uiteindelik lei tot 'n onvoorspelbare gedrag

Swift 4. * en Xcode 9.3

Die opstel scrollView zoom skaal tot 0 sal jou scrollView herstel na dit aanvanklike toestand.

self.scrollView.setZoomScale(0.0, animated: true)
Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top