Nasıl bir UIScrollView zoom sonra sıfırlarım?

oy
15

Bir grafikte bir iç çiziliyor var UIScrollView. Biri iri # UIViewözel bir alt sınıfını kullanarak CATiledLayerkendi katman olarak.

Ben içine ve dışına zumladığınızda UIScrollView, ben gelen grafiği döndüğünüzde grafik öyle dinamik gibi yeniden boyutlandırmak istediğiniz viewForZoomingInScrollView. Ancak, Grafik yeni yakınlaştırma düzeyinde kendisini yeniden çizer ve ben kullanıcı yakınlaştırır dahaki sefere mevcut görünümden başlar dönüşümü böylece 1x1 ölçek dönüşümü sıfırlamak istiyor. Ben Kimlik dönüşümü sıfırlarsanız scrollViewDidEndZooming, simülatörü çalışır, ancak bir atar EXC_BAD_ACCSEScihazda.

Kullanıcı yakınlaştırır dahaki sefere, en ne idiyse yakınlaştırma seviyesine sıfırlar kendisini dönüştürmeye çünkü bu bile, ya tamamen simülatörde sorunu çözmüyor, ben örneğin, 2x yakınlaştırılmış yani eğer o benziyor o 4x aniden bu. Ben zoom bitirince, doğru ölçekte biter, ama yakınlaştırma gerçek eylemi kötü görünüyor.

Yani ilk: nasıl grafik yakınlaştırma sonra 1x1 standart ölçeğinde kendisini yeniden çizmek için izin veriyoruz ve nasıl boyunca pürüzsüz zoom var?

Düzenleme: Yeni bulgular hatası gibi görünüyor [CALayer retainCount]: message sent to deallocated instance

Ben asla herhangi katmanları kendim ayırmayı kaldırma ediyorum. Önce, ben bile herhangi görünümleri veya silerek değildi. Bu hata zoom ve ayrıca döndürmek üzerine atılmış ediliyordu. Ben rotasyon ve önce nesneyi silerseniz o istisna değil, daha sonra bunu yeniden ekleyin. Bu yakınlaştırma için bir seçenek değildir.

Oluştur 15/01/2009 saat 21:16
kaynak kullanıcı
Diğer dillerde...                            


7 cevaplar

oy
41

kontrol ve istemeden bir görünüm autoreleasing veya kod içinde bir yerde katman olmadığından emin olmak için size daha ben çökmesini ile diğer yardımcı olamaz. I (parçacığı söz konusu olduğunda genellikle) simülatörü cihazında farklı autoreleases zamanlamasını kolu gördük.

Görünüm ölçekleme ile bir konudur UIScrollViewGerçi çalıştırmak. Bir tutam-yakınlaştırma Etkinlik sırasında, UIScrollViewsen belirtilen görünümü alacak viewForZoomingInScrollView:temsilci yöntemi ve bir o dönüşümü uygulanır. Dönüşümü Bu, her çerçeve yeniden çizmek için gerek kalmadan bir görüş düz ölçekleme sağlar. Yakınlaştırma operasyonun sonunda, temsilci yöntemi scrollViewDidEndZooming:withView:atScale:denilen ve size yeni ölçek faktörü adresinden görünümünde bir daha yüksek kaliteli render yapmak için bir şans vermek olacaktır. Genellikle, olmak için görünüm dönüştürmek sıfırlamak düştüğü düşünülmektedir CGAffineTransformIdentityve sonra görünümü el ile yeni boyut ölçeğinde kendisini yeniden çizmek gerekir.

Ancak bu, çünkü bir soruna neden UIScrollViewbu kadar sonraki yakınlaştırma operasyon genel ölçek faktörü ne olursa olsun içerik bakış dönüşümü ayarlayan, içerik görünümü dönüşümü izlemek için görünmüyor. El son ölçek faktöründe görünümünüzü yeniden çizilmesi ettik bu yana, ne görüyorsanız olan ölçeklendirme bileşikleri.

Çözüm olarak, ben tanımlanan aşağıdaki yöntemlerden ile benim içerik görünümü için bir UIView alt sınıfı kullanın:

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

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

burada previousScale bakış bir yüzdürme örneği değişkendir. şöyle Sonra yakınlaştırma temsilci yöntemini uygulamak:

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

Bunu yaparak, içerik görünümüne gönderilen dönüşümler ayarlanabilir görünümü son yeniden çizilmiştir hangi ölçekte dayanır. Sıkıştırarak yakınlaştırma yapıldığında, normal ayarlama atlayarak 1.0 bir ölçekte sıfırlanır dönüşümü setTransform:yöntem. Bu, bir zoom bitiminde net bir görünüm çizmek izin verirken doğru ölçeklendirme davranışı sağlamak gibi görünüyor.

GÜNCELLEME (2010/07/23): iPhone OS 3.2 ve üzeri yakınlaştırma açısından kaydırma görünümleri davranışını değişti. Şimdi, UIScrollViewbir içerik görüntüleme için geçerli ve sadece göreli ölçek faktörünü sağlamak dönüşümü kimliğini saygı göstereceğiz -scrollViewDidEndZooming:withView:atScale:. Bu nedenle, yukarıda kod UIViewalt sınıf 3.2 daha eski iPhone OS sürümlerini çalıştıran cihazlar için gereklidir.

Cevap 16/01/2009 saat 20:29
kaynak kullanıcı

oy
12

Burada önceki tüm cevaplar ve sayesinde benim çözümdür.
Uygulamak UIScrollViewDelegate yöntemleri:

- (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 UIView benim alt sınıfıdır
  • tmvScrollView - UIScrollView, çıkış
  • set maximumZoomScale ve minimumZoomScale önce
  • oluşturmak previousScale örnek değişkeni ve 1.0f için değerini ayarlamak

mükemmel benim için çalışıyor.

BR Eugene.

Cevap 02/08/2011 saat 17:33
kaynak kullanıcı

oy
5

Ben UIScrollView yakınlaştırma de nasıl çalıştığını (ve neden) ayrıntılı bir tartışma github.com/andreyvit/ScrollingMadness/ .

(Bağlantı da programlı UIScrollView nasıl yakınlaştırıp açıklamasını içerir, nasıl Foto Kütüphanesi tarzı sayfalama taklit + yakınlaştırma, yakınlaştırma büyü kapsüller örnek projesini ve ZoomScrollView sınıfını kaydırma + için.)

Alıntı:

Her kendi geçerli yakınlaştırma seviyesine sahip olabilir içeren Subview çünkü UIScrollView, bir “geçerli yakınlaştırma düzeyi” kavramını yok. Geçerli yakınlaştırma düzeyini korumak için UIScrollView hiçbir alan vardır unutmayın. Ancak birisi eğer bir subview çimdik-Büyütmek çünkü, o zaman onun CGAffineTransformIdentity dönüşümü sıfırlamak ve yeniden çimdik, sen subview önceki yakınlaştırma düzeyi restore edilmiştir göreceksiniz, o yakınlaştırma düzeyi depolayan biliyoruz.

Eğer sökme bakarsak, bu (iç UIGestureInfo nesne _gestureInfo alanıyla işaretlenen) kendi yakınlaştırma düzeyini depolayan UIView olduğunu. Aynı zamanda gibi güzel belgesiz yöntemler kümesine sahiptir zoomScaleve setZoomScale:animated:. (Eğer Zihin, aynı zamanda dönme ilgili yöntemlerin bir grup var, belki rotasyon jest gün yakında desteklemek alıyoruz.)

biz sadece yakınlaştırma için yeni bir UIView oluşturmak ve çocuk olarak bizim gerçek yakınlaştırılabilen görünümü eklemek Ancak, biz her zaman yakınlaştırma düzeyinde 1.0 ile başlayacak. programatik yakınlaştırma Benim uygulanması bu hüner dayanmaktadır.

Cevap 08/05/2009 saat 00:04
kaynak kullanıcı

oy
4

Ben sadece bunu Büyütmek zaman ayırmanın alana kadar, Scrollview sonraki sefer için aynı yakınlaştırma ölçeğini yaşadığından dolayı, zum ölçeğini varsayılan yüke sıfırlamak için arıyordu.

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

oyunu değiştirdi.

Cevap 03/06/2015 saat 06:53
kaynak kullanıcı

oy
3

Aşağıdaki gibi iOS 3.2 ve 4.0 için uygun ve daha sonra Oldukça güvenilir yaklaşım vardır. Herhangi istenilen ölçekteki sizin ölçeklenebilir görünümü (kaydırma görünümünde baş Subview) tedarik etmeye hazır olmalıdır. Sonra içinde scrollViewDidEndZooming:size bu bakış bulanık ölçek dönüştürülmüş sürümünü kaldıracak ve yeni ölçekli çizilmiş yeni görünümü ile değiştirin.

İhtiyacın olacak:

  • Önceki ölçek muhafaza edilmesi için bir ivar; diyelim oldScale

  • Her ikisi, ölçeklenebilir görünümü tanımlamanın bir yolu, viewForZoomingInScrollView:ve için scrollViewDidEndZooming:; Burada, bir etiketi uygulamak için gidiyorum (999)

  • Ölçeklenebilir bir görünüm oluşturur bunu etiketler ve kaydırma görünümünde (burada ben arayacağım içine ekler bir yöntem addNewScalableViewAtScale:). O ölçeğine göre her şeyi yapmak gerektiğini unutmayın - bu görünümü ve subviews veya çizimi boyutları ve maç için kaydırma görünümün contentSize boyutları.

  • minimumZoomScale ve maximumZoomScale için Sabitler. Bunlar detaylı geniş sürümü tarafından ölçekli görünümünü değiştirdiğinizde sistem, geçerli ölçek 1 olduğunu düşünecek çünkü ihtiyaç vardır, bu yüzden kullanıcı geri aşağı ölçeğinde izin içine aptal gerekir.

Çok iyi o zaman. Eğer kaydırma görünümünü oluştururken, ölçek 1,0 olarak ölçeklenebilir bir görünüm yerleştirin. Bu Gözlerinde farklı olabilir viewDidLoad, örneğin ( svkaydırma görünümüdür):

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

Ardından içinde scrollViewDidEndZooming:aynı şeyi, ama ölçek değişikliği telafi:

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;
Cevap 12/11/2010 saat 06:33
kaynak kullanıcı

oy
2

Brad tarafından sağlanan çözüm olsa bir sorunu vardır unutmayın: programlı yakınlaştırma devam edersek, (çifte musluk olayı diyelim) ve manuel kullanıcı (parmaklarını birbirinden uzaklaştırma) uzaklaştırmak izin bir süre sonra gerçek ölçek ve ölçek arasındaki fark UIScrollView çok büyük büyüyecek izleme, böylece previousScaleen sonunda bir öngörülemeyen davranışlara float'in hassasiyet dışında bir noktada sonbaharda de irade sonuçlanacak

Cevap 28/07/2009 saat 04:43
kaynak kullanıcı

oy
0

Swift 4. * ve Xcode 9.3

başlangıçtaki eyalet için 0'a scrollview zum ölçeğini ayarlamak, scrollview sıfırlar.

self.scrollView.setZoomScale(0.0, animated: true)
Cevap 29/06/2018 saat 05:21
kaynak kullanıcı

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