web-dev-qa-db-fra.com

Comment puis-je faire un mouvement NSView à l'avant de tous NSViews

J'ai une super vue, qui a 2 sous-vues. Ces sous-vues se chevauchent.

Chaque fois que je choisis une vue dans un menu, la vue correspondante doit devenir la vue de face et gérer les actions. C'est-à-dire qu'elle devrait être la sous-vue la plus à l'avant. 

acceptsFirstResponder abandonne tout le travail correctement. Mais les événements de la souris enfoncés sont envoyés à la plus haute sous-vue définie.

Cordialement, Dhana

31
Dhanaraj

Voici un autre moyen d'accomplir ceci qui est un peu plus clair et succinct:

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

Selon la documentation de cette méthode, lorsque vous utilisez relativeTo:nil, la vue est ajoutée au-dessus (ou au-dessous, avec NSWindowBelow) à tous ses frères et sœurs.

36
Adam Preble

Une autre méthode consiste à utiliser la méthode sortSubviewsUsingFunction: de NSView: context: pour réorganiser une collection de vues sœurs à votre guise. Par exemple, définissez votre fonction de comparaison:

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;
}

Ensuite, lorsque vous souhaitez vous assurer que votre affichage personnalisé reste au-dessus de tous les affichages frères, envoyez ce message à la vue d'ensemble de votre affichage personnalisé:

[[myCustomView superview] sortSubviewsUsingFunction:myCustomViewAboveSiblingViewsComparator context:NULL];

Alternativement, vous pouvez déplacer ce code vers la vue principale et envoyer le message sortSubviewsUsingFunction: context: à self à la place.

14
Dalmazio

J'ai pu obtenir que cela fonctionne sans appeler removeFromSuperView

// pop to top
[self addSubview:viewToBeMadeForemost positioned:NSWindowAbove relativeTo:nil];
4
user511037

utiliser la réponse de @ Dalmazio dans une catégorie Swift 4 qui imite la méthode UIView équivalente donne les éléments suivants:

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)
    }

}

donc, pour mettre subView à l'avant dans containerView

containerView.bringSubviewToFront(subView)

contrairement aux solutions qui suppriment et rajoutent la vue, les contraintes restent inchangées

1
Confused Vorlon

Vous pouvez y parvenir en ajoutant simplement la vue; cela ne créera pas une autre instance.

[self addSubview:viewToBeMadeForemost];

Vous pouvez enregistrer le nombre de sous-vues avant et après l'exécution de cette ligne de code.

1
Alfredo Campos

Le code ci-dessous devrait fonctionner correctement.

    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..
1
Dhanaraj

Pour déplacer une vue vers l'avant, elle doit être placée en tant que dernier élément du tableau de sous-vues. Voici une solution 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
Jason McClinsey