Câu trả lời:
Chỉnh sửa: Nhờ có cocoafan : Tình huống này được xử lý bằng thực tế NSView
và UIView
xử lý mọi việc khác nhau. Đối với NSView
(chỉ phát triển máy tính để bàn), bạn chỉ cần sử dụng như sau:
[someNSView setSubviews:[NSArray array]];
Đối với UIView
(chỉ phát triển iOS), bạn có thể sử dụng một cách an toàn makeObjectsPerformSelector:
vì thuộc subviews
tính sẽ trả về một bản sao của mảng các cuộc phỏng vấn:
[[someUIView subviews]
makeObjectsPerformSelector:@selector(removeFromSuperview)];
Cảm ơn Tommy vì đã chỉ ra rằng có makeObjectsPerformSelector:
vẻ như sửa đổi subviews
mảng trong khi nó đang được liệt kê (cái này làm NSView
, nhưng không phải cho UIView
).
Xin vui lòng xem câu hỏi SO này để biết thêm chi tiết.
Lưu ý: Sử dụng một trong hai phương pháp này sẽ xóa mọi chế độ xem mà chế độ xem chính của bạn chứa và giải phóng chúng , nếu chúng không được giữ lại ở nơi khác. Từ tài liệu của Apple về removeFromSuperview :
Nếu giám sát của người nhận không bằng không, phương pháp này sẽ giải phóng người nhận. Nếu bạn có kế hoạch sử dụng lại chế độ xem, hãy chắc chắn giữ lại trước khi gọi phương thức này và chắc chắn phát hành nó khi thích hợp khi bạn thực hiện với nó hoặc sau khi thêm nó vào hệ thống phân cấp chế độ xem khác.
UIView
trả về một bản sao của subviews
mảng có thể thay đổi, vì vậy mã này chỉ hoạt động. Câu chuyện hoàn toàn khác nhau trên máy tính để bàn, trong đó cùng một mã sẽ đưa ra một ngoại lệ. Xem stackoverflow.com/questions/4665179/
someUIView.Subviews.All( v => { v.RemoveFromSuperview(); return true; } );
. IMHO sạch hơn để nói những gì bạn có nghĩa là : someUIView.Subviews.ToList().ForEach( v => v.RemoveFromSuperview() );
.
Nhận tất cả các cuộc phỏng vấn từ bộ điều khiển gốc của bạn và gửi cho mỗi removeFromSuperview:
NSArray *viewsToRemove = [self.view subviews];
for (UIView *v in viewsToRemove) {
[v removeFromSuperview];
}
self.view
như bạn có.
for (UIView *v in [self.view subviews])
nó dễ dàng hơn
Trong Swift, bạn có thể sử dụng một cách tiếp cận chức năng như thế này:
view.subviews.forEach { $0.removeFromSuperview() }
Để so sánh, cách tiếp cận bắt buộc sẽ như thế này:
for subview in view.subviews {
subview.removeFromSuperview()
}
Các đoạn mã này chỉ hoạt động trong iOS / tvOS , mọi thứ hơi khác một chút trên macOS.
(subviews as [UIView]).map { $0.removeFromSuperview() }
.map
. Đây là một tác dụng phụ thuần túy và được xử lý tốt hơn như thế này:view.subviews.forEach() { $0.removeFromSuperview() }
Nếu bạn muốn xóa tất cả các cuộc phỏng vấn trên UIView của bạn (tại đây yourView
), sau đó viết mã này vào nút của bạn, nhấp:
[[yourView subviews] makeObjectsPerformSelector: @selector(removeFromSuperview)];
Điều này chỉ áp dụng cho OSX vì trong iOS, một bản sao của mảng được giữ
Khi xóa tất cả các cuộc phỏng vấn, một ý tưởng tốt là bắt đầu xóa ở cuối mảng và tiếp tục xóa cho đến khi bạn đạt đến điểm bắt đầu. Điều này có thể được thực hiện với hai dòng mã này:
for (int i=mySuperView.subviews.count-1; i>=0; i--)
[[mySuperView.subviews objectAtIndex:i] removeFromSuperview];
Chuyển đổi 1.2
for var i=mySuperView.subviews.count-1; i>=0; i-- {
mySuperView.subviews[i].removeFromSuperview();
}
hoặc (ít hiệu quả hơn, nhưng dễ đọc hơn)
for subview in mySuperView.subviews.reverse() {
subview.removeFromSuperview()
}
GHI CHÚ
Bạn KHÔNG nên xóa các cuộc phỏng vấn theo thứ tự thông thường, vì nó có thể gây ra sự cố nếu một đối tượng UIView bị xóa trước khiremoveFromSuperview
tin nhắn được gửi đến tất cả các đối tượng của mảng. (Rõ ràng, xóa phần tử cuối cùng sẽ không gây ra sự cố)
Do đó, mã
[[someUIView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
KHÔNG nên được sử dụng.
Trích dẫn từ tài liệu của Apple về makeObjectsPerformSelector :
Gửi đến từng đối tượng trong mảng thông điệp được xác định bởi một bộ chọn đã cho, bắt đầu với đối tượng đầu tiên và tiếp tục thông qua mảng đến đối tượng cuối cùng.
(đó sẽ là hướng đi sai cho mục đích này)
removeFromSuperview
kết thúc, UIView sẽ bị xóa khỏi mảng và nếu không có trường hợp sống nào khác có mối quan hệ chặt chẽ với UIView, UIView cũng sẽ bị xóa. Điều này có thể gây ra một ngoại lệ ràng buộc.
[yourView subviews]
trả về một BẢN SAO của mảng, do đó an toàn. (LƯU Ý rằng trên OSX, những gì bạn nói là chính xác.)
Hãy thử cách này nhanh chóng 2.0
view.subviews.forEach { $0.removeFromSuperview() }
forEach
giải pháp dựa trên đã được thêm vào sau bạn, tôi đã bỏ lỡ điều đó. Lời xin lỗi.
Sử dụng mã sau đây để loại bỏ tất cả các cuộc phỏng vấn.
for (UIView *view in [self.view subviews])
{
[view removeFromSuperview];
}
Để xóa tất cả các cuộc phỏng vấn Cú pháp:
- (void)makeObjectsPerformSelector:(SEL)aSelector;
Sử dụng :
[self.View.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
Phương thức này có trong tệp NSArray.h và sử dụng giao diện NSArray (NSExtendsArray)
Nếu bạn đang sử dụng Swift, nó đơn giản như:
subviews.map { $0.removeFromSuperview }
Về mặt triết học, nó tương tự như makeObjectsPerformSelector
cách tiếp cận, tuy nhiên với sự an toàn hơn một chút.
map
không nên dẫn đến tác dụng phụ. Thêm vào đó, kết quả tương tự có thể đạt được thông qua forEach
.
Đối với ios6 bằng cách sử dụng tự động thanh toán, tôi đã phải thêm một chút mã để loại bỏ các ràng buộc.
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)];
Tôi chắc chắn có một cách gọn gàng hơn để làm điều này, nhưng nó hiệu quả với tôi. Trong trường hợp của tôi, tôi không thể sử dụng trực tiếp [tagview removeConstraints:tagview.constraints]
vì có các ràng buộc được đặt trong XCode đang bị xóa.
Trong monotouch / xamarin.ios, điều này làm việc cho tôi:
SomeParentUiView.Subviews.All(x => x.RemoveFromSuperview);
Để xóa tất cả các cuộc phỏng vấn khỏi giám sát:
NSArray *oSubView = [self subviews];
for(int iCount = 0; iCount < [oSubView count]; iCount++)
{
id object = [oSubView objectAtIndex:iCount];
[object removeFromSuperview];
iCount--;
}
iCount++
và iCount--
, để lại chỉ mục giống nhau, vì vậy nó sẽ là một vòng lặp vô hạn nếu [oSubView count]>0
. Đây chắc chắn là lỗi và mã KHÔNG CÓ .