11
votes

Centre de fenêtre créée par programme

J'utilise l'exemple d'ici pour créer une fenêtre de titre de titre personnalisée:

Dessinez une fenêtre personnalisée sur Mac OS X

J'ai trouvé que c'est la seule façon de créer une fenêtre Titlebar-moins dans le léopard, Snow Leopard et Lion, d'autres méthodes ne fonctionnent pas non plus sur le léopard ni le lion. (Si je tente d'invoquer une fenêtre titlebar-moins par NSWindow normal et IB, il ne démarre pas dans Leopard plus)

Jusqu'à présent, cette fenêtre Titlebar-Moins personnalisée fonctionne bien partout, mais je ne peux pas le centrer, une position fixe dure dans le constructeur d'interface.

Il est assez facile de centrer une implémentation normale Nswindow * window avec [Centre de fenêtre], mais je n'ai rien trouvé qui fonctionne sur cette sous-classe de fenêtre personnalisée, une fenêtre qui n'est pas créée à partir de NIB via Interface Builder.

J'ai essayé quelques choses à partir de Nswindow , mais rien ne semble fonctionner.

Des idées?


0 commentaires

7 Réponses :


4
votes

La question devrait probablement être la raison pour laquelle [centre de fenêtre] ne fonctionne pas; Mais en supposant que c'est le cas, utilisez nscreen pour obtenir les coordonnées de l'écran, faire le calcul et centrer la fenêtre directement.


2 commentaires

En prenant le code supérieur à partir du lien "Dessiner une fenêtre personnalisée sur Mac OS X", où et comment Nscreen doit-il y être utilisé?


@devilhunter: Voir @wekwa - [Écran de fenêtre] Renvoie un Nscreen , celui de la fenêtre est actuellement sur. Si vous souhaitez placer la fenêtre sur un écran particulier nscreen vous donnera une liste de toutes, la principale, etc.



21
votes
CGFloat xPos = NSWidth([[window screen] frame])/2 - NSWidth([window frame])/2;
CGFloat yPos = NSHeight([[window screen] frame])/2 - NSHeight([window frame])/2;
[window setFrame:NSMakeRect(xPos, yPos, NSWidth([window frame]), NSHeight([window frame])) display:YES];
This puts it at the literal center of the screen, not taking into account the space occupied by the dock and menu bar. If you want to do that, change [[window screen] frame] to [[window screen] visibleFrame].

10 commentaires

En regardant le projet Exemple Xcode, il n'y a pas de définition «fenêtre». (La fenêtre est non déclaue). Même si je déclare la "fenêtre" à la création de programme programmatique "Roundwindow", la barre de titre montre à nouveau parce que c'est maintenant une classe de fenêtre normale.


N'oubliez pas que pour être correct pour plusieurs affichages, vous devez également faire xpos + = [[[[écran] Cadre] .origin.x; YPOS + = [[[[[écran] Cadre] .origin.y;


@Glyph le gist de ce que vous dites est correct, mais le calcul est faux. En fonction des dispositions d'affichage, vous devez effectuer des calculs différents. Par exemple, si le deuxième écran se trouve à gauche de l'écran principal, vous devez - = le XPOS. Je déterminerai toujours comment faire le calcul correctement pour tous les arrangements d'écran.


@Benbaron s'il vous plaît effectuez un lien quand vous ne trouvez que les maths :)


@Glyph, nous avons finalement fait le comprendre. Notre application est open source alors jetez un coup d'œil aux méthodes updatewindowframe et updatewindoworigin ici: github.com/balancemymey/balance-open/blob/master/balance/...


Notez que notre cas d'utilisation est un peu différent puisque notre application est une application de barre d'état, mais nous avons eu le même problème de positionnement. Désolé, cela n'est pas commenté, mais cela devrait vous donner une idée de ce que nous devions faire pour le faire fonctionner correctement.


En fait, vous n'êtes pas sûr de la pertinence que ce soit pour vous parce que beaucoup de notre solution implique l'utilisation de notre bouton d'état d'état.


En outre, cela a été un moment et un autre Dev s'est terminé par la fixation, désolé, je ne peux pas m'empêcher beaucoup plus que de pointer votre code à notre code.


@Ramarajt: [Centre de fenêtre] fonctionne uniquement pour la fenêtre intitulée Fenêtre. Pour la fenêtre sans titre, nous devons faire comme cette réponse suggérée.


@Anoopvaidya ok



0
votes

Version Swift: On peut écrire une fonction d'utilitaire statique simple pour la même xxx


0 commentaires

9
votes
extension NSWindow {
    public func setFrameOriginToPositionWindowInCenterOfScreen() {
        if let screenSize = screen?.frame.size {
            self.setFrameOrigin(NSPoint(x: (screenSize.width-frame.size.width)/2, y: (screenSize.height-frame.size.height)/2))
        }
    }
}

0 commentaires

1
votes

Je suis tombé sur le même problème. Ce qui a fonctionné pour moi est de définir iSresorable à false sur le nswindow objet avant d'appeler centre () .


0 commentaires

1
votes

objectif - c em> strong> dans MacOS Catalina, version 10.15.3

plus lisible @ Réponse de Wekwa P>

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    NSWindow * window = NSApplication.sharedApplication.windows[0];
    CGFloat xPos = NSWidth(window.screen.frame)/2 - NSWidth(window.frame)/2;
    CGFloat yPos = NSHeight(window.screen.frame)/2 - NSHeight(window.frame)/2;
    [window setFrame:NSMakeRect(xPos, yPos, NSWidth(window.frame), NSHeight(window.frame)) display:YES];
}


0 commentaires

0
votes

mis à jour pour SWIFT 5

J'ai toujours trouvé que centré la fenêtre avec écran.frame code> a abouti à une fenêtre ressent em> comme s'il était trop proche du bas de l'écran. Cela est dû à la taille du quai étant de près de 3 fois aussi grand que la barre d'état / menu (environ 70-80px contre 25px, respectivement). P>

Ceci provoque la fenêtre apparaissent em> Comme s'il était positionné plus bas au bas de l'écran, comme nos yeux ne réglent pas automatiquement les embarqués de la barre d'état (taille 1x) et de la touche Dock (~ 3x). P>

Pour cette raison, Je choisis toujours d'aller avec Screen.VisibleFrame code>, comme il est définitivement ressent em> plus centré. VisibleFrame CODE> prend en compte la barre d'état et la tailles de quai, et calcule les points centraux pour le cadre entre ces deux objets. P>

override func viewDidLoad() {
    super.viewDidLoad()
    initWindowSize(width: 900, height: 600)
}

func initWindowSize(width: Int, height: Int) {
    let x = self.view.window?.xCenter() ?? CGFloat(0)
    let y = self.view.window?.yCenter() ?? CGFloat(0)
    self.view.window?.setFrame(NSRect(x: x, y: y, width: CGFloat(width), height: CGFloat(height)), display: true)
}


0 commentaires