iOS: Bagaimana seseorang menganimasikan ke batasan tata letak otomatis baru (tinggi)

123

Saya belum pernah bekerja dengan batasan tata letak otomatis sebelumnya. Saya memiliki aplikasi kecil baru yang sedang saya kerjakan dan melihat bahwa tampilan NIB secara default menggunakan tata letak otomatis. Jadi, kupikir aku akan mengambil kesempatan untuk bekerja dengan itu dan mencoba untuk mencari tahu di mana Apple akan dengan ini.

Tantangan pertama:

Saya perlu mengubah ukuran MKMapView dan saya ingin menganimasikannya ke posisi baru. Jika saya melakukan ini dengan cara yang biasa saya lakukan:

[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;
}];

... maka MKMapView akan 'kembali' ke ketinggian aslinya setiap kali tampilan saudara diperbarui (dalam kasus saya, judul UISegmentedControl sedang diperbarui [myUISegmentedControl setTitle:newTitle forSegmentAtIndex:0]).

Jadi, apa yang saya pikir saya ingin lakukan adalah mengubah kendala dari MKMapView dari yang sama dengan hight induk pandangan untuk menjadi relatif terhadap bagian atas UISegmentedControl bahwa itu meliputi:V:[MKMapView]-(16)-[UISegmentedControl]

Yang saya inginkan adalah tinggi MKMapView dipersingkat sehingga beberapa kontrol di bawah tampilan peta terungkap. Untuk melakukannya, saya pikir saya perlu mengubah batasan dari tampilan ukuran penuh tetap ke tampilan di mana bagian bawah dibatasi ke atas UISegmentedControl ... dan saya ingin itu dianimasikan saat tampilan menyusut ke ukuran baru.

Bagaimana seseorang melakukan ini?

Sunting - animasi ini tidak beranimasi meskipun bagian bawah tampilan naik langsung ke 170:

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

    }];

dan nibMapViewConstraintdisambungkan di IB ke batasan Ruang Vertikal bawah.

Meltemi
sumber
1
Saya tahu bahwa Anda dapat dengan mudah mengubah nilai konstanta batasan dalam blok [UIView animateWithDuration ..] untuk menganimasikan perubahan ketinggian. Anda perlu membuat IBOutlet untuk batasan itu dan menghubungkannya di xib Anda, atau menyimpan referensi ke sana jika Anda membuatnya dalam kode (atau mengulang semua batasan untuk mencarinya). Tidak yakin bagaimana menganimasikan perubahan relatedBy tetapi saya telah membaca bahwa Anda hanya harus mengubah konstanta dan bukan nilai lain dari batasan (untuk nilai lain, buat batasan baru).
yuf
Hmm. pikir saya bisa tetapi saya itu tidak menjiwai. Itu berubah, berhasil, dan ada di blok animasi, tetapi tidak beranimasi!?!
Meltemi
Temukan jawaban saya di sini: < stackoverflow.com/questions/12926566/… >
Meltemi
1
Jangan lupa [view layoutIfNeeded], itu masalah saya juga haha. Itu adalah pertanyaan yang sama yang memecahkan masalah saya.
yuf
Kemungkinan duplikat dari Bagaimana cara menganimasikan perubahan batasan?
Senseful

Jawaban:

179

Setelah memperbarui kendala Anda:

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

Ganti self.viewdengan referensi ke tampilan yang memuat.

Ed McManus
sumber
4
yang berfungsi untuk tampilan itu sendiri, namun tampilan yang memiliki batasan ke tampilan tersebut akan langsung bergerak. Apa yang saya lakukan? ty
dietbacon
7
Anda perlu memanggil layout jika diperlukan pada tampilan tersebut juga. namun itu tidak benar-benar berfungsi dengan baik karena ini akan menganimasikan tampilan yang disegarkan juga. Bagaimana Anda menganimasikan penyesuaian batasan hanya di tampilan lain?
ngb
3
Hati-hati: Jika menggunakan UIViewAnimationOptionBeginFromCurrentStatebatasan tata letak akan diatur SEBELUM animasi!
Robert
12
Daripada meminta layoutIfNeededsetiap pandangan tersebut, cukup hubungi[[self.view superview] layoutIfNeeded];
Flying_Banana
2
@ngb Anda perlu mengubah konstanta batasan di dalam blok animasi. Dengan cara itu batasan berubah dengan animasi dan Anda dapat terus menggunakan UIViewAnimationOptionBeginFromCurrentState.
Eran Goldin
86

Ini berfungsi untuk saya (Baik iOS7 dan iOS8 +). Klik pada batasan tata letak otomatis yang ingin Anda sesuaikan (dalam pembuat antarmuka, mis. Batasan teratas). Selanjutnya jadikan ini IBOutlet;

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

Menganimasikan ke atas;

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

Animasikan kembali ke tempat semula

    self.topConstraint.constant = 0;    
    [self.viewToAnimate setNeedsUpdateConstraints];  
    [UIView animateWithDuration:1.5 animations:^{
        [self.viewToAnimate layoutIfNeeded];
    }];
DevC
sumber
2
WOW!! Ini sebenarnya benar-benar berhasil! Jawaban ini membuka mata saya. Terima kasih banyak! - Erik
Erik van der Neut
2
@ErikvanderNeut itu untuk saya juga, senang itu membantu. Saya akan menjiwai batasan mulai sekarang daripada posisi bingkai.
DevC
jangan lewatkan untuk menambahkan: [containerView layoutIfNeeded]; Ini memastikan bahwa semua operasi tata letak yang tertunda telah diselesaikan SEBELUM blok animateWithDuration.
ingconti
11

Ada tutorial yang sangat bagus dari apple itu sendiri yang menjelaskan bagaimana menggunakan animasi dengan autolayout. Ikuti link ini dan kemudian temukan video bernama "Auto layout by example" Ini memberikan beberapa hal menarik tentang autolayout dan bagian terakhir adalah tentang bagaimana menggunakan animasi.

Glenn
sumber
3

Saya telah membuat demo kecil ini tersedia . Ini menunjukkan bagaimana batasan tata letak otomatis dapat diubah dan dianimasikan dalam contoh yang sangat sederhana. Cukup lihat DemoViewController.m .

Jens Schwarzer
sumber
1

Kebanyakan orang menggunakan autolayout untuk mengatur tata letak item pada tampilan mereka dan mengubah batasan tata letak untuk membuat animasi.

Cara mudah untuk melakukan ini tanpa banyak kode adalah membuat UIView yang ingin Anda animasikan di Storyboard, lalu membuat UIView tersembunyi di mana Anda ingin UIView diakhiri. Anda dapat menggunakan pratinjau di xcode untuk memastikan kedua UIViews berada di tempat yang Anda inginkan. Setelah itu, sembunyikan UIView penutup dan tukar batasan tata letak.

Ada podfile untuk menukar batasan tata letak yang disebut SBP jika Anda tidak ingin menulisnya sendiri.

Berikut tutorialnya .

Arjay Waran
sumber
0

Tidak perlu menggunakan lebih banyak IBOutlet referencebatasan daripada ini, Anda bisa langsung accessatau updatesudah menerapkan batasan baik yang diterapkan oleh Programmaticallyatau dari Interface Buildertampilan mana pun menggunakan KVConstraintExtensionsMasterpustaka. Perpustakaan ini juga mengelola Cumulativeperilaku NSLayoutConstraint.

Untuk menambahkan Batasan Ketinggian di containerView

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

Untuk memperbarui Batasan Ketinggian containerView dengan animasi

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

            /* for the animation */ 
            [self.containerView  updateModifyConstraintsWithAnimation:NULL];
      }
    }];
keshav vishwkarma
sumber