Как заставить 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];
Другие вопросы по тегам