Custom ImageView doesn't display image - ios

I have created on custom imageView class. And am trying to override the image setter method. But for some reason the imageView is not displaying anything, though the image is getting assigned onto it.
The code is as follows:
#implementation CustomImageView
#synthesize image = _image;
- (void)setImage:(UIImage *)correctedImage
{
_image = correctedImage;
}
#end
I have tried removing the setter method. i.e Without overriding any method at all. Still it is not displaying anything. :(

The problem was that I had to set the image by passing it to the super.
[super setImage: correctedImage];
Simply, setting it from the base class doesn't seen to work :/

Related

Initialize a subclass from a superclass in Objective C

I have created a UIImage subclass named MyImage.
MyImage obviously responds to every method originally implemented by UIImage. I would like to completely hide UIImage implementation, so for example MyImage redeclares a method like:
- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets;
to
- (MyImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets;
I attempt to write the implementation like:
- (MyImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets {
UIImage *original = [super resizableImageWithCapInsets:capInsets];
MyImage *result = [[[self class] alloc] initWithUIImage:original];
return result;
}
- (id) initWithUIImage:(UIImage *)image {
// HOW TO IMPLEMENT THIS METHOD???
}
but I stopped at initWithUIImage method. How can I achieve such a behavior without using composition?
You don't want to do that. Its a lot of unnecessary code with a high risk of breaking something. Don't redeclare these methods. Is there a specific reason that you want to do that?
The problem here is simple and it is called: INHARITANCE.
Do not do inaritance but provide some class which owns UIImage. It will be easier and more relialeble.
Another issue is that you didn't expain why you need change something in UIImage! I'm prety sure yuo are trying to resolve some simple problem in nasty way.
The answer is that you cannot do what it seems like you're attempting to do. MyImage IS a UIImage, meaning it implicitly has all methods and properties of UIImage. You can add new ones, but never remove existing ones.
And UIImage is used all over the system APIs. What exactly are you attempting to accomplish by doing this?

Explain data management of storyboards?

I have this UIImageView in one of my view controllers
I've set it as a subclass of this cutsom UIImageView, ABProfileImageView
Here's that ProfileImageView class:
#import "ABProfileImageView.h"
#implementation ABProfileImageView
-(id)init {
self = [super initWithImage:[UIImage imageNamed:#"X4Hibreb.jpeg"]];
if (self) {
self.image = [UIImage imageNamed:#"X4Hibreb.jpeg"];
}
return self;
}
#end
and I have an image name X4Hibreb.jpeg in the project folder,
So I'm not sure why the imageview doesn't have the picture I set it to be? I think it's some higher understanding thing that I don't get, I usually do programmatic UI's, this is the first time I'm using a storyboard.
You have implemented init, however you also need to implement initWithCoder:, which is the initializer called when decoding objects from NIB files and storyboards.
Usually a good practice is to move common code from init and initWithCoder: to a _commonInit method and call it in the init.
You need to initialize the imageview.

image comparison is not working after application did become active

I am using following for comparing button's background image.
if([[button currentBackgroundImage] isEqual:[UIImage imageNamed:#"image1.png"]]){
// do something
}
The code works fine when application is in active state. But when app gets back from idle state the above code doesn't work.
Any idea why this happens?
Thanks
The images don't compare after you come back from background because you're creating a new instance of that image for your comparison by using [UIImage imageNamed:#"image1.png"] (the images are compared by looking at their hash values, not by looking at the actual image contents). If you create a property for your image, when you first use imageNamed:, and use that in the comparison, it should work properly. So, I tested with this code, and it returned true when I checked after coming back from the background (I set the button's background image in IB).
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UIButton *greenButton;
#property (strong,nonatomic) UIImage *greenPng;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.greenPng = [UIImage imageNamed:#"Green.png"];
}
- (IBAction)checkImages:(id)sender {
BOOL isTheSame = [self.greenButton.currentBackgroundImage isEqual:self.greenPng];
NSLog(#"The images are %#",isTheSame? #"the same" : #"different");
NSLog(#" button image hash is %d",self.greenButton.currentBackgroundImage.hash);
NSLog(#" imageNamed image hash is %d",self.greenPng.hash);
}
After Edit: I'm not sure my explanation is quite correct -- in one run of the app, you can make multiple calls to imageNamed:, and all the images that are returned will have the same hash (including the image you pick in IB, if you do it that way). I think this is due to cashing. In any case, when you come back from the background and call imageNamed: again, it returns an image with a different hash.

Setting up a UIImageView subclass between loading from a NIB and willMoveToSuperview:

I have a UIImageView subclass (AdImageView) placed in my view controller's NIB. This AdImageView knows how to go off and load a remote image into itself using some asynchronous calls invoked from willMoveToSuperview. I know this works because if I add the AdImageView through my own code and tell it before it gets added to a super view which image to load it works great. However when switching setup to use a NIB, I'm not sure when to set the remote path on the AdImageView.
I can't do it in any of the VC's init methods, because the NIB objects aren't yet setup. By the time the VC's viewDidLoad gets called AdImageView's willMoveToSuperview: is already called. I tried setting some IBOutlets telling AdImageView who to ask for the image url, but that is also called after AdImageView's willMoveToSuperview:.
I could start the remote image loading in AdImageView's awakeFromNib, but I want to continue to also have the option to programmatically add an AdImageView to a view controller. Putting the code there then puts me in a situation where I could remote image loading reinvoked in willMoveToSuperview: unless I protect it with some sort of flag that just feels ugly.
So where does state setup code for Interface Builder objects normally occur?
(Sorry there is no code for this question, but it's more about strategy)
This doesn't really sound like a view's job but you could do something like this
#interface AdImageView : UIImageView
#property (nonatomic, copy) NSString *path
#end
#implementation AdImageView
- (void)setPath:(NSString *)path
{
if (_path != path) {
_path = [path copy];
[self loadAd];
}
}
- (void)didMoveToSuperview
{
[super didMoveToSuperview];
[self loadAd];
}
- (void)loadAd
{
// This will only load when the view is on screen
if (self.window) {
// ... fetch ad etc
}
}
#end

iOS w/ storyboards & ARC: Controller property not initialized

The problem is simple to explain but difficult for me to resolve. I have a property that is NEVER initialized.
First of all, I'm using the iCarousel custom class in order to display some images for my app. In one of its delegate methods (the one that it uses in order to know which view is going to show at some index), I use this code:
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
{
if(!view)
{
CustomController* controller = [self.storyboard instantiateViewControllerWithIdentifier: "identifier"];
//BTW, the CustomController is initialized properly. Its instance is not nil after the initialization.
controller.imageView.image = [UIImage imageNamed: "something.png"];
view = controller.view;
}
return view;
}
As you can see, the view that I show in my carousel is a custom view with its own controller. I initialize it using the storyboard method and then I just set the image in my imageView property, which is, obviously, an UIImageView.
Don't get excited and say that I'm not initializing my imageView, because I have a custom getter in my "CustomController" class. Like this:
//interface (.h)
...
#property (nonatomic, strong) UIImageView* imageView;
...
//implementation (.m)
...
#synthesize imageView = _imageView;
...
- (UIImageView*) imageView
{
if(!_imageView)
_imageView = [[UIImageView alloc] init];
return _imageView;
}
...
Believe it or not, even if I put a breakpoint in the "_imageView = [[UIImageVIew alloc] init];"... the program executes that line but the _imageView remains nil. ¿Why?
I don't want to know "How to set my property", so please don't give workarounds for this... what I want to know is "Why my property is never setted and remains nil always", what's am I doing wrong?.
I've also tried to use my imageView as an IBOutlet... but even if I link it to an imageView in the Interface Builder and check its value after the "viewDidLoad", it still remains nil.
P.S: Btw, I'm using ARC (yeah, I know is in the title... xD)
Well, it looks like the answer was what borrrden said, the problem was the LLDB debugger. Actually, my property was initialized but the debugger didn't detect it like that, if I change it to GDB I could see it wasn't nil after all. Furthermore, the reason why I had also issues with my child viewcontroller's outlets was because I didn't use the View Controller Container methods in iOS5 (DidMoveParentViewController and those ones).
Kinda tricky.

Resources