Saya baru-baru ini bergumul dengan kesalahan tata letak otomatis saat menyembunyikan file UIStackView. Daripada melakukan banyak pembukuan dan membungkus tumpukan UIViews, saya memilih untuk membuat outlet untuk saya parentStackViewdan outlet untuk anak-anak yang ingin saya sembunyikan / perlihatkan.
@IBOutlet weak var parentStackView: UIStackView!
@IBOutlet var stackViewNumber1: UIStackView!
@IBOutlet var stackViewNumber2: UIStackView!
Di storyboard, inilah tampilan parentStack saya:

Ini memiliki 4 anak dan masing-masing anak memiliki banyak tampilan tumpukan di dalamnya. Saat Anda menyembunyikan tampilan tumpukan, jika ada elemen UI yang juga merupakan tampilan tumpukan, Anda akan melihat aliran kesalahan tata letak otomatis. Daripada menyembunyikan, saya memilih untuk menghapusnya.
Dalam contoh saya, parentStackViewsberisi array dari 4 elemen: Top Stack View, StackViewNumber1, Stack View Number 2, dan Stop Button. Indeksnya arrangedSubviewsmasing-masing adalah 0, 1, 2, dan 3. Ketika saya ingin menyembunyikannya, saya cukup menghapusnya dari parentStackView's arrangedSubviewsarray. Karena tidak lemah, itu tetap ada di memori dan Anda bisa meletakkannya kembali ke indeks yang Anda inginkan nanti. Saya tidak menginisialisasi ulang, jadi itu hanya hang sampai dibutuhkan, tapi tidak mengasapi memori.
Jadi pada dasarnya, Anda dapat ...
1) Seret IBOutlets untuk tumpukan orang tua Anda dan anak-anak yang ingin Anda sembunyikan / tampilkan ke storyboard.
2) Saat Anda ingin menyembunyikannya, hapus tumpukan yang ingin Anda sembunyikan dari parentStackView's arrangedSubviewsarray.
3) Telepon self.view.layoutIfNeeded()dengan UIView.animateWithDuration.
Perhatikan bahwa dua stackView terakhir tidak weak. Anda harus menyimpannya saat Anda memperlihatkannya.
Katakanlah saya ingin menyembunyikan stackViewNumber2:
parentStackView.removeArrangedSubview(stackViewNumber2)
stackViewNumber2.removeFromSuperview()
Kemudian animasikan:
UIView.animate(withDuration: 0.25,
delay: 0,
usingSpringWithDamping: 2.0,
initialSpringVelocity: 10.0,
options: [.curveEaseOut],
animations: {
self.view.layoutIfNeeded()
},
completion: nil)
Jika Anda ingin "memperlihatkan" stackViewNumber2nanti, Anda dapat memasukkannya ke dalam parentStackView arrangedSubViewsindeks yang diinginkan dan menganimasikan pembaruan.
parentStackView.removeArrangedSubview(stackViewNumber1)
stackViewNumber1.removeFromSuperview()
parentStackView.insertArrangedSubview(stackViewNumber2, at: 1)
UIView.animate(withDuration: 0.25,
delay: 0,
usingSpringWithDamping: 2.0,
initialSpringVelocity: 10.0,
options: [.curveEaseOut],
animations: {
self.view.layoutIfNeeded()
},
completion: nil)
Saya menemukan itu jauh lebih mudah daripada melakukan pembukuan pada kendala, mengutak-atik prioritas, dll.
Jika Anda memiliki sesuatu yang ingin disembunyikan secara default, Anda bisa meletakkannya di storyboard dan menghapusnya viewDidLoaddan memperbarui tanpa menggunakan animasi view.layoutIfNeeded().