2013-03-07 12 views
5

Bazı basit nesnelerin görüntülendiği GLKit tabanlı bir uygulama var.GLKit'in -drawRect: ekran döndürme sırasında çağrılmadı

GLKView'un (-drawRect: çağrılmadığı) ekran dönüşü hariç tüm işlemler düzgün çalışıyor. Bu nedenle, döndürme projeksiyonu sırasında matris, dinamik olarak değişen ekran boyutlarına göre güncellenmez ve nesne kötü görünür (gerilir).

+0

Gölgeler veya GLKBaseEffect kullanıyor musunuz? –

+0

Her ikisinde de çalıştı: "GLKBaseEffect" ve kendi gölgelendiricilerim - aynı sonuç. '-drawRect:' animasyon bittikten sonra çağrılacak - bu yüzden herhangi bir GL renderleme (normalde oradayız) o an için askıya alınacaktır. – kpower

+1

Tamam. GLKBaseEffect'teki projectionMatrix özelliğinin buggy olduğunu düşünüyordum. Bir düşüncem var ... oryantasyon değiştikten sonra –

cevap

1

Bu, UIKit animasyonlarının nasıl çalıştığı değil. bunun yarısı this answer nasıl işlediğini ben sıralama-açıklamak ama ilgili bitleri özetlemeye çalışacağım:

  • Her şey dokulu dikdörtgendir. (Belki de CAShapeLayer gibi bazı istisnalar vardır, ancak bu çoğu zaman için geçerlidir.)
  • UIView'un özellikleri CALayer'in "model ağacı" özelliklerine bağlıdır. 'u anında değiştirir.
  • Animasyonlar, "sunum ağacı" özelliklerini başlangıç ​​değerinden geçerli model değerine göre hareket ettirerek çalışır.
  • Animasyonun başlangıç ​​değeri, varsayılan olarak önceki model değeridir. UIViewAnimationOptionBeginFromCurrentState belirtmek, geçerli sunum değerini kullanır.

vardır, tabii ki, birkaç istisna (CAShapeLayer, UIView geçişler ... tamamen başka bir şey vardır UIScrollView uyandırmasına animasyonlar kaydırma yok, dokulu rect'in daha görünüyor).

rotasyon sözde Nasıl çalışmak tek -setFrame:, her şey ortaya koydu (ve potansiyel olarak yeniden oluşturulur) olduğu almak, sonra da canlandırılabilir özellikleri animasyonlu olmasıdır. Varsayılan olarak, bu durum şeylerin yeni boyutlara yeniden işleneceği, ancak eski boyutlara sığacak şekilde uzatılacağı ve daha sonra döndürme ilerledikçe harekete geçirildiği (ve geri çekildiği) olduğu anlamına gelir.

Bu, GLKView farklı şekilde çalışabilir.GLKViewController kullanıyorsanız, döndürme animasyonu sırasında oluşturmayı bile askıya alabilir. Döndürme sırasında -setNeedsDisplay numaralı telefonu aramayı deneyebilirsiniz, ancak çerçeve zaten son değerine ayarlandığından çok yardımcı olmaz.

Muhtemelen döndürme animasyonuyla başa çıkmanın en kolay yolu, animasyonlu olmayan bir geçişi döndürülmüş çerçeveye zorlamak ve daha sonra rendererde biraz dalgalanma yapmaktır (siyah kenarlık ve durum çubuğu ayrı ayrı olsa da).

Alternatif olarak, geleneksel yöntem VC'nizi yalnızca portre yapmak ve aygıt yönlendirme bildirimlerini kendiniz yapmaktır, ancak bu büyük bir solucan olabilir (daha sonra dokunma gibi şeyleri belirleyen durum çubuğu yönlendirmesi hakkında endişelenmeniz gerekir) ofset ve klavyeli yönlendirme ve diğer VC'lere geçiş yaparken "ilginç şekilde" etkileşime girme eğilimindedir.

0

Her şeyden önce, uygulama yaşam döngüsünüzün başında bir noktada aygıt yönlendirme değişikliklerini etkinleştirdiğinizden emin olun.

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; 

Daha sonra görünümünüz başlatıldığında, böyle bir bildirim için kayıt olun.

[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(deviceOrientationDidChange:) name: UIDeviceOrientationDidChangeNotification object: nil]; 

Sonra ancak UIView ve -drawRect: deneyimi var, sizin bakış denetleyicisi -deviceOrientationDidChange: uygulamak ve ben GLKit ile herhangi bir deneyime sahip olmadığı için -setNeedsDisplay

+0

'-... DidChange' denilecek. Ve bu sefer "drawRect:" de çağrılacak (çünkü matrisleri zamana göre ve her çerçeve değişikliğinde güncelliyorum). Ancak bu süreçte değişiklik yapmam gerekiyor. – kpower

+0

Şimdi anlıyorum. Hiç bir rotasyon bilgisi almadığınızı söylüyordunuz. Görüntü denetleyici yöntemini dinleyiniz ve uygulayınız '- (void) - AnimateRotationToInterfaceOrientation: (UIInterfaceOrientation) interfaceOrientation duration: (NSTimeInterval) duration'. Süre geçiş sırasında animasyonlarınızı hesaplamanıza olanak tanır. –

+1

Evet, biliyorum. Ayrıca, '-setFrame:' görünümünü yeniden görüntüleyebilirim ve görüntü boyutu her animasyon adımında değişiklikler alır. Ancak bu değişikliklere cevap veremiyorum - projeksiyon matrisini güncelleyebiliyorum, ancak güncellemeler uygulanmayacak çünkü animasyon bitene kadar '-drawRect:' (ve ilgili GL çizimi) çağrılmayacak. – kpower

6

Bu karanlıkta bir atış olabilir diyoruz. yeniden çizmek için söz konusu görünümün contentMode değiştirmeyi deneyin:

view.contentMode = UIViewContentModeRedraw;

Bu o sınırları değiştirmek olduğunda bu içeriği yeniden çizme ihtiyacı olduğu görüşünü söyleyecektir. Aksi takdirde, UIView sadece içeriğini ölçeklemeye çalışır (contentMode için varsayılan değer UIViewContentModeScaleToFill'dur). Bunun nedeni, içeriği yeniden çizmekten çok daha kolay olması ve UIView'un olabildiğince verimli olması için tasarlanmasıdır.

+0

Ne yazık ki, bu bir GLKView üzerinde pratikte herhangi bir fark yaratıyor gibi görünmüyor. – pmdj

İlgili konular