Custom NSPopUpButtonCell drawImage:withFrame:inView not getting called - cocoa

I have a custom NSPopUpButtonCell and I'm trying to override drawImage:withFrame:inView. Strangely, the drawImage method is never called, but the image appears on screen. What am I missing?
I've checked to make sure my cell is properly installed -- I am getting drawWithFrame:inView:controlView messages.
Note that I'm trying to compensate for an image only gradient-style button not properly centering it's image (it's 1 pixel to the left of where it should be).

NSPopupButtonCell inherits from NSMenuCell and NSMenuCell has a method called drawImageWithFrame:inView: which might be what you're looking for. It has several other drawing methods too so check those and see which one is being called.

Related

Mapbox Callout Image

I have a question about Mapbox Callouts. I was wondering if it was possible to turn the standard white callout background into an image. I want my annotation callout to have this image and when clicked segue to a view controller displaying a large image of the location. I would normally use a right or left calloutAccessoryView button, however, I am already using these two buttons for different functions. Does anybody know if this is possible? I have done a fair bit of research and it seems that there are no definite ways of creating this (although it seems extremely simple in MapKit!!).
Yes, you can do this, it's built into the Mapbox API. You use the MGLMapViewDelegate method optional func mapView(_ mapView: Any!, tapOnCalloutForAnnotation annotation: Any!) From the website:
This method is called when the user taps on the body of the callout view, as opposed to the callout’s left or right accessory view. If the annotation has a custom callout view via the -mapView:calloutViewForAnnotation: method, this method is only called whenever the callout view calls its delegate’s -[MGLCalloutViewDelegate calloutViewTapped:] method.
If this method is present on the delegate, the standard callout view’s
body momentarily highlights when the user taps it, whether or not this
method does anything in response to the tap.
Example usage

isOpaque not stopping passing to parents drawRect

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

GLKViewController inside a ViewController inside a Navigation Controller

I'm not certain why this isn't working, but maybe someone here can shed some light on what the problem might be. I am working on game based on the XCode OpenGL template. I have a small GLKViewController with a view that does not take up the full screen area, so I'm creating it inside another UIViewController that does have a full screen view as a container. This works, and my update/draw methods are called as I would expect.
However, when I take my container view (with the GLKViewController inside it) and try to initialize it inside a UINavigationController as the rootViewController, the update method for the GLKViewController never gets called, and the draw methods is called exactly once.
This view hieracrhy works fine if there is no UINavigationController, however as soon as it's added, it does not work. I have verified that the viewDidLoad for the GLKViewController is being called. The context is initialized, because I can see the first frame, but after that it looks like the draw/update messages are being swallowed up. I can get around this by not using a navigation controller for this particular view, but I'd like to understand why this does not work. Any idea on what might be happening to the draw/update functions?
I recently managed to get GLKViewController running inside a Master/Detail view controller and faced this same problem.
Did you check that GLKViewController is not paused?
This would fire the update loop:
self.paused = NO;

Changing selection state of IKImageBrowserView

Hey guys, I've just migrated my image selector from NSCollectionView to IKImageBrowserView. I've got almost everything set up the way I want it, except for the selection ring. I don't like the greyed out background that IKImageBrowserView defaults to, and I wanted to do a yellow stroke around the edge of my selected image to indicate it's selection (like in iPhoto). Is is possible to override the draw state of IKImageBrowserCell? I haven't been able to find any way to do it yet. It doesn't have the simple drawRect methods that I'm used to. Any help would be appreciated. I'm assuming I have to use CALayers?
I overrode - (CALayer *)layerForType:(NSString *)type and tried just as a test, setting the layer corner radius to 0, but it didn't seem to change anything. The method is being called because if I throw a breakpoint in it, it stops there. However, even if I return nil from that method, it still draws the images like usual.
Thanks!
That is the right method for customizing the IKImageBrowserCell.
Using CALayers and configuring different attributes, you can control many facets of how the images are presented.,
A layer of type = IKImageBrowserCellSelectionLayer is what you will want to change to have the display behave and present as you wish.
Here's a link to Apple's sample code project that will get you started

How can my code get notified when the user pastes or drags an image into NSImageView?

I have an instance of NSImageView. I have told InterfaceBuilder to allow the user to paste or drag an image into this view. This works. However, I don't see a way in the NSImageView or related documentation to get notified when this actually happens. I was expecting a delegate or some such, but I have been unable to find it. Any ideas?
This is what Cocoa Bindings does best.
Instead of talking to the view, simply have a property whose value is an image, and bind the image view's image binding to it; then, when you want to change the image in the image view yourself, all you have to do is set the value of the property, and the image view will notice the change.
The user pasting or dragging into the image view is essentially the same thing, partly in reverse: The paste or drop will change the value of the image view, which will then set the value of your property, which will cause anything else bound to it to notice the change and pick up the new value as before.
Aside from ripping out your existing send-explicit-messages-to-views code, this will require almost no code work: The only code you need is for your property. You'll hook up the Binding in IB.
See the Key-Value Coding Programming Guide and the Cocoa Bindings Programming Topics.
As for me the better way to override function
-(void)paste:(id)sender
But only if you have it in NSView based class which has NSResponder as parent

Resources