0

I got a problem with Cocoa and its View redraw hierarchy.

I'm currently testing displaying (audio) levels in a meter style control and I'm using the MeteringView class from MatrixMixerTest example project from apple. This class is drawing the meter and only drawing the difference what got changed which looks like a very efficient class.

My project is splitted into 2 splitviews, in some are NSCollectionViews (Scrollview, Clipview) and in others are only static views. If I add the meter to those "static" views they work fine when these views call setNeedsDisplay:YES. If a meter is added to the view of a CollectionView Item it gets rendered, but loosing its drawn "old level" parts and its corners/background. I think this happens because the CollectionView item gets also called to be redrawn (which has a background image) and everything is gone. It is drawing some parts whats currently changing (the drawing works).

Is there a way to prevent the Item itself to be redrawn? Or, I dont know why it is not happening in those static views, because those views also have background images but do not draw over the meter.

Are there some tricks or whats different in a CollectionView than in a "normal" view?

EDIT: After reading about isOpaque (MeteringView isOpaque = YES) means it should not call the parent views drawRect if set to yes. Well that works for the static views, those MeteringViews do not call parents drawRect, but those in a CollectionView do however. I dont know why.

EDIT 2: I gave this topic another title, because isOpaque=YES in MeteringView is not stopping calling the parents drawRect in a CollectionView, in a normal view it is working. Are there some things to know about? I have to stop redrawing the CollectionView Item because thats the problem.

Thanks in advance guys

Benjamin

bennibeef
  • 105
  • 2
  • 9

1 Answers1

0

isOpaque is just hint to the system. It does not prevent other views from drawing their contents, it only means that it can sometimes skip making other views update their contents.

If your view is opaque, it should draw itself as opaque and completely fill its bounds.

Dave Wood
  • 13,143
  • 2
  • 59
  • 67
  • To tell a bit more about my situation: I have a timer which is getting audio levels and sets those to the MeteringView wich then is drawing the Meter. MeteringView isOpaque. But if MeteringView which is a subview of a CollectionViewItem View it calls the drawRect of the CollectionViewItem. I know this because a NSLog in drawRect of the Item is getting fired with the timer. And because the Item's View gets called after the Meter itself it draws the background image again over the Meter and the Meter is just a moment there. I have no idea how to solve this. – bennibeef Feb 15 '14 at 20:13
  • If the MeteringView is a subview of the cell, the cell's drawRect will be called first, then the MeteringView's drawRect will be called. – Dave Wood Feb 15 '14 at 21:02
  • I just tested this, the CollectionViewItem gets called first then the Meterings Subview. Well, is there any way to prevent this? Because I dont want to redraw the Cell/Item I think this hitting the perfomance as well. I just want to redraw the Code in MeteringView but not the whole Item/Cell – bennibeef Feb 16 '14 at 12:14
  • Unfortunately anytime the drawRect method is called, you need to do the draw the view, otherwise you can have messed up views. You only need to draw inside the rect that is passed in, and it's up to you to decide if it's more efficient to just draw the entire view or only update inside the rect given. – Dave Wood Feb 16 '14 at 22:13
  • I solved it, there was a View "under" the CollectionView which was drawing a background image which caused every view to redraw -- Thanks! – bennibeef Feb 20 '14 at 15:50