Problème d'affichage de NSView depuis MacOS 14.5
Bonjour
Une de mes applications MacOS me pose un problème :
Une NSView affiche des carrés de couleur et des lignes. Il y a 6 modes d'affichage différents.
Depuis MacOS 14.5, un des modes ne s'affiche plus mais les 5 autres oui. Mieux, le NSView répond correctement aux mouseDown dans ce mode alors que l'on ne voit pas les carrés de couleur : la NSView ne s'affiche pas, on ne voit que le gris-blanc de la fenêtre globale, mais elle fonctionne lorsqu'on clique dessus! Le code est appelé et exécuté (vérification par des NSLog).
J'ai lu des articles au sujet de la fonction clipsToBound. J'ai mis "self.clipsToBound = YES" pour voir, mais sans résultat. De toutes façons j'ai toujours utilisé "self.bounds" pour calculer la position des carrés. Et les autres modes fonctionnent normalement.
La NSView fait partie d'un synthé de musique, mais la classe son est totalement indépendante de la classe NSView (et elle fonctionne parfaitement)
D'où peut venir le problème selon vous?
je code encore en Objectiv-C, les premières versions du logiciel ont plus de dix ans)
Réponses
Au cas où tu ne l'aurais pas fait, voici la réponse de ChatGPT4o :
Le problème que tu décris semble être assez complexe et spécifique à la version 14.5 de MacOS. Voici quelques pistes pour tenter de diagnostiquer et résoudre ce problème :
Vérifier le Drawing Code : Il est possible que le code de dessin pour ce mode particulier contienne des appels ou des configurations spécifiques qui ne sont plus compatibles avec MacOS 14.5. Assure-toi que tous les appels de dessin sont appropriés et que rien n'est obsolète.
clipsToBounds : La propriété
clipsToBounds
est utile pour s'assurer que tout le contenu dessiné reste à l'intérieur des limites de la vue. Cependant, siself.clipsToBounds = YES
n'a pas résolu le problème, cela signifie probablement que le problème se situe ailleurs. Néanmoins, assure-toi que toutes les vues subordonnées sont correctement configurées pour ne pas dépasser les limites de la vue parent.Layer-Backed Views : Si ta vue utilise des calques (
CALayer
), vérifie que les propriétés du calque sont correctement configurées. Parfois, des problèmes d'affichage peuvent survenir si les calques ne sont pas configurés correctement pour la nouvelle version de l'OS.Debugging avec Instruments et NSView : Utilise les outils de développement comme Instruments pour profiler l'application et vérifier si le rendu des vues est interrompu d'une manière ou d'une autre. Les logs de debug avec
NSLog
peuvent également aider à vérifier si certaines parties du code ne sont pas exécutées comme prévu.Compatibilité et Deprecation : Vérifie la documentation de MacOS 14.5 pour voir s'il y a des changements ou des dépréciations qui pourraient affecter ton code. Parfois, des fonctions ou des comportements peuvent être modifiés dans les nouvelles versions de l'OS.
Tests de Dessin Simplifiés : Simplifie temporairement le code de dessin de ce mode pour voir si un dessin minimaliste fonctionne. Par exemple, essaie juste de dessiner un simple rectangle ou une ligne pour voir si cela s'affiche correctement.
Coordonnées et Transformations : Assure-toi que les coordonnées et transformations utilisées pour dessiner les carrés sont correctes. Un changement dans le système de coordonnées pourrait être à l'origine du problème d'affichage.
Voici un exemple de vérification de base pour le code de dessin en Objective-C :
Si après toutes ces vérifications le problème persiste, il pourrait être utile de consulter les forums de développeurs Apple ou de soumettre un ticket auprès du support technique Apple pour voir si d'autres développeurs ont rencontré un problème similaire avec MacOS 14.5.
Merci, je regarde tout ça. Je vous tiens au courant.
Je viens de modifier ceci : j'avais laissé un "vieil" NSAlert dans cette NSView, mais dans une autre fonction que celle du dessin. (J'avais déjà remplacé tous les autres il y a longtemps mais avais oublié celui-là) J'ai remplacé le code par le nouveau de type :
NSAlert *alert = [[NSAlert alloc] init]; [alert addButtonWithTitle:@"OK"]; [alert setInformativeText:@"...."];
Apparemment le bug a disparu. L'affichage est redevenu normal.
Merci Rocou!
J'ai parlé un peu vite... Le problème est revenu!! Je cherche encore
C'est difficile de répondre sans voir de code.
Que fais-tu de particulier dans ce mode? Utiliserais-tu une couleur "système" ?
Merci Céroce pour ton message. Depuis le début tu m'aides beaucoup à créer ce synthétiseur inhabituel, et je t'en remercie.
Voici le code qui pose problème : les points couleur sur le NSView correspondent à des timbres dans le moteur audio. Ceux-ci sont parfaitement joués bien que le NSView ne s'affiche pas du tout. (les deux moteurs sont indépendants de toute façon, c'est normal).
Un coup le code fonctionne, un coup non.
Je ne voulais pas vous infliger ceci mais bon (en sachant que le code est appelé, que les vérifications NSLog sont OK, etc.)
Plus loin :
Encore une fois, seul l'affichage n'a pas lieu. Si je clique sur un point - bien que non visible - l'éditeur de timbre apparaît!!
Merci par avance pour vos suggestions et votre immense expérience.
Ah oui! Le code aurait besoin d'un bon remaniement! (on peut en reparler si c'est un chantier dans lequel tu souhaites t'investir, mais c'est hors-sujet). Toutefois, il vaut mieux réparer le code avant.
Il n'y a rien qui me saute aux yeux. Mon intuition pencherait pour un état qui ne serait pas rétabli avant le dessin. Quand
-drawRect:
est appelée, leNSGraphicsContext
correspond à la vue, et dans mon souvenir, son GState est réinitialisé (quoique…).En l'absence de chose évidente, voici la méthode que je te conseille:
En activant/désactivant des pans de code, tu pourras délimiter les endroits jusqu'où ça dessine, et finalement cerner la partie qui ne fonctionne pas.
Merci Céroce. En suivant tes conseils je me suis rendu compte que j'avais fait une grosse erreur de débutant.
A un moment du code je faisais :
for (int i = 0; i < 18; i++){ [NSBezierPath strokeLineFromPoint:NSMakePoint(0, ligneA[i]) toPoint:NSMakePoint(cadre.size.width, ligneA[i])]; }
alors que plus haut il est écrit :
float ligneA[12];
Ouhh! Mais Ouhh quoi!!!
Merci et pardon pour le dérangement. (Hi hi hi!!)
Le plus étonnant est que le code ait fonctionné auparavant!
Pas de souci!
Essaie de découper ton code en fonctions; il est trop difficile à suivre en l'état, c'est normal que des erreurs bêtes s'y glissent. Une fonction de 20 lignes est trop longue, 10 ou moins c'est bien.
Il y a beaucoup trop de code répété à mon avis, or qui dit code répété dit souvent oops, y'a un cas où j'ai mal copié ou alors j'ai modifié un, et il faut remodifier partout en n'en oubliant aucun...
Il faudra un peu de travail de refactorisation pour qu'il soit plus lisible et plus facile à maintenir.
Je vois par exemple plein de :
Et seul
likeE5
est modifié.Je conseillerais aussi de ne pas faire du code en une seule ligne.
->
D'utiliser également les short syntax pour les dictionaires/array :
->
Oui, ce sont de bons conseils. Merci. J'en tiendrai compte.