アプリがルート ビュー コントローラーに戻ったら、viewDidAppear:
メソッドですべてのサブビューを削除する必要があります。
これどうやってするの?
編集: cocoafanのおかげで: この状況は、物事を別の方法NSView
で処理するという事実によって混乱しています。UIView
(デスクトップ Mac 開発のみ) の場合NSView
は、次のように簡単に使用できます。
[someNSView setSubviews:[NSArray array]];
UIView
(iOS 開発のみ) の場合、プロパティはサブビューの配列のコピーを返すため、安全に使用できますmakeObjectsPerformSelector:
。subviews
[[someUIView subviews]
makeObjectsPerformSelector:@selector(removeFromSuperview)];
列挙されている間に配列を変更しているように見えることを指摘してくれたTommyに感謝します(これは に対して行われますが、 に対しては行われません)。makeObjectsPerformSelector:
subviews
NSView
UIView
詳細については、この SO の質問を参照してください。
注:これら 2 つの方法のいずれかを使用すると、メイン ビューに含まれるすべてのビューが削除され、他の場所に保持されていない場合は解放されます。removeFromSuperviewに関する Apple のドキュメントから:
レシーバーのスーパービューが nil でない場合、このメソッドはレシーバーを解放します。ビューを再利用する場合は、このメソッドを呼び出す前にビューを保持し、使用が終了したとき、またはビューを別のビュー階層に追加した後に、必要に応じて解放してください。
ルート コントローラーからすべてのサブビューを取得し、それぞれに removeFromSuperview を送信します。
NSArray *viewsToRemove = [self.view subviews];
for (UIView *v in viewsToRemove) {
[v removeFromSuperview];
}
Swiftでは、次のような機能的アプローチを使用できます。
view.subviews.forEach { $0.removeFromSuperview() }
比較として、命令型アプローチは次のようになります。
for subview in view.subviews {
subview.removeFromSuperview()
}
これらのコード スニペットはiOS / tvOSでのみ機能しますが、macOS では少し異なります。
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];
スイフト 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 ドキュメントからの引用:
配列内の各オブジェクトに、特定のセレクターによって識別されたメッセージを送信します。最初のオブジェクトから始まり、配列内の最後のオブジェクトまで続きます。
(これはこの目的には間違った方向です)
この方法を試してくださいSwift 2.0
view.subviews.forEach { $0.removeFromSuperview() }
Objective-C では、UIView クラスからカテゴリ メソッドを作成します。
- (void)removeAllSubviews
{
for (UIView *subview in self.subviews)
[subview removeFromSuperview];
}
すべてのサブビューを削除するには 構文:
- (void)makeObjectsPerformSelector:(SEL)aSelector;
使用法 :
[self.View.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
このメソッドは NSArray.h ファイルにあり、NSArray(NSExtendedArray) インターフェイスを使用します
monotouch / xamarin.ios では、これでうまくいきました:
SomeParentUiView.Subviews.All(x => x.RemoveFromSuperview);
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に設定された制約がクリアされていたため、直接使用できませんでした。