Как заставить NSView переместиться на передний план всех NSView - PullRequest
31 голосов
/ 20 мая 2010

У меня супер просмотр, который имеет 2 подпредставления. Эти подпредставления перекрываются.

Всякий раз, когда я выбираю вид из меню, соответствующий вид должен стать видом спереди и обрабатывать действия. то есть, это должно быть переднее самое подпредставление.

acceptsFirstResponder подает в отставку, все работает нормально. Но события нажатия мыши отправляются в самый верхний подвид, который был установлен.

С уважением, Dhana

Ответы [ 8 ]

37 голосов
/ 22 мая 2010

Вот еще один способ сделать это более понятным и лаконичным:

[viewToBeMadeForemost removeFromSuperview];
[self addSubview:viewToBeMadeForemost positioned:NSWindowAbove relativeTo:nil];

В соответствии с документацией для этого метода, когда вы используете relativeTo:nil, представление добавляется выше (или ниже, с NSWindowBelow) всеми его родственниками.

14 голосов
/ 21 декабря 2011

Другой способ - использовать метод 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: to self .

4 голосов
/ 18 сентября 2012

Мне удалось заставить это работать без вызова removeFromSuperView

// pop to top
[self addSubview:viewToBeMadeForemost positioned:NSWindowAbove relativeTo:nil];
3 голосов
/ 22 января 2019

Использование ответа @ 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)

в отличие от решений, которые удаляют и повторно добавляют представление, это сохраняет ограничения без изменений

1 голос
/ 31 декабря 2014

Вы можете достичь этого, просто добавив представление снова; это не создаст другой экземпляр этого.

[self addSubview:viewToBeMadeForemost];

Вы можете зарегистрировать количество подпредставлений до и после выполнения этой строки кода.

1 голос
/ 20 мая 2010

Ниже приведенный код должен работать нормально ..

    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..
0 голосов
/ 18 февраля 2017

Чтобы переместить вид вперед, он должен быть помещен как последний элемент в массиве 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
            }
        }
    }
}
0 голосов
/ 26 января 2012

Вы можете попробовать это:

[viewToBeMadeFirst.window makeKeyAndOrderFront:nil];
...