Changing an NSImage in XCode - this line of code not working - objective-c

I am having a problem that is eating me alive. I really hope I am just missing something small here. It appears to be a rather "n00b" issue.
I have a blank NSImageView that I want to display a picture when a button is pressed — simple as that.
Here is my line of coding
NSBundle *mb = [NSBundle mainBundle];
NSString *fp = [mb pathForResource:#"tiles" ofType:#"PNG"];
NSImage *image = [[NSImage alloc] initWithContentsOfFile:fp];
if ( [image isValid] ) {
[selection setImage:image];
[selection setImageScaling:NSScaleProportionally];
}
Whereas,
tiles.PNG is a resource in my bundle
and if [image isValid] is satisfied, because I've inserted dummy code into the clause and had that work
selection is defined in my header file as follows
IBOutlet NSImageView *selection;
It is also linked up to the application delegate in IB.
I have a feeling I might not be linking it properly?
WHy wouldn't the image display? If anyone can see an error - or provide me with working code - I would be soooooo thankful
Brian

It's not a linking issue—your app wouldn't even launch (assuming it even links successfully) if you'd failed to link against Cocoa or AppKit.
More probably, either you haven't connected the outlet to your image view in your nib, or you haven't loaded the nib yet. The way to check this would be to NSLog the value of the imageView pointer, using the %p formatter.

I had a similar issue where my view wasn't displaying, and it turned out that the view was hidden. This was a setting in the view properties in Interface Builder. Just a punt, but give it a go.

You need to use the debugger and see what's going on as it runs. Is fp nil? Is image nil? Is selection nil? The debugger is your friend.

did you remember to send -setNeedsDisplay to the NSImageView after you set the image?

Related

Something very strange UITextView in iOS 7 ... not in iOS 6?

I'm creating a UITextView:
greetingTextView = [[UITextView alloc] initWithFrame:greetingRect];
Using it fine, but when the ViewController it is attached to deallocs I'm getting memory leaks ONLY in iOS 7 ? I'm even Nulling the greetingTextView out of desperation but to no effect:
[greetingTextView.undoManager removeAllActions];
greetingTextView.delegate = Nil;
[greetingTextView removeFromSuperview];
greetingTextView = Nil;
The leaks are in this image:
So it appears something to do with the UITextView UndoManager ? But why only in iOS 7 ?
Regards
I face a similar situation, and after hunting around and some trail and error, i noticed that when ARC is disabled for that particular file, the strange behavior stopped and no memory leaks occurred. check here for how to disable arc for a particular file
You'll need to empty out the undo manager if you want any object you add to it to be released.
Review the steps laid out in this document :
https://developer.apple.com/library/ios/documentation/cocoa/Conceptual/UndoArchitecture/Articles/CleaningUndoStack.html
It did occurs to me once when I didn't specify the delegate of a UITextField. After the delegate was set everything went normal. Hope it helps. BTW, I'm using Storyboard.

NSImageView setImage causing NSView not correctly initialized

I'm writing a networking program which sends an image from an iPhone to a Mac. I have the connection going fine, and passing data alright, but my problem is when I have the image sent over I try to display it and get the following warning:
NSImageView(0x101321fd0) - NSView not correctly initialized. Did you
forget to call super?
Here is the code, it's the "setImage" command throwing the error.
This is my first major venture into Objective-C, I'm worried I messed up something with the xib but I can't be sure.
imageView = [NSImageView alloc];
[imageView setImage:theImage];
NSLog(#"Should be able to see image now..");
If this is too vague for a direct answer then any tips, references or tutorials you can guide me to would be very welcome.
Thanks for your time.
You forget to init the imageView.
imageView = [[NSImageView alloc] initWithFrame:someFrame]

UIImage causing memory leaks

Instruments is telling me that alot of memory is being allocated when I rapidly set the image name of a UIImageview in my app. I have a UIImageView that changes its image name every frame in my game. When profiled with zombie checking in instruments, the app seems to be constantly gaining live bytes at an enourmous rate. Is there a way that I can deallocate the UIImageView's current image to stop it from doing this? I am using ARC.
My code to assign the UIImageView's image is as follows:
aPlanet.image = [UIImage imageNamed:tempPlanetName];
Where aPlanet is the UIImageView and tempPlanetName is the name of the image. This is called every frame.
[UIImage ImageNamed:] method loads the image into image view and adds this newly created uiimage object to autorelease pool. To get rid of this problem you should use -
NSString *imgPath = [NSBundle mainbundle] pathForResource:#"imageName" ofType:#"png"];
aPlanet.image = [[UIImage alloc] ]initWithContentsOfFile:imgPath];
if you are using arc then you don't need to bother about releasing this newly allocated object of uiimage which was created using initWithContentsOfFile: method.
When you use UIImage imageNamed: it will load and cache that image file. This is intended for reuse of icons and other image resources that will be utilized more than once in your application.
Apart from it seeming somewhat unusual to update an image view with a new image every frame, you should look into alternative means of loading images that you will not need more than once - or even if you do, when you need more control over its lifecycle.
For example have a look at UIImage imageWithContentsOfFile: (documented here: Apple Developer Library Reference). It explicitly states that this method will not do any caching of the image contents.
I hope this helps you, but for every frame I doubt that your performance will be good enough with this approach, but this is probably the topic of a different question should the need arise.

I added a WebView to my Cocoa app and it's generating an error

I added a WebView to my app and I'm loading a page into it using this code:
-(void)awakeFromNib{
NSString *resourcesPath = [[NSBundle mainBundle] resourcePath];
NSString *htmlPath = [resourcesPath stringByAppendingString:#"/calendarHTML/test.html"];
[[webView mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:htmlPath]]];
}
However, when I run the app I receive the following error:
Layout still needs update after calling -[WebHTMLView layout].
WebHTMLView or one of its superclasses may have overridden
-layout without calling super. Or, something may have dirtied
layout in the middle of updating it. Both are programming errors in
Cocoa Autolayout. The former is pretty likely to arise if some
pre-Cocoa Autolayout class had a method called layout, but it should be fixed.!
What is causing this problem?
This is caused by the fact that the nib containing the window that you have placed the WebView into is using the new Auto Layout feature, introduced in Lion.
When a nib file has auto layout enabled, the window will call the -layout method on all NSView objects in the window.
This causes a problem with WebView because it had a method named -layout before it the method was added to the NSView API in Lion, and WebView's layout method does not understand auto layout.
Probably the best fix for the time being is to use the old autoresizing mask method of laying out the views in your window. As Xcode now creates nib files with autolayout enabled, you need to disable it yourself.
You can do that in the File inspector for your nib file, by disabling the Use Auto Layout checkbox.
After you do this, you'll need to make sure that all the views in the nib have the correct autoresizing settings in the Size tab of the view inspector.
Note that you can safely ignore that log message for WebViews.
I am not sure about the case of WebView but If you are using any custom class (like subclass of UILabel) and you are using the method :
- (void)updateConstraints
{
}
then definitely It will crash your app. Best solution is to remove this method and write your required changes in 'awakeFromNib' method. Hope this help someone else who is getting this crash in custom class.

show quick look preview in a view

I am trying to show the preview of a file in a View instead of in a panel. All examples I found are about QLPreviewPanel. :(
Thanks in advance for your help.
Starting in OS X 10.7, there is a public API for this: QLPreviewView.h, which is part of the QuickLookUI framework (which is part of the Quartz framework). There doesn't seem to be documentation on it, but the header file provides some basic info.
It seems like Apple really wants you to use the QLPreviewPanel; the only possibility I see is "scraping" the preview, by setting the panel to layer-backed and getting the contents of the correct sublayer. Something like this (although I haven't gotten it to work):
[[[QLPreviewPanel sharedPreviewPanel] contentView] setWantsLayer:YES];
[[QLPreviewPanel sharedPreviewPanel] makeKeyAndOrderFront:nil];
NSLog(#"layer: %#", [[[QLPreviewPanel sharedPreviewPanel] contentView] layer]);
// I believe there are two sublayers
id QLcontents = [[[[[[QLPreviewPanel sharedPreviewPanel] contentView] layer] sublayers] objectAtIndex:0] contents];
NSLog(#"contents: %#", QLcontents);
[myView layer].contents = QLcontents;
[myView layer] setNeedsDisplay];
Not a final solution by any means (this doesn't work as is) but maybe it'll point you in a useful direction.
UPDATE: Just stumbled across a category on NSImage, written by a fellow named Matt Gemmell, which uses QLThumbnailImageCreate. Look for "NSImage+QuickLook" on his source code page. He seems to imply that the QuickLook Panel actually uses QLThumbnailImageCreate. I think that function may be the best way to go. The category might make your life a little easier.
I've made some headway with this. The sublayers' contents were nil. But the old-fashioned subviews work:
[[[QLPreviewPanel sharedPreviewPanel] contentView] setWantsLayer:YES];
[[QLPreviewPanel sharedPreviewPanel] makeKeyAndOrderFront:nil];
NSArray* subviews = [[[QLPreviewPanel sharedPreviewPanel] contentView] subviews] ;
for (id subview in subviews) {
// The first view is the one we want, which is an unsubclassed NSView.
// The second is a QLPreviewTitleBarView. However, instead of relying
// on that order, we check for the class.
if ([subview isMemberOfClass:[NSView class]]) {
NSLog(#"frame of subview: %#", NSStringFromRect([subview frame])) ;
// The following statement will *remove* the desired subview from
// the QLPreviewPane and place it into myWindow instead.
[[myWindow contentView] addSubview:subview];
break ;
}
}
It even seems to update myWindow when I send -reloadData to the QLPreviewPane. I'm feeling slimy. Not sure what to do next, though. One problem is to deal with the arbitrary size of the subview. One of the reasons why I don't like QLPreviewPane is that there is no control over the window size; it gets a view from the generator at some arbitrary size and splats it on the screen. I guess I could put it into a scroll view. Another issue is how to deal with the QLPreviewPanel which is still on the screen. Maybe set its frame origin to off-screen But I need to go work on another task right now. Any further ideas would be appreciated.
Later. I think this approach is going to be to problematic. First, I tried to get rid of the QLPreviewPane window by sending it a setFrameOrigin:NSMakePoint(10000, 10000). Result: [QL] Assertion failure ([event window] == window) - Wrong window in event. Then I tried to omit the call to -makeKeyAndOrderFront: and instead skip up to -reloadData. Result: [QL] QLError(): -[QLPreviewPanel reloadData] called while the panel has no controller - Fix this or this will raise soon. See comments in QLPreviewPanel.h for -acceptsPreviewPanelControl:/-beginPreviewPanelControl:/-endPreviewPanelControl:.
The second error is understandable, however it indicates that the QLPreviewPanel will not try to find its data source, as it does, until it is made key or ordered front. The first assertion, however, indicates that, besides not providing a proper API to get the preview data directly, maybe Apple has laid some traps for the casual hacker like me.
If I come back to this, next time I'll try the more serious hack proposed by Ken Apeslagh.