Saya memiliki tampilan khusus yang tidak menerima layoutSubview
pesan selama animasi.
Saya memiliki pandangan yang memenuhi layar. Ini memiliki subview khusus di bagian bawah layar yang mengubah ukuran dengan benar di Interface Builder jika saya mengubah ketinggian bilah navigasi. layoutSubviews
dipanggil saat tampilan dibuat, tetapi tidak pernah lagi. Subview saya diatur dengan benar. Jika saya menonaktifkan bilah status panggilan masuk, subview itu layoutSubviews
tidak dipanggil sama sekali, meskipun tampilan utama memang menganimasikan ukurannya.
Dalam keadaan apa layoutSubviews
sebenarnya disebut?
Saya telah autoresizesSubviews
menetapkan untuk NO
untuk tampilan kustom saya. Dan di Interface Builder saya memiliki struts atas dan bawah dan set panah vertikal.
Bagian lain dari teka-teki adalah bahwa jendela harus dibuat kunci:
[window makeKeyAndVisible];
selain itu subview tidak secara otomatis diubah ukurannya.
sumber
layoutSubviews
. ApakahinitWithFrame:
sebablayoutSubviews
untuk dipanggil?view1.1
panggilanlayoutSubviews
dariview1
dan kemudianlayoutSubviews
dariview1.1
. Panggilan ini tidak merambat tanpa batas ke superviews, menyebutnya padaview1.1.1
panggilan hanyalayoutSubviews
padaview1.1
danview1.1.1
. Hanya bergerak tanpa mengubah ukurannya tidak memanggillayoutSubviews
mereka.view1.2
ke dalamview1
,layoutSubviews
dariview1.2
danview1
yang dipanggil, tetapilayoutSubviews
dariview1.1
tidak disebut. (view1.1
danview1.2
merupakan subview dariview1
). Artinya, tidak semua subview dari tampilan target disebutlayoutSubviews
metode .Membangun jawaban sebelumnya oleh @BadPirate, saya bereksperimen sedikit lebih jauh dan muncul dengan beberapa klarifikasi / koreksi. Saya menemukan bahwa
layoutSubviews:
akan dipanggil pada tampilan jika dan hanya jika:Beberapa detail yang relevan:
layoutSubviews:
dipanggil setiap kali UIScrollView menggulir, saat melakukan pengguliran dengan mengubah asal batasnya.layoutSubviews:
ketika tampilan akhirnya ditambahkan ke hierarki tampilan .setNeedsLayout
, yang menetapkan / menaikkan bendera. Setiap iterasi dari run loop, untuk semua tampilan dalam hierarki tampilan , flag ini dicentang. Untuk setiap tampilan tempat bendera ditemukan dinaikkan,layoutSubviews:
dipanggil dan bendera diatur ulang. Tampilan lebih tinggi hierarki akan diperiksa / dipanggil terlebih dahulu.sumber
https://developer.apple.com/library/prerelease/tvos/documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/CreatingViews/CreatingViews.html#//apple_ref/doc/uid/TP40009503-CH5-SW1
sumber
Beberapa poin dalam jawaban BadPirate hanya sebagian yang benar:
Untuk
addSubView
poinItu tergantung pada topeng autoresize tampilan (target view). Jika memiliki autoresize mask ON, layoutSubview akan dipanggil masing-masing
addSubview
. Jika tidak memiliki mask autoresize maka layoutSubview akan dipanggil hanya ketika ukuran bingkai tampilan (target view) berubah.Contoh: jika Anda membuat UIView secara terprogram (secara default tidak memiliki mask autoresize), LayoutSubview akan dipanggil hanya ketika frame UIView berubah tidak pada setiap
addSubview
.Melalui teknik ini kinerja aplikasi juga meningkat.
Untuk titik rotasi perangkat
Ini bisa benar hanya ketika VC Anda berada dalam hierarki VC (root at
window.rootViewController
), nah ini kasus yang paling umum. Di iOS 5, jika Anda membuat VC, tetapi tidak ditambahkan ke VC lain, maka VC ini tidak akan mendapat perhatian ketika perangkat diputar. Karenanya pandangannya tidak akan diketahui dengan memanggil layoutSubviews.sumber
Saya melacak solusinya hingga desakan Interface Builder bahwa pegas tidak dapat diubah pada tampilan yang mengaktifkan elemen layar simulasi (bilah status, dll.). Karena pegas tidak aktif untuk tampilan utama, tampilan itu tidak dapat mengubah ukuran dan karenanya digulir ke bawah secara keseluruhan ketika bilah panggilan muncul.
Mematikan fitur yang disimulasikan, kemudian mengubah ukuran tampilan dan mengatur pegas dengan benar menyebabkan animasi terjadi dan metode saya dipanggil.
Masalah tambahan dalam debugging ini adalah bahwa simulator keluar dari aplikasi ketika status panggilan masuk diaktifkan melalui menu. Keluar dari aplikasi = tidak ada debugger.
sumber
memanggil
[self.view setNeedsLayout];
di viewController membuatnya memanggil viewDidLayoutSubviewssumber
Anda sudah melihat layoutIfNeeded?
Cuplikan dokumentasi di bawah ini. Apakah animasi berfungsi jika Anda memanggil metode ini secara eksplisit selama animasi?
layoutIfNeeded Menjabarkan subview jika diperlukan.
Diskusi Gunakan metode ini untuk memaksa tata letak subview sebelum menggambar.
Ketersediaan Tersedia di iPhone OS 2.0 dan yang lebih baru.
sumber
Saat memigrasi aplikasi OpenGL dari SDK 3 ke 4, layoutSubviews tidak dipanggil lagi. Setelah banyak trial and error akhirnya saya membuka MainWindow.xib, memilih objek Window, di inspektur memilih tab Window Attributes (paling kiri) dan centang "Visible at launch". Tampaknya di SDK 3 masih digunakan untuk menyebabkan panggilan layoutSubViews, tetapi tidak di 4.
6 jam frustrasi diakhiri.
sumber
Kasus yang agak kabur, namun berpotensi penting ketika
layoutSubviews
tidak pernah dipanggil adalah:sumber