回答:
編集:cocoafanのおかげで:この状況は、物事を異なる方法NSView
でUIView
処理するという事実によって混乱しています。以下のためにNSView
(のみデスクトップのMac開発)、あなたは、単に以下のように使用することができます。
[someNSView setSubviews:[NSArray array]];
以下のためにUIView
(のみのiOS開発)、あなたは安全に使用することができますmakeObjectsPerformSelector:
ので、subviews
プロパティが返されますコピーサブビューの配列のを:
[[someUIView subviews]
makeObjectsPerformSelector:@selector(removeFromSuperview)];
ありがとうトミーことを指摘するためにmakeObjectsPerformSelector:
表示され、変更するsubviews
ことが列挙されている間、(それがためていた配列をNSView
、ではないためUIView
)。
詳細については、このSOの質問を参照してください。
注:これらの2つの方法のいずれかを使用すると、メインビューに含まれているすべてのビューが削除され、他の場所に保持されていない場合は解放されます。removeFromSuperviewに関するAppleのドキュメントから:
レシーバーのスーパービューがnilでない場合、このメソッドはレシーバーを解放します。ビューを再利用する予定がある場合は、このメソッドを呼び出す前にビューを保持し、必要に応じて、またはビューを別のビュー階層に追加した後は、必要に応じて解放してください。
UIView
返すので、このコードはうまくいきます。デスクトップ上のまったく異なるストーリー。同じコードが例外をスローします。stackoverflow.com/questions/4665179/…を参照してくださいsubviews
someUIView.Subviews.All( v => { v.RemoveFromSuperview(); return true; } );
です。あなたが何を意味するか言うために私見クリーナー: someUIView.Subviews.ToList().ForEach( v => v.RemoveFromSuperview() );
。
ルートコントローラーからすべてのサブビューを取得し、それぞれにremoveFromSuperviewを送信します。
NSArray *viewsToRemove = [self.view subviews];
for (UIView *v in viewsToRemove) {
[v removeFromSuperview];
}
self.view
あなたのように使うべきだった。
for (UIView *v in [self.view subviews])
簡単
でスウィフトを使用でき、機能的なアプローチこのように:
view.subviews.forEach { $0.removeFromSuperview() }
比較として、命令型アプローチは次のようになります。
for subview in view.subviews {
subview.removeFromSuperview()
}
これらのコードスニペットはiOS / tvOSでのみ機能しますが、macOSでは少し異なります。
(subviews as [UIView]).map { $0.removeFromSuperview() }
.map
。これは純粋な副作用であると、より良い、このように処理されますview.subviews.forEach() { $0.removeFromSuperview() }
UIView(ここyourView
)のすべてのサブビューを削除する場合は、ボタンをクリックしてこのコードを記述します。
[[yourView subviews] makeObjectsPerformSelector: @selector(removeFromSuperview)];
iOSでは配列のコピーが保持されるため、これはOSXにのみ適用されます
すべてのサブビューを削除する場合は、配列の最後から削除を開始し、最初に到達するまで削除を続けることをお勧めします。これは、次の2行のコードで実現できます。
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();
}
または(効率は落ちますが、読みやすくなります)
for subview in mySuperView.subviews.reverse() {
subview.removeFromSuperview()
}
注意
メッセージが配列のすべてのオブジェクトに送信される前にUIViewインスタンスが削除されると、クラッシュを引き起こす可能性があるため、通常の順序でサブビューを削除しないでくださいremoveFromSuperview
。(明らかに、最後の要素を削除してもクラッシュは発生しません)
したがって、コード
[[someUIView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
使用しないでください。
makeObjectsPerformSelectorに関するAppleドキュメントからの引用:
最初のオブジェクトから最後のオブジェクトまで、指定されたセレクターで識別されたメッセージを配列内の各オブジェクトに送信します。
(これはこの目的のために間違った方向になるでしょう)
removeFromSuperview
仕上げは、UIViewのは、配列から削除されますのUIViewに強い関係を持つ他の生活のインスタンスが存在しない場合、および、UIViewのも削除されます。これにより、範囲外の例外が発生する可能性があります。
[yourView subviews]
配列のCOPYが返されるため、安全です。(OSXでは、あなたの言うことは正しいことに注意してください。)
この方法をすぐに試してください2.0
view.subviews.forEach { $0.removeFromSuperview() }
forEach
ベースのソリューションがあなたの後に追加されました、私はそれを逃しました。謝罪。
次のコードを使用して、すべてのサブビューを削除します。
for (UIView *view in [self.view subviews])
{
[view removeFromSuperview];
}
view.subviews.forEach { $0.removeFromSuperview() }
すべてのサブビューを削除するには構文:
- (void)makeObjectsPerformSelector:(SEL)aSelector;
使用法 :
[self.View.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
このメソッドはNSArray.hファイルにあり、NSArray(NSExtendedArray)インターフェイスを使用します
Swiftを使用している場合は、次のように簡単です。
subviews.map { $0.removeFromSuperview }
哲学はmakeObjectsPerformSelector
アプローチと似ていますが、型の安全性が少し高くなっています。
map
なく、副作用をもたらすことはありません。さらに、を使用しても同じ結果が得られますforEach
。
autolayoutを使用するios6の場合も、制約を削除するためにコードを少し追加する必要がありました。
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)];
これを行うためのよりきちんとした方法があると確信していますが、それは私にとってはうまくいきました。私の場合[tagview removeConstraints:tagview.constraints]
、XCodeで設定された制約がクリアされていたため、直接使用できませんでした。
スーパービューからすべてのサブビューを削除するには:
NSArray *oSubView = [self subviews];
for(int iCount = 0; iCount < [oSubView count]; iCount++)
{
id object = [oSubView objectAtIndex:iCount];
[object removeFromSuperview];
iCount--;
}
iCount++
とiCount--
、それがあれば、無限ループになり、同じインデックスを残します[oSubView count]>0
。これは間違いなくバグがあり、使用できないコードです。