iOS: Yeni otomatik düzen kısıtlamasına (yükseklik) nasıl animasyon uygulanır?


123

Daha önce otomatik düzen kısıtlamalarıyla hiç çalışmadım . Üzerinde çalıştığım küçük yeni bir uygulamam var ve NIB'nin görünümlerinin varsayılan olarak otomatik düzen şeklinde olduğunu fark ettim. Yani, işten fırsatı düşündüm ile kendisine ve Apple bununla nereye anlamaya çalışın.

İlk zorluk:

Bir MKMapView'ı yeniden boyutlandırmam gerekiyor ve onu yeni konuma canlandırmak istiyorum. Bunu alıştığım şekilde yaparsam:

[UIView animateWithDuration:1.2f
     animations:^{
         CGRect theFrame = worldView.frame;
         CGRect newFrame = CGRectMake(theFrame.origin.x, theFrame.origin.y, theFrame.size.width, theFrame.size.height - 170);
         worldView.frame = newFrame;
}];

... daha sonra, bir kardeş görünümü güncellendiğinde MKMapView orijinal yüksekliğine geri dönecektir (benim durumumda bir UISegmentedControl başlığı güncelleniyor [myUISegmentedControl setTitle:newTitle forSegmentAtIndex:0]).

Peki, ne düşünüyorum ben o UISegmentedControl üstüne göreli olmasının ana görünümün yükseklik eşit olmaktan MKMapView kısıtlarını değiştirmek yapmak istediğim oldu kapsayan:V:[MKMapView]-(16)-[UISegmentedControl]

İstediğim şey, MKMapView yüksekliğinin kısaltılması, böylece harita görünümünün altındaki bazı kontrollerin ortaya çıkması. Ben Bunu yapmak için düşünüyorum ben alt bir UISegmentedControl üstüne sınırlandırılmıştır birine sabit bir tam boy görünümünden kısıtlamayı değiştirmek gerekiyor ... ve bunu yeni bir boyuta görünüm ruh doktoru olarak animasyon istiyorum.

Bu nasıl yapılır?

Düzenleme - Bu animasyon edilir değil animasyon görüntüsü alt 170 anında yukarı hareket etmez gerçi:

    [UIView animateWithDuration:1.2f
         animations:^{
             self.nibMapViewConstraint.constant = -170;

    }];

ve nibMapViewConstraintIB'de alt Dikey Uzay kısıtlamasına bağlanır.


1
Yükseklik değişikliğini canlandırmak için [UIView animateWithDuration ..] bloğundaki kısıtlamanın sabit değerini kolayca değiştirebileceğinizi biliyorum. Bu kısıtlama için bir IBOutlet oluşturmanız ve xib'inize bağlamanız veya kodda oluşturduysanız başka bir şekilde referans tutmanız (veya aramak için tüm kısıtlamaların üzerinden geçmeniz) gerekir. Değişikliklere göre nasıl canlandırılacağından emin değilim, ancak bir kısıtlamanın diğer değerlerini değil, yalnızca sabiti değiştirmeniz gerektiğini okudum (diğer değerler için yeni bir kısıt oluşturun).
yuf

Hmm. Yapabileceğimi düşündüm ama canlandırmıyorum. Başarılı bir şekilde değişiyor ve animasyon bloğunda ama animasyon yapmıyor !?!
Meltemi

Cevabımı burada buldum: < stackoverflow.com/questions/12926566/… >
Meltemi

1
[View layoutIfNeeded] 'i unutma, bu benim de sorunumdu haha. Sorunumu çözen sorunun aynısı bu.
yuf

Yanıtlar:


179

Kısıtlamanızı güncelledikten sonra:

[UIView animateWithDuration:0.5 animations:^{[self.view layoutIfNeeded];}];

self.viewİçeren görünüme bir referansla değiştirin .


4
görünümün kendisi için çalışır, ancak bu görünümle ilgili kısıtlamaları olan görünümler anında hareket eder. Ben ne yaparım? ty
dietbacon

7
bu görünümlerde de gerekirse düzeni aramanız gerekir. ancak bu, görünüm yenilemesini de canlandıracağı için gerçekten düzgün çalışmaz. Kısıtlama ayarını yalnızca diğer görünümlerde nasıl canlandırırsınız?
ngb

3
Dikkat:UIViewAnimationOptionBeginFromCurrentState Düzen kısıtlamaları kullanıyorsanız , animasyondan ÖNCE ayarlanacaktır !
Robert

12
Bunun yerine çağıran layoutIfNeededbu görünümlere her biri için, basitçe çağrı[[self.view superview] layoutIfNeeded];
Flying_Banana

2
@ngb , animasyon bloğunun içindeki kısıt sabitini değiştirmeniz gerekir . Bu şekilde kısıtlama animasyonla değişir ve kullanmaya devam edebilirsiniz UIViewAnimationOptionBeginFromCurrentState.
Eran Goldin

86

Bu benim için çalışıyor (Hem iOS7 hem de iOS8 +). Ayarlamak istediğiniz otomatik düzen kısıtlamasına tıklayın (arayüz oluşturucuda, örneğin üst sınırlama). Sonra bunu bir IBOutlet yapın;

@property (strong, nonatomic) IBOutlet NSLayoutConstraint *topConstraint;

Yukarı doğru hareket ettirin;

    self.topConstraint.constant = -100;    
    [self.viewToAnimate setNeedsUpdateConstraints]; 
    [UIView animateWithDuration:1.5 animations:^{
        [self.viewToAnimate layoutIfNeeded]; 
    }];

Orijinal yere geri dönün

    self.topConstraint.constant = 0;    
    [self.viewToAnimate setNeedsUpdateConstraints];  
    [UIView animateWithDuration:1.5 animations:^{
        [self.viewToAnimate layoutIfNeeded];
    }];

2
VAY!! Bu gerçekten işe yarıyor! Bu cevap benim için göz açıcı oldu. Çok teşekkür ederim! - Erik
Erik van der Neut

2
@ErikvanderNeut benim için de öyleydi, yardımcı olmasına sevindim. Bundan sonra çerçevelerin konumu yerine kısıtlamaları canlandıracağım.
DevC

eklemeyi unutmayın: [containerView layoutIfNeeded]; AnimateWithDuration bloğundan ÖNCE tüm bekleyen düzen işlemlerinin tamamlanmasını sağlar.
ingconti

11

Apple'ın kendisinden otomatik düzen ile animasyonun nasıl kullanılacağını açıklayan çok iyi bir öğretici var. Bu bağlantıyı izleyin ve ardından "Örnekle otomatik düzen" adlı videoyu bulun. Otomatik düzen hakkında bazı ilginç bilgiler verir ve son bölüm, animasyonun nasıl kullanılacağıyla ilgilidir.



1

Çoğu kişi, görünümlerinde öğeleri yerleştirmek için otomatik düzen kullanır ve animasyon oluşturmak için düzen kısıtlamalarını değiştirir.

Bunu çok fazla kod olmadan yapmanın kolay bir yolu, Storyboard'da canlandırmak istediğiniz UIView oluşturmak ve ardından UIView'ın bitmesini istediğiniz yerde gizli bir UIView oluşturmaktır. Her iki UIV Görünüm'ün de olmasını istediğiniz yerde olduğundan emin olmak için xcode'daki önizlemeyi kullanabilirsiniz. Bundan sonra, biten UIView'ı gizleyin ve düzen kısıtlamalarını değiştirin.

Kendiniz yazmak istemiyorsanız, SBP adı verilen takas düzen kısıtlamaları için bir pod dosyası vardır.

İşte bir eğitim .


0

IBOutlet referenceBunun yerine kısıtlamanın daha fazlasını kullanmanıza gerek yok , kitaplığı kullanarak herhangi bir görünümden veya herhangi bir görünümden doğrudan accessveya updateönceden uygulanan kısıtlama yapabilirsiniz . Bu kütüphane de yönetiyor davranışını .ProgrammaticallyInterface BuilderKVConstraintExtensionsMasterCumulativeNSLayoutConstraint

ContainerView'a Yükseklik Kısıtlaması eklemek için

 CGFloat height = 200;
 [self.containerView applyHeightConstrain:height];

ContainerView'un Yükseklik Kısıtlamasını animasyonla güncellemek için

[self.containerView accessAppliedConstraintByAttribute:NSLayoutAttributeHeight completion:^(NSLayoutConstraint *expectedConstraint){
        if (expectedConstraint) {
            expectedConstraint.constant = 100;

            /* for the animation */ 
            [self.containerView  updateModifyConstraintsWithAnimation:NULL];
      }
    }];
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.