スーパービューがあり、2つのサブビューがあります。これらのサブビューは重複しています。
メニューからビューを選択するたびに、対応するビューが正面ビューになり、アクションを処理する必要があります。つまり、最前面のサブビューである必要があります。
acceptsFirstResponder
はすべての作業をうまく辞任します。ただし、マウスダウンイベントは、設定された一番上のサブビューに送信されます。
よろしく、ダナ
これを実現するもう1つの方法は、もう少し明確で簡潔です。
[viewToBeMadeForemost removeFromSuperview];
[self addSubview:viewToBeMadeForemost positioned:NSWindowAbove relativeTo:nil];
このメソッドのドキュメントによれば、relativeTo:nil
を使用すると、ビューはそのすべての兄弟の上(またはNSWindowBelow
の下)に追加されます。
別の方法は、NSViewのsortSubviewsUsingFunction:context:メソッドを使用して、好みに合わせて兄弟ビューのコレクションを並べ替えることです。たとえば、比較関数を定義します。
static NSComparisonResult myCustomViewAboveSiblingViewsComparator( NSView * view1, NSView * view2, void * context )
{
if ([view1 isKindOfClass:[MyCustomView class]])
return NSOrderedDescending;
else if ([view2 isKindOfClass:[MyCustomView class]])
return NSOrderedAscending;
return NSOrderedSame;
}
次に、カスタムビューがすべての兄弟ビューの上に留まるようにする場合は、次のメッセージをカスタムビューのスーパービューに送信します。
[[myCustomView superview] sortSubviewsUsingFunction:myCustomViewAboveSiblingViewsComparator context:NULL];
または、このコードをスーパービュー自体に移動し、代わりにメッセージsortSubviewsUsingFunction:context:をselfに送信することもできます。
同等のUIViewメソッドを模倣するSwift 4カテゴリで@Dalmazioの回答を使用すると、次のようになります。
extension NSView {
func bringSubviewToFront(_ view: NSView) {
var theView = view
self.sortSubviews({(viewA,viewB,rawPointer) in
let view = rawPointer?.load(as: NSView.self)
switch view {
case viewA:
return ComparisonResult.orderedDescending
case viewB:
return ComparisonResult.orderedAscending
default:
return ComparisonResult.orderedSame
}
}, context: &theView)
}
}
したがって、subView
をcontainerView
で前面に表示するには
containerView.bringSubviewToFront(subView)
ビューを削除して再度追加するソリューションとは異なり、これにより制約が変更されません。
RemoveFromSuperViewを呼び出さずにこれを機能させることができました
// pop to top
[self addSubview:viewToBeMadeForemost positioned:NSWindowAbove relativeTo:nil];
ビューを再度追加するだけでこれを実現できます。別のインスタンスは作成されません。
[self addSubview:viewToBeMadeForemost];
このコード行が実行される前後のサブビューの数をログに記録できます。
以下のコードは正常に動作するはずです。
NSMutableArray *subvies = [NSMutableArray arrayWithArray:[self subviews]];//Get all subviews..
[viewToBeMadeForemost retain]; //Retain the view to be made top view..
[subvies removeObject:viewToBeMadeForemost];//remove it from array
[subvies addObject:viewToBeMadeForemost];//add as last item
[self setSubviews:subvies];//set the new array..
ビューを前面に移動するには、ビューをsubviews配列の最後の要素として配置する必要があります。これがSwift 3.0ソリューションです:
func bringChildToFrontWith(viewIdentifier: Int) {
var subViewArray = self.subviews // Apple docs recommend copying subViews array before operating on it, as it "can be changed at any time"
for ix in 0 ..< subViewArray.count {
if let childView = subViewArray[ix] as? MyViewSubClass {
if childView.myViewSubClassIdentifier == viewIdentifier {
let topItem = subViewArray[ix];
subViewArray.remove(at: ix)
subViewArray.append(topItem)
self.contentView.subviews = subViewArray
}
}
}
}