UIImageView subclass does not display - iphone

I am using a custom subclass of UIImageView, but I can't figure out why it's not being displayed.
The relevant code from my UIImageView subclass:
-(id) initWithImage:(UIImage*)image{
if(self = [super initWithImage:image]){
}
return self;
}
And from the view controller for the view that will be displaying my subclass:
UIImage *zoomRatateSliderHorizontal =
[[UIImage imageNamed:#"ZoomRotate Slider Horizontal.png"]
stretchableImageWithLeftCapWidth:(75.0)/2-1.0 topCapHeight:0];
scaleHorizontalControl = [[ViewTransformationController alloc]
initWithImage:zoomRatateSliderHorizontal];
scaleHorizontalControl.onScreenFrame = CGRectMake(0.0, 5.0,
self.view.frame.size.width,
scaleHorizontalControl.image.size.height);
scaleHorizontalControl.frame = scaleHorizontalControl.onScreenFrame;
scaleHorizontalControl.offScreenFrame = CGRectZero;
[self.view addSubview:scaleHorizontalControl];
Before I was subclassing, I had no trouble with the following in the view controller:
UIImage *zoomRatateSliderVertical =
[[UIImage imageNamed:#"ZoomRotate Slider Vertical.png"]
stretchableImageWithLeftCapWidth:0 topCapHeight:(75.0)/2-1.0];
scaleOrRatateViewVertical = [[UIImageView alloc]
initWithImage:zoomRatateSliderVertical];
scaleOrRatateViewVertical.frame = CGRectMake(-zoomRatateSliderVertical.size.width,
zoomRatateSliderHorizontal.size.height+5.0+5.0,
zoomRatateSliderVertical.size.width,
465.0 - zoomRatateSliderHorizontal.size.height-10.0-5.0);
[self.view addSubview:scaleOrRatateViewVertical];
Using break points I checked the frame and image being passe to my class, and they both appear to be valid and desired.
Any advice on what I'm doing wrong I'd greatly appreciate.

The Apple Docs read:
The UIImageView class is optimized to draw its images to the display. UIImageView will not call drawRect: a subclass. If your subclass needs custom drawing code, it is recommended you use UIView as the base class.
So I'd subclass UIView and work from there.

Related

addSubview does not work

I will add a label to an Image with addSubview but this does not work.
here the code:
.h
UIImageView *bgimage;
IBOutet UILabel *loadingLabel;
.m
loadingLabel.text =#"......";
bgimage = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,320,480)];
bgimage.image = [UIImage imageNamed:#"Wait.png"];
[self.view addSubview:bgimage];
[bgimage addSubview:loadingLabel];
Screenshot:
"Tisch wird reserviert..." is the loadinglabel and is label shoud be in the UiImage
This is the "Layout" with the code from 2nd answer
Change your code as...
.h
IBOutet UIImageView *bgimage;
UILabel *loadingLabel;
.m
bgimage.image = [UIImage imageNamed:#"Wait.png"];
loadingLabel = [[UILabel alloc] init];
loadingLabel.frame = CGRectMake(0, 0, 100, 50);
loadingLabel.text = #"testing";
[bgimage addSubview:loadingLabel];
It will work.
You cant add a subview to a uiimageview, since drawRect: will never be called.
source:
"The "UIImageView class is optimized to draw its images to the display. UIImageView will not call the drawRect: method of a subclass. If your subclass needs custom drawing code, it is recommended you use UIView as the base class." from the apple docs:https://www.google.de/#bav=on.2,or.r_qf.&fp=90e2434f04e1ee9b&q=uiimageview+class+reference&safe=off
Solution:
As suggested, use a uiview to contain both the label and the imageview, and then bring the label to the top using -bringSubviewtoFront: of UIView. You can also use a UIViews backgroundimage to show your image and then have a label as a subclass in that view. Depends on the Situation you are in, i guess.
EDIT: YOU SHOULD READ THIS:
I misread the question, and it appears that you can add subviews to UIImageView, just like Zev pointed out in his comment. Right now im guessing that -bringSubviewToFront did the trick for you, and that the rest of my answer, while not really harmful, was unnecessary. Im sorry.

How do I move an existing image without Interface Builder

I created multiple images without the use of interface builder. I used this code:
for (Row* row in parser.rows) {
CGRect IphoneFrameImageRect;
IphoneFrameImageRect = CGRectMake(10, 10, 150.0f, 150.0f);
UIImageView *IphoneFrame = [[UIImageView alloc] initWithFrame:IphoneFrameImageRect];
NSString *IphoneFrameurl = [NSString stringWithFormat:#"http://some.url.com/iphone/IphoneFrame.png"];
[IphoneFrame setImage:[UIImage imageWithData: [NSData dataWithContentsOfURL: [NSURL URLWithString:IphoneFrameurl]]]];
[IphoneFrame setTag:(i)];
IphoneFrame.opaque = YES; // explicitly opaque for performance
[self.view addSubview:IphoneFrame];
[IphoneFrame release];
}
I need to move these images to a different location in landscape mode. I did tag each image and it looks I can select the images back using this tag. But how can I gave the image a new coordinate ? I have this code:
-(void)positionViews {
UIInterfaceOrientation destOrientation = self.interfaceOrientation;
int i=4; //Picture with tag=4 for example
UIImage *tempImage=(UIImage *)[self.view viewWithTag:(i)];
// HOW TO MOVE ??
}
I am able to do this with a button using this code:
UIButton *tempButton=(UIButton *)[self.view viewWithTag:i];
[temp setFrame:CGRectMake(x, y, X10ButtonWidth, X10ButtonHeight)];
You are mixing up two different things / classes :
UIImage that represent image data, with its pixels, in memory
UIImageView that represent a view to display an image onscreen.
If it's more clear to you, an UIImage is to UIImageView what NSString is for an UILabel. The object representing the data/content is different from the view that can display it on screen.
So when you want to retrieve your imageview using the tag you set, you retrieve a view, especially an UIImageView for what matters, not an UIImage.
Change your cast to UIImageView and you will be able to call setFrame: on it the same way you do for your UIButton (as setFrame: is a method of the UIView class, and both UIImageView and UIButton are subclasses of UIView).
UIImageView *tempImageView = (UIImageView *)[self.view viewWithTag:(i)];
[tempImageView setFrame:...];
Or don't even do any cast, as viewWithTag: returns a UIView and that's all you need if you just want to change the frame: whether it's a basic UIView or specifically a UIImageView or whatever kind of view does not matter if you just want to change the frame property, as this is a property of the generic UIView class and can be applied to any UIView, whatever specific subclass of UIView it is.
UIView *tempImageView = [self.view viewWithTag:(i)];
[tempImageView setFrame:...];

Changing UITableViewCell width to fit a UIImageView outside of the cell

I would like to know the best way/correct way to achieve from following layout? I want to place an UIImageView outside of UITableViewCell in a UITableView with static cells.
I have done the following by subclassing UITableViewCell for the cells in section 1 using the following code
- (void)setFrame:(CGRect)frame {
frame.size.width -= 125.0;
[super setFrame:frame];
}
In the UITableViewController's viewDidLoad I add the UIImageView and position it according to the width of the custom UITableViewCell.
This sort of works, but i'm not sure how to deal with rotation and also if what i've done so far would be the correct way?
there are differnt ways to do it. one is to set the width of table view less as you showd in pic 2nd is to use custom table view cell and on required cell add image so that your cell data as well as image will be shown. i think custom cell would be the better solution. tell me if you are asking the same thing what i answered, if no, then i review my answer thank.
I managed to produce what I wanted using the follow, this is proberly not the best way or cleanest way but as no one from StackOverFlow gave any better suggestions I thought I better answer this.
I subclassed the first 3 UITableViewCells and set a frame size to take into account the size of my image.
- (void)setFrame:(CGRect)frame {
float cellWidth = (frame.size.width - 345);
frame.size.width = cellWidth;
[super setFrame:frame];
}
Then in my UITableViewController's viewDidLoad I create and position the UIImageView using the first static cell in the tableview as an IBOutlet ("firstCell"). I then set the autoResizingMask which sorts out rotation and finally add the UIImageView to the view.
//Create and position the image view
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake((firstCell.frame.size.width), (firstCell.frame.origin.y + 70), 300, 137)];
// Add border and round corners of image view to make style look a little like tableviewcells
[imageView.layer setBorderColor:[UIColor colorWithWhite:0 alpha:0.5].CGColor];
[imageView.layer setBorderWidth:2.0];
[imageView.layer setCornerRadius:5.0];
[imageView setClipsToBounds:YES];
//Set the image in the image view
UIImage *image = [UIImage imageNamed:#"defaultPicture.png"];
imageView.image = image;
//Set resizing of image view for when view is rotated
imageView.contentMode = UIViewContentModeRedraw;
imageView.autoresizingMask = UIViewContentModeScaleAspectFit;
//Add tap gesture for imageview to initiate taking picture.
imageView.userInteractionEnabled = YES;
UITapGestureRecognizer *imageViewTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(takePicture:)];
[imageView addGestureRecognizer:imageViewTap];
//Add image view to view
[self.view addSubview:imageView];
This has not been fully tested and i'm sure isn't a great implementation, but its a starting point for the effect i'm after. Please reply if you know of a better way.
Note: The above code is written for my app on the iPad but screenshots are from testing I did on iPhone

Image VIew problem

How can i remove an ImageView added on a dynamically created UIView, so that i can add another ImageView on my UIView.
You either add a tag for that UIImageView and find it based on tag or loop throughout the subviews and look for an object of class UIImageView containing the image you need to change.
Easiest way is probably with tags. So...
UIImageView *removeMe = [[UIImageView alloc] init];
removeMe.image = [UIImage imageNamed:#"theImage.png"];
removeMe.tag = 1;
[theView addSubview:removeMe];
[removeMe release]; //theView now retains it!
...then later:
UIImageView *removalTarget = (UIImageView *)[theView viewWithTag:1];
[removalTarget removeFromSuperview];

subclassed UITableViewCell - backgroundView covers up anything I do in drawRect

I'm trying to make a subclassed UITableViewCell where I draw an image in the upper right corner. I have it working perfectly - except when I set self.backgroundView, my background image covers up the image drawn in drawRect.
There must be a way to be able to set a background image (and the selectedBackgroundView) without covering up what's being done in drawRect.
Am I going about this the wrong way?
EDIT: I've posted an example project with the problem.
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {
// TODO: figure out why this covers up self.starImage that's drawn in drawRect
self.backgroundView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"cellBackground.png"]] autorelease];
}
return self;
}
- (void)drawRect:(CGRect)rect {
[self.starImage drawAtPoint:CGPointMake(self.bounds.size.width - self.starImage.size.width, 0.0)];
}
EDIT 2: at AWrightIV's request, here's how I got it working... which didn't require subclassing UITableViewCell at all. I'm just adding a subview to cell.backgroundView:
// create a UIImageView that contains the background image for the cell
UIImageView *bgImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"cellBackground.png"]];
// create another UIImageView that contains the corner image
UIImage *starRedImage = [UIImage imageNamed:#"starcorner_red.png"];
UIImageView *starImageView = [[UIImageView alloc] initWithFrame:CGRectMake(297,
0,
starRedImage.size.width,
starRedImage.size.height)];
starImageView.image = starRedImage;
// add the corner UIImageView as a subview to the background UIImageView
[bgImageView addSubview:starImageView];
// set cell.background to use the background UIImageView
cell.backgroundView = bgImageView;
You are not really supposed to mix the drawing with your cell like that, you are operating at a lower-level than the UITableViewCell machinery is operating, and this is why you get this problem.
This is just one of the various problems you will end up running into. You will run into other problems as you go down that path, including problems with how the selection works.
The proper approach is to create a custom UIView that contains the code to draw, and then you can addSubView that into your cell's root view. That will take care of the rendering in the proper order, and wont interfere with the selection system, and will work correctly in this case.
You shouldn't override the -drawRect: of a tablecell. Instead, create a new custom view and add it to the cell's contentView, and draw in there.
Have you tried adding a [super drawRect:rect]; there?
Here's a solution that's a bit of a kludge, but it fits my requirements exactly... with one fatal flaw: when cells get reused, the star corner shows up when I don't want it to.
http://dl.dropbox.com/u/2349787/UIImage_Position_subclassed_cell2.zip
I'm still using drawRect here, but only because self.starImage is null if you access it within the initWithStyle method. Also, instead of adding the subview to self.contentView, I'm adding it to self.backgroundView to prevent the cell's delete button from interfering with it. The star corner is positioned correctly in both portrait and landscape mode, and works fine within edit mode as well.
With the cell reuse issue though, It's still a no go... so, maybe I'm back to trying to do it without subclassing UITableViewCell.
I'm open to any further suggestions. Thank you!
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {
// Initialization code
self.backgroundView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"cellBackground.png"]] autorelease];
}
return self;
}
- (void) drawRect:(CGRect)rect {
UIImageView *imageView = [[[UIImageView alloc] initWithFrame:CGRectMake(self.bounds.size.width - self.starImage.size.width, 0, self.starImage.size.width, self.starImage.size.height)] autorelease];
imageView.image = self.starImage;
imageView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
[self.backgroundView addSubview:imageView];
}