Как заставить NSView перемещаться по фронту всех NSViews
У меня есть супер-представление, которое имеет 2 подпункта.
Эти подструкции перекрываются.
Всякий раз, когда я выбираю представление из меню, соответствующее представление должно стать видом спереди и обработать действия.
т.е. он должен быть фронтом самого подсмотра.
acceptsFirstResponder
уходит в отставку.
Но события мыши вниз отправляются на самый верхний подвид, который был установлен.
С уважением,
Dhana
Ответы
Ответ 1
Вот еще один способ сделать это более понятным и сжатым:
[viewToBeMadeForemost removeFromSuperview];
[self addSubview:viewToBeMadeForemost positioned:NSWindowAbove relativeTo:nil];
В документации для этого метода, когда вы используете relativeTo:nil
, над ним добавляется представление (или ниже, с NSWindowBelow
) всех его братьев и сестер.
Ответ 2
Другой способ - использовать метод 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;
}
Затем, когда вы хотите, чтобы ваш пользовательский вид оставался выше всех представлений sibling, отправьте это сообщение в свой пользовательский вид viewview:
[[myCustomView superview] sortSubviewsUsingFunction:myCustomViewAboveSiblingViewsComparator context:NULL];
В качестве альтернативы вы можете переместить этот код в сам супервизор и вместо этого отправить сообщение sortSubviewsUsingFunction: context: на self.
Ответ 3
Мне удалось заставить это работать без вызова removeFromSuperView
// pop to top
[self addSubview:viewToBeMadeForemost positioned:NSWindowAbove relativeTo:nil];
Ответ 4
Ниже приведенный код должен работать нормально.
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..
Ответ 5
Вы можете добиться этого, просто добавив снова; он не создаст другого экземпляра.
[self addSubview:viewToBeMadeForemost];
Вы можете зарегистрировать количество подпрограмм до и после выполнения этой строки кода.
Ответ 6
Чтобы переместить представление в начало, он должен быть помещен как последний элемент в массив 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
}
}
}
}
Ответ 7
Использование ответа @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
на передний subView
в containerView
containerView.bringSubviewToFront(subView)
в отличие от решений, которые удаляют и повторно добавляют представление, это сохраняет ограничения без изменений
Ответ 8
Вы можете попробовать следующее:
[viewToBeMadeFirst.window makeKeyAndOrderFront:nil];