Jawaban:
Sunting: Dengan terima kasih kepada cocoafan : Situasi ini kacau oleh fakta bahwa NSView
dan UIView
menangani berbagai hal secara berbeda. Untuk NSView
(pengembangan Mac desktop), Anda cukup menggunakan yang berikut ini:
[someNSView setSubviews:[NSArray array]];
Untuk UIView
(pengembangan iOS saja), Anda dapat menggunakan dengan aman makeObjectsPerformSelector:
karena subviews
properti akan mengembalikan salinan array subview:
[[someUIView subviews]
makeObjectsPerformSelector:@selector(removeFromSuperview)];
Terima kasih kepada Tommy untuk menunjukkan yang makeObjectsPerformSelector:
tampaknya mengubah subviews
array saat sedang dihitung (memang untuk apa NSView
, tetapi tidak untuk UIView
).
Silakan lihat pertanyaan SO ini untuk lebih jelasnya.
Catatan: Menggunakan salah satu dari kedua metode ini akan menghapus setiap tampilan yang berisi tampilan utama Anda dan melepaskannya , jika tidak disimpan di tempat lain. Dari dokumentasi Apple tentang removeFromSuperview :
Jika superview penerima tidak nol, metode ini melepaskan penerima. Jika Anda berencana untuk menggunakan kembali tampilan, pastikan untuk menyimpannya sebelum memanggil metode ini dan pastikan untuk melepaskannya sesuai ketika Anda selesai dengan itu atau setelah menambahkannya ke hierarki tampilan lain.
UIView
kembali sebuah salinan dari subviews
array bisa berubah, jadi kode ini hanya bekerja. Cerita yang sama sekali berbeda di desktop, di mana kode yang sama akan memberikan pengecualian. Lihat stackoverflow.com/questions/4665179/…
someUIView.Subviews.All( v => { v.RemoveFromSuperview(); return true; } );
. IMHO cleaner untuk mengatakan apa yang Anda maksud: someUIView.Subviews.ToList().ForEach( v => v.RemoveFromSuperview() );
.
Dapatkan semua subview dari pengontrol root Anda dan kirim masing-masing removeFromSuperview:
NSArray *viewsToRemove = [self.view subviews];
for (UIView *v in viewsToRemove) {
[v removeFromSuperview];
}
self.view
seperti yang Anda miliki.
for (UIView *v in [self.view subviews])
lebih mudah
Di Swift Anda dapat menggunakan pendekatan fungsional seperti ini:
view.subviews.forEach { $0.removeFromSuperview() }
Sebagai perbandingan, pendekatan imperatif akan terlihat seperti ini:
for subview in view.subviews {
subview.removeFromSuperview()
}
Cuplikan kode ini hanya berfungsi di iOS / tvOS , ada sedikit perbedaan pada macOS.
(subviews as [UIView]).map { $0.removeFromSuperview() }
.map
. ini adalah efek samping murni dan lebih baik ditangani seperti ini:view.subviews.forEach() { $0.removeFromSuperview() }
Jika Anda ingin menghapus semua subview pada UIView Anda (di sini yourView
), maka tulis kode ini di klik tombol Anda:
[[yourView subviews] makeObjectsPerformSelector: @selector(removeFromSuperview)];
Ini hanya berlaku untuk OSX karena di iOS salinan array disimpan
Saat menghapus semua subview, itu ide yang baik untuk mulai menghapus di akhir array dan terus menghapus sampai Anda mencapai awal. Ini dapat dicapai dengan dua baris kode ini:
for (int i=mySuperView.subviews.count-1; i>=0; i--)
[[mySuperView.subviews objectAtIndex:i] removeFromSuperview];
SWIFT 1.2
for var i=mySuperView.subviews.count-1; i>=0; i-- {
mySuperView.subviews[i].removeFromSuperview();
}
atau (kurang efisien, tetapi lebih mudah dibaca)
for subview in mySuperView.subviews.reverse() {
subview.removeFromSuperview()
}
CATATAN
Anda TIDAK boleh menghapus subview dalam urutan normal, karena dapat menyebabkan crash jika instance UIView dihapus sebelum removeFromSuperview
pesan dikirim ke semua objek array. (Jelas, menghapus elemen terakhir tidak akan menyebabkan kerusakan)
Karena itu, kodenya
[[someUIView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
seharusnya TIDAK digunakan.
Kutipan dari dokumentasi Apple tentang makeObjectsPerformSelector :
Mengirim ke setiap objek dalam array pesan yang diidentifikasi oleh pemilih yang diberikan, dimulai dengan objek pertama dan melanjutkan melalui array ke objek terakhir.
(yang akan menjadi arah yang salah untuk tujuan ini)
removeFromSuperview
selesai, UIView akan dihapus dari array, dan jika tidak ada instance hidup lainnya yang memiliki hubungan kuat dengan UIView, UIView juga akan dihapus. Ini dapat menyebabkan pengecualian di luar batas.
[yourView subviews]
mengembalikan COPY dari array, oleh karena itu aman. (Perhatikan bahwa pada OSX, apa yang Anda katakan benar.)
Coba cara ini cepat 2.0
view.subviews.forEach { $0.removeFromSuperview() }
forEach
solusi berbasis ditambahkan setelah Anda, saya melewatkan itu. Permintaan maaf.
Gunakan kode berikut untuk menghapus semua subview.
for (UIView *view in [self.view subviews])
{
[view removeFromSuperview];
}
Untuk menghapus semua sintaks subview:
- (void)makeObjectsPerformSelector:(SEL)aSelector;
Penggunaan:
[self.View.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
Metode ini hadir dalam file NSArray.h dan menggunakan antarmuka NSArray (NSExtendedArray)
Jika Anda menggunakan Swift, sesederhana:
subviews.map { $0.removeFromSuperview }
Ini mirip dalam filosofi dengan makeObjectsPerformSelector
pendekatan, namun dengan sedikit lebih aman.
map
seharusnya tidak menghasilkan efek samping. Plus, hasil yang sama dapat dicapai melalui forEach
.
Untuk ios6 menggunakan autolayout saya harus menambahkan sedikit kode untuk menghilangkan kendala juga.
NSMutableArray * constraints_to_remove = [ @[] mutableCopy] ;
for( NSLayoutConstraint * constraint in tagview.constraints) {
if( [tagview.subviews containsObject:constraint.firstItem] ||
[tagview.subviews containsObject:constraint.secondItem] ) {
[constraints_to_remove addObject:constraint];
}
}
[tagview removeConstraints:constraints_to_remove];
[ [tagview subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
Saya yakin ada cara yang lebih rapi untuk melakukan ini, tetapi itu berhasil bagi saya. Dalam kasus saya, saya tidak bisa menggunakan direct [tagview removeConstraints:tagview.constraints]
karena ada batasan yang ditetapkan dalam XCode yang sedang dibersihkan.
Di monotouch / xamarin.ios ini berfungsi untuk saya:
SomeParentUiView.Subviews.All(x => x.RemoveFromSuperview);
Untuk menghapus semua subview dari superviews:
NSArray *oSubView = [self subviews];
for(int iCount = 0; iCount < [oSubView count]; iCount++)
{
id object = [oSubView objectAtIndex:iCount];
[object removeFromSuperview];
iCount--;
}
iCount++
dan iCount--
, biarkan indeksnya sama, sehingga akan menjadi infinite loop jika [oSubView count]>0
. Ini jelas buggy dan BUKAN kode yang bisa digunakan.