Как заставить NSView переместиться на передний план всех NSView
У меня супер вид, который имеет 2 подпредставления. Эти подпредставления перекрываются.
Всякий раз, когда я выбираю вид из меню, соответствующий вид должен стать видом спереди и обрабатывать действия. то есть, это должно быть переднее самое подпредставление.
acceptsFirstResponder
подает в отставку, все работает нормально. Но события нажатия кнопки мыши отправляются в самый верхний подвид, который был установлен.
С уважением, Дхана
8 ответов
Вот еще один способ сделать это более понятным и лаконичным:
[viewToBeMadeForemost removeFromSuperview];
[self addSubview:viewToBeMadeForemost positioned:NSWindowAbove relativeTo:nil];
Согласно документации для этого метода, когда вы используете relativeTo:nil
вид добавляется выше (или ниже, с NSWindowBelow
) все его братья и сестры.
Использование ответа @Dalmazio в категории Swift 4, которая имитирует эквивалентный метод UIView, дает следующее:
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)
в отличие от решений, которые удаляют и повторно добавляют представление, это сохраняет ограничения без изменений
Другой способ - использовать NSS's 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: для себя.
Я смог заставить это работать без вызова 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
}
}
}
}
Вы можете попробовать это:
[viewToBeMadeFirst.window makeKeyAndOrderFront:nil];