I'm trying to create a simple ImageView that just loads an image from disk, but this isn't working (I put it in my applicationDidFinishLoading):
NSString *file = [#"~/update.png" stringByStandardizingPath];
NSImage *image = [[NSImage alloc] initWithContentsOfFile:file];
[wView setImage:image];
Apparently the image for the NSImageView isn't being set, because if I NSLog [wView image], I get (null). I'm pretty sure I'm making a beginner mistake here, but what?
The file and image load fine; if I draw the image to an NSView it shows up fine. wView isn't nil, and I tried making another project with the default window's view a custom NSImageView subclass whose initWithFrame: calls setImage. Still nothing.
(OP here with an actual account)
So it turns out that setImage doesn't work on an NSImageView that's explicitly constructed in IB, if you get what I mean. I made an NSView subclass that constructs an NSImageView inside it and calls setImage, and that worked fine. Really annoying.
Most likely, wView is nil. The most common reason for this is when a class that's instantiated in the nib with a connection to a view also gets instantiated a second time in code.
Related
I have a simple custom NSView that has a label and an image. Currently the view works quite well (all the thumbs are instances of my custom view):
However, I want to set the opacity of these thumbnails. Setting viewInstance.layer.opacity doesn't work as the layer is nil. When I use [viewInstance setWantsLayer:YES] first somewhere, and I set the opacity, the opacity of the text changes (it is displayed correctly), but the image view disappears altogether:
I've tried creating a layer first, assigning it, and then calling setWantsLayer: after reading this question: How to add a CALayer to an NSView on Mac OS X but nothing changed:
CALayer *selfLayer = [[CALayer alloc] init];
[selfLayer setFrame:CGRectMake(0, 0, 100, 100)];
[self setLayer:selfLayer];
[self setWantsLayer:YES];
I've tried all combinations of creating a layer and displaying it for the image view too (just calling setWantsLayer:, creating layer and then assigning it, calling display method of it), but still nothing changes:
[self addSubview:self.imageView];
CALayer *imageLayer = [[CALayer alloc] init];
[imageLayer setFrame:CGRectMake(0, 0, 100, 100)];
[self.imageView setLayer:imageLayer];
[self.imageView setWantsLayer:YES];
I've tried adding the image view's layer as a sublayer of the main view and then displaying it:
[self.layer addSublayer:self.imageView.layer];
[self.imageView.layer display];
[self.layer display];
But still, the images won't display, whereas the text always displays correctly. When I comment out the code about assigning and wanting layers, images display again, but obviously, I can't use the layer opacity. I am on OS X Mavericks with OS X SDK 10.8. What am I doing wrong?
UPDATE: I ended up getting rid of NSImageView completely and drawing the NSImage directly into the layer by setting the layer's contents property. However, this is just another approach which solved my problem for this project, it still doesn't answer the original question.
I ended up getting rid of NSImageView completely and drawing the NSImage directly into the layer by setting the layer's contents property. However, this is just another approach which solved my problem for this project, it still doesn't answer the original question.
I've made an NSWindow in Interface Builder. Inside this window is an NSScrollView and inside that is a custom NSView.
The NSScrollview fills the NSWindow and the custom NSView fills the NSScrollview.
When the custom NSView is sent the awakeFromNib method its bounds are 0,0 and 256x373 as I'd expect, filling the scrollview.
However later I change the size of the NSView to be larger than 373high but it never changes size in the scrollview.
I've tried setting the frame, I've tried setting the bounds, but nothing makes it change.
Except, when I tried changing the intrinsicSize of the custom NSView it did change, but it made the NSWindow and NSScrollview change sizes as well to fit the new size of 256x1452
Can anyone tell me where I might be going wrong?
Is it something to do with the constraints set on the Scrollview or the NSView? I haven't set any but when I added the items in Interface Builder they were automatically added for me
[EDIT]
I've changed it so that the custom NSView is created programmatically and added to the NSScrollView with setDocumentView: and everything works as I expect. So I guess technically I've solved the problem, but I'd still like an explanation on why it's not working via Interface Builder if anyone knows.
I have a partial solution, which also causes me to pose an additional question. I had a similar issue, I needed to programatically change the size of a view embedded in a NSScrolView.
This code works, need both methods
-(void)markViewSizeChanged /* Works correctly */
{
[self setFrameSize:currentViewSize];
[self setBoundsSize:currentViewSize];
[self setNeedsDisplay:YES];
}
-(NSSize)intrinsicContentSize // Override of class method
{
return currentViewSize;
}
Note: MUST set currentViewSize in awakeFromNib
Now for the curious part. If I reverse the order of the two calls setting the frame and bounds, the size of the embedded view is correct, but the scaling factor of objects drawn is off.
-(void)markViewSizeChanged /* DOES NOT work correctly, scaling in drawing off */
{
[self setBoundsSize:currentViewSize];
[self setFrameSize:currentViewSize];
[self setNeedsDisplay:YES];
}
I've been looking for hours now and i cant find a solution. i have an imageview, i have declare it as an IBOutlet, inside that imageview i have already put an image using the interface build of xCode 4.2.
Now my quesion, whats the line of code that it can change the image of the imageview?
The old ones like UIImage *image = [UIImageView imageNamed:#"image2.png"];
its not working because it says that *image is unused variable. it also gives me error at imageNamed it says No known class method for selector 'imageName'
Whats the new code in 4.2? or is it me doing something wrong?
myImageView.image = [UIImage imageNamed:#"image2.png"];
That should do it. UIImageView has an image property that you can set, either as above, or using the -setImage: method that the property provides. Also, from the docs:
Setting the image property does not change the size of a UIImageView.
Call sizeToFit to adjust the size of the view to match the image.
Your other questions:
its not working because it says that *image is unused variable.
In the code you provided, you're assigning the image to a local variable. If you don't then do something with that variable, there's no point in that code. Instead, assign the image to the image property of your image view, as described above.
it also gives me error at imageNamed it says No known class method for selector
'imageName'
That just looks like a typo in your code. The lack of a 'd' in 'imageName' is surely the problem.
Whats the new code in 4.2?
Nothing has changed with respect to setting the image of an image view, as far as I know. I think you've just got a couple little issues in your code.
It's you doing something wrong. You are mixing up UIImage and UIImageView classes. The former is for representing image data in memory. The latter one is representing UIImage instances in a view.
You should change your line to:
imageViewOutlet.image = [UIImage imageNamed:#"image2.png"];
Notice that I'm using UIImage class to assign the image to UIImageView's image property.
You are trying to declare a new variable and not using the ivar you declared with the IBOutlet
You need to assign
[UIImage imageNamed:#"image2.png"]
to the image property of the ivar of the IBOutlet.
For example if your IBOutlet is defined:
#property (nonatomic, strong) IBOutlet UIImageView *imageView;
assign like so:
imageView.image = [UIImage imageNamed:#"image2.png"];
This Works fine for me. oldImage is the IBOutlet of UIImageView. The setCellImage method is inside the Custom UITableViewCell Class.
- (void)setCellImage:(UIImage*)newImage{
[self.oldImage setImage:newImage];
}
I'm using an NSViewController class with a single view in it to display a progress indicator bar and some text fields. I'm trying to use progressIndicator setMaxValue:and theTextField setStringValue: but neither of these are doing anything.
I've done this before and I've checked and rechecked, it's fairly straightforward, the fact that it's not working makes me think that it has to do with the fact that the class is NSViewController. Which is why I tried
Timers *aTimer = [[Timers alloc] init];
[aTimer.timerNameLabel setStringValue:#"name"];
[aTimer.progressIndicator setMaxValue:x];
in the app delegate which is an NSObject class, but that didn't work either.
I've tried looking around the NSViewController documentation but I can't find anything that says it can't set those values so I don't know what's happening. What am I doing wrong?
You probably want to use -initWithNibName:bundle: instead of a regular init to initialize your custom nib.
EDIT: It seemed the problem was due to the view not being queried before getting other objects. By calling [myController view] you actually load the nib, which isn't done automatically when you initialize the view controller. So before you can use any element of the view, you need to call [myController view]
I created UIImageView with the help of Interface Bulder. Now I want to place label inside it (as its subview). In code I can type something like: [myUIImageView addSubview:myUILabel]; But can I do it with the help of IB? I found the solution for UIView, but can't find something similar for UIImageView.
You cannot add a subview to UIImageView in interface builder for reasons only known to Apple! You are right in saying that you can addSubview programmatically, but then, the overhead of setting autoresizing masks and placements of subviews should all be handled in code, which is cumbersome.
So there is an easy workaround. Instead of dragging an instance of UIImageView in the nib, just drag a UIView and change its class to UIImageView from UIView (cmd+4 option of inspector). The only difference you find in the nib for default imageView instance and your new UIImageView subclass instance is: you cannot set image to your new imageView from nib (cmd+1 option). So, in the -viewDidLoad method of its appropriate viewController, set image to this outlet of UIImageView.
By doing so, you are free to add subviews to your "now UIImageView" instances in interface builder, which is much easy.
I would like to add answer.
While it sucks you cannot add subview to UIImageView, you can get the same effect by incorporating UIView with transparent (clear color) background.
Then put the UIImageview BEFORE it.
So the UIView has the subviews and the UIImageview is the background of the UIView.
I think that's apple's intent.
Here is a screenshot:
Here is the result:
Don't forget to set background as clear color
Now if someone could actually point me to a tutorial how to do this it'll be great. I spent hours doing it the checked answered way. The checked answer is a fine answer but very unintuitive because you can't see your background image clearly while working. I think mine is the proper way to do so.
In latest XCode(4.5) there is an option to drag and drop the required controls to the parent.
It is quite easy.
Attached screen shot for the same. I dragged the Label/TextField and Button to UIImageView
Use this code:
UIImage *image = [UIImage imageNamed:#"background.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
[self.view insertSubview:imageView atIndex:0];
(replace background.png with image) (replace atIndex:0 with whatever place in the .index root you want to insert the image and your off.