Hogyan töröljem után UIScrollView zoom?

szavazat
15

Van egy Graph állítanak belsejében UIScrollView. Ez az egyik nagy UIViewegy egyéni alosztálya CATiledLayer, mint a réteg.

Amikor a nagyítás és kicsinyítés a UIScrollView, szeretnék a diagram átméretezése dinamikusan, mint ez, amikor visszatérek a grafikonon viewForZoomingInScrollView. Azonban a Graph újra rajzolja maga az új nagyítási szinten, és azt kívánja állítani a transzformációs skála 1x1 úgy, hogy a következő alkalommal a felhasználó nagyít, a transzformáció indul az aktuális nézetet. Ha beállítom a transzformációt, identitás scrollViewDidEndZooming, működik a szimulátorban, hanem dob egy EXC_BAD_ACCSESa készüléken.

Ez még csak nem is tudja megoldani a problémát teljes egészében a szimulátor sem, mert a következő alkalommal, amikor a felhasználó nagyít, a transzformáció alaphelyzetbe állítja magát, hogy bármilyen nagyítási szinten ez volt, és úgy néz ki mint ha én nagyított 2x például ez hirtelen 4x. Amikor befejeztük a zoom, hogy végül a megfelelő méretű, de a tényleges cselekmény nagyítás néz ki rosszul.

Tehát az első: hogyan teszi lehetővé a grafikonon, hogy dolgozza át magát a standard méretű 1x1 után nagyítás, és hogyan lehet egy sima zoom egész?

Edit: Új megállapítások A hiba úgy tűnik, hogy „ [CALayer retainCount]: message sent to deallocated instance

Én soha nem deallocating minden réteget magam. Azelőtt nem is törli bármely véleményre vagy semmit. Ezt a hibát dobnak a nagyítás és forgatás is. Ha törlöm a tárgy forgatás előtt, és újra hozzá ezután, hogy nem dobja a kivétel. Ez nem egy lehetőség a nagyítás.

A kérdést 15/01/2009 21:16
a forrás felhasználó
Más nyelveken...                            


7 válasz

szavazat
41

Nem tudok segíteni Önnek az összeomlást, kivéve mondani, hogy ellenőrizze, és győződjön meg róla, nem véletlenül autoreleasing céljából vagy réteg valahol a kódban. Láttam a szimulátor kezelni az időzítés autoreleases másképp, mint a készülék (leggyakrabban, amikor a menetek részt).

A kilátás méretezés olyan kérdés, UIScrollViewamit befut, mégis. Közben egy csipet-zoom esetben UIScrollViewmegteszi a nézetben meghatározott viewForZoomingInScrollView:megbízottja eljárás és alkalmazza a transzformációs rá. Ez átalakítja egy sima méretezés a nézet, anélkül, hogy dolgozza át azt minden egyes képkocka. Végén a nagyítás, a felhatalmazott eljárás scrollViewDidEndZooming:withView:atScale:fogják hívni, és kapsz egy esélyt, hogy egy kiváló minőségű renderelés a véleménye az új léptékét. Általában ez azt, hogy állítsa vissza a transzformáció a céllal, hogy legyen CGAffineTransformIdentity, és ezt követően a nézet kézi dolgozza át magát az új méretet.

Azonban ez okozza a problémát, mert UIScrollViewúgy tűnik, nem ellenőrzi a tartalom nézet átalakítani, így a következő zoom művelet beállítja a transzformációs tartalom érdekében bármilyen általános skálafaktorból. Mivel már kézzel rajzolni a nézet az utolsó lépték tényezőt, akkor vegyületek a méretezés, ami, mit lát.

Megoldásként azt használja a UIView alosztálya a saját tartalmi véli az alábbi módszerekkel határozták meg:

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

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

ahol previousScale egy float például a változó a nézetet. Aztán végre a nagyítási küldött eljárás az alábbiak szerint:

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

Ezzel, a transzformáció küldeni a tartalom nézet alapján állítottuk be a skála, amelyen a véleményen volt utolsó rajzolni. Amikor a csipet-zoom történik, a transzformáció visszaáll skálán 1,0 megkerülésével a kiigazítás a szokásos setTransform:eljárás. Ez úgy tűnik, hogy a helyes méretarány viselkedését, miközben hagyta húzol egy éles néző befejezésekor a zoom.

UPDATE (2010/07/23): iPhone OS 3.2 vagy újabb megváltoztatta a viselkedését scroll nézetek tekintetében nagyítással. Most, egy UIScrollViewtiszteletben fogja tartani a személyazonosságát átalakítani, akkor alkalmazni kell a tartalom megtekintése és csupán a relatív skálán tényező -scrollViewDidEndZooming:withView:atScale:. Ezért a fenti kódot egy UIViewalosztály csak szükséges eszközökön futó iPhone OS változat régebbi, mint a 3.2.

Válaszolt 16/01/2009 20:29
a forrás felhasználó

szavazat
12

Köszönet az összes korábbi válaszokat, és itt van a megoldás.
Végrehajtása UIScrollViewDelegate módszerek:

- (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 én alosztálya UIView
  • tmvScrollView - kivezető UIScrollView
  • meghatározott maximumZoomScale és minimumZoomScale előtt
  • létrehozásához previousScale például a változó és az értéke legyen 1.0f

Nekem működik tökéletesen.

BR, Eugene.

Válaszolt 02/08/2011 17:33
a forrás felhasználó

szavazat
5

Van egy részletes tárgyalása, hogyan (és miért) UIScrollView nagyítás dolgozik github.com/andreyvit/ScrollingMadness/ .

(A link is tartalmaz egy leírást, hogyan kell programozottan zoom UIScrollView, hogyan versenyez Photo Library-style lapozás + nagyítás + görgetés példát projekt ZoomScrollView osztály, amely magában néhány nagyítási varázslat.)

Idézet:

UIScrollView nincs fogalma a „jelenlegi nagyítási szinten”, mert minden egyes subview tartalmaz lehet saját aktuális nagyítási szintre. Vegyük észre, hogy nincs a területen a UIScrollView tartani az aktuális nagyítási szintre. Azonban tudjuk, hogy valaki tárolja, hogy a nagyítási szinten, mert ha csipetnyi-zoom a subview, majd állítsa be a transzformációt CGAffineTransformIdentity, majd csipetnyi újra, akkor veszi észre, hogy az előző nagyítási szint subview helyreállt.

Valóban, ha megnézi a szétszerelési, akkor UIView, amely tárolja a saját nagyítási szinten (belső UIGestureInfo objektum által hivatkozott _gestureInfo mező). Ez is egy sor szép dokumentált módszerek, mint a zoomScaleés setZoomScale:animated:. (Ugyan ez is egy csomó forgatás kapcsolatos eljárások, talán mi vagyunk egyre forgatás mozdulatot támogat néhány nap hamarosan.)

Azonban, ha egy új UIView csak a nagyítás, és add meg a valós nagyítható nézet, mint a gyermek, akkor mindig kezdeni a nagyítási szinten 1,0. Saját végrehajtása programadó nagyítás alapján ezt a trükköt.

Válaszolt 08/05/2009 00:04
a forrás felhasználó

szavazat
4

Csak néztem, hogy állítsa vissza a terhelés az alapértelmezett nagyítási szinten, mert amikor kinagyíthatod, scrollview is, amelyek ugyanazt a zoom mértéke a következő alkalommal, amíg nem lesz felszabadítva.

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

Megváltozott a játékot.

Válaszolt 03/06/2015 06:53
a forrás felhasználó

szavazat
3

Viszonylag megbízható megközelítés indokolt iOS 3.2 és 4.0 és újabb, a következő. Meg kell készülnie, hogy a kínálat a skálázható nézet (a legfőbb subview a scroll nézetet) a kért méretben. Majd scrollViewDidEndZooming:akkor távolítsa el a homályos skála transzformált változata ezt a nézetet, és helyette egy új nézet húzott az új skála.

Szükséged lesz:

  • Egy Ivar fenntartásához az előző skála; nevezzük oldScale

  • A azonosításának módját skálázható nézetben, mind a viewForZoomingInScrollView:és scrollViewDidEndZooming:; Itt fogok alkalmazni egy címke (999)

  • Eljárás, amely létrehozza a skálázható véli, jeladók, és beilleszti azt a tekercset nézet (itt fogom nevezni addNewScalableViewAtScale:). Ne felejtsük el, hogy mindent meg kell tenni szerinti skála - a méretek a nézetet, és annak subviews vagy rajz, és méretben a tekercset nézet contentSize egyeztetni.

  • Állandói minimumZoomScale és maximumZoomScale. Ezekre szükség, mert ha cserélni a skálázott véli, hogy a részletes nagyobb változatát, a rendszer fogja gondolni, hogy a jelenlegi skála 1, így kell becsapni be, amely lehetővé teszi a felhasználó számára, hogy a skála nézet vissza.

Jól majd. Amikor létrehozza a scroll nézetben helyezze a skálázható kilátás skálán 1,0. Ez lehet az viewDidLoad, például ( sva scroll nézet):

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

Ezután a scrollViewDidEndZooming:te ugyanaz a dolog, de kompenzálja a változás skála:

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;
Válaszolt 12/11/2010 06:33
a forrás felhasználó

szavazat
2

Megjegyezzük, hogy a megoldás a Brad van egy probléma mégis: ha folyamatosan programozottan nagyítás (mondjuk a dupla csap esetén), és hagyja, hogy a felhasználó manuálisan (csipet-out) kicsinyítés, egy idő után a különbség a valós mértékét, és a skála UIScrollView olyan nyomkövető növekedni fog túl nagy, így a previousScaleszándék egy bizonyos ponton esik ki az úszó precíziós amelyek hatására végül kiszámíthatatlan viselkedése

Válaszolt 28/07/2009 04:43
a forrás felhasználó

szavazat
0

Swift 4 * és Xcode 9.3

Beállítás scrollView zoom skála 0 visszaállítja a scrollView hogy ez a kezdeti állapot.

self.scrollView.setZoomScale(0.0, animated: true)
Válaszolt 29/06/2018 05:21
a forrás felhasználó

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more