I've typically followed the pattern of creating an object in my method (like viewDidLoad), have the property hold onto it, then release the original object created. So something like this:
NSArray *myArray = [NSArray alloc] initWithObjects:#"1", #"2", #"3", nil];
self.array = myArray;
[myArray release];
I thought I could do the same thing with UIImageView. I have a UIImageView created in my .xib. I have an outlet to it that is a property like so
#property (nonatomic, retain) IBOutlet UIImageView *imageView;
In my viewDidLoad, I do:
UIImageView *imgView = [[UIImageView alloc] initWithImage;[UIImage imageNamed:#"arrow.png"]];
self.imageView = imgView;
[imgView release];
If I run this, I do not get anything on screen. However, if I do just this in my viewDidLoad instead:
[self.imageView setImage:[UIImage imageNamed:#"arrow.png"]];
I do get my arrow image on screen. Is there something different about UIImageView that I am missing here?
Edit because of first response: Is UIImageView different than UITableView in that I need to add it as a subview to my current view? When I create a UITableView in IB, I do not add it as a subview in viewDidLoad.
Thanks.
You are missing the point behind how IBOutlet work. If something is specified in .xib then it is already allocated for you :) You just use it.
Hence [self.imageView setImage:[UIImage imageNamed:#"arrow.png"]]; works since you just assigned an image to it.
However, when doing
UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"arrow.png"]];
self.imageView = imgView;
[imgView release];
you actually deallocated the imageView instance created by IB at the self.imageView = imgView; line and set a new one and neither did you added it as subview to anything. Since it is a new instance it will need to be added !! But anyways this approach is wrong if you are using IBOutlet
You need to add self.imageView to your view hierarchy.
- (void)viewDidLoad
{
[super viewDidLoad];
self.imageView = ...
// You are missing this part!
[self.view addSubview:self.imageView];
...
}
PS. You dont need to mark your UIImageView property as IBOutlet since you are not using Interface Builder to build your view.
Related
I'm trying to displaying an image from file on my ViewController in Xcode. I have in my ViewController.h:
UIImageView *image;
#property(nonatomic,retain) IBOutlet UIImage* image ;
ViewController.m
- (id)initWithImage:(UIImage *)image
{
UIImageView * imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"nameoffile.jpg"]];
self.image = image;
[image release];
}
But no luck. It won't let me link my UIImage instance in the xib.
Try to use this one.You know you can't get IBOutlet on UIImage. So you need to write UIImageView instead of UIImage.
#property(nonatomic,retain) IBOutlet UIImageView* image ;
As the UIImageView is created when the NIB file is loaded, there is no need to make it an instance variable, so remove it from your header file:
UIImageView *image;
Next ensure that your UIImageView outlet is actually connected correctly to the image view within the NIB file. You will see a filled circle when it is connected (this is from a Beginning iOS Development example, which uses ARC, so ignore the weak keyword):
And finally you should be able to set the image view's image in the viewDidLoad method (there is no need to use an instance variable for the UIImage either, as it will be retained within the UIImageView):
- (void)viewDidLoad
{
[super viewDidLoad];
imageView.image = [UIImage imageNamed:#"nameoffile.jpg"];
}
Check the Error of your code.
#property(nonatomic,retain) UIImageView *imageView;
#property(nonatomic,retain)UIImage* image ;
- (id)initWithImage:(UIImage *)image
{
_imageView = [[UIImageView alloc] initWithImage:image];
_imageView.frame=self.view.frame;
[self.view addSubView:_imageView];
[image release];
}
In .h file I declare this;
IBOutlet UIImageView *image;
In .m file;
UIImage *image1 = [UIImage imageName:#"http://image.com/image.jpg"];
image = [[UIImageView alloc] initWithImage:image1];
image.frame = CGRectMake(0,0, 50,50);
[self.view addSubView:image];
and I connected the UIImageView from the Interface builder. But I need to do this Only by code (without using the Interface Builder). Can someone help me modify the code so that I could do this only by code?
I THINK you have some problem in displaying a remote image in uiimageview so i thing u should do that fashion.
NSData *receivedData = [[NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://image.com/image.jpg"]] retain];
UIImage *image = [[UIImage alloc] initWithData:receivedData] ;
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(0,0, 50,50);
[self.view addSubView:image];
[image release];
[imageView release];
and i connected the UIImageView from the Interface builder
That was a mistake. If you do that, the image view pointed to by your image instance variable will be the wrong one - the one in the nib. You want it to be the one that you created in code.
So, make no connection from Interface Builder; in fact, delete the image view from Interface Builder so you don't confuse yourself. Make sure your instance variable is also a property:
#property (nonatomic, retain) UIImageView* image;
Synthesize the property:
#synthesize image;
Now your code will work:
UIImage *image1 = [UIImage imageName:#"http://image.com/image.jpg"];
self.image = [[UIImageView alloc] initWithImage:image1];
// no memory management needed if you're using ARC
[self.view addSubview:self.image];
You will need to play with the frame until the location is correct. Note that the frame will automatically be the same size as the image, by default.
you dont need to connect. This code will work without connecting. Leave IBOutlet out.
UIImage *someImage = [UIImage imageName:#"http://image.com/image.jpg"];
UIImageView* imageView = [[UIImageView alloc] initWithImage:someImage];
[self.view addSubView:imageView];
I'm trying to base part of my app off of Apple's Image Zooming example, to get zooming, scrolling, and orientation of images that are saved to the app's sandbox.
http://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/UIScrollView_pg/Introduction/Introduction.html
I have it sort of working now, except that when the ScrollView loads, it's blank. The code looks something like this:
#interface PhotoViewController : UIViewController <UIScrollViewDelegate> {
UIScrollView *imageScrollView;
UIImageView *imageView;
}
#property (nonatomic, retain) IBOutlet UIScrollView *imageScrollView;
#property (nonatomic, retain) UIImageView *imageView;
#end
#implementation PhotoViewController
#synthesize imageView, imageScrollView;
- (void)viewDidLoad {
[super viewDidLoad];
imageScrollView.bouncesZoom = YES;
imageScrollView.delegate = self;
imageScrollView.clipsToBounds = YES;
imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image1.jpg"]];
imageView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.backgroundColor = [UIColor blackColor];
imageView.userInteractionEnabled = YES;
[imageScrollView addSubview:imageView];
imageScrollView.contentSize = [imageView frame].size;
}
The xib has a Photo View Controller->Scroll View->View structure. I have a feeling this is where the problem is. I tried to hook up all the outlets identically to the example, but under Referencing Outlets the example has a viewController hooked up to the ImageZoomingAppDelegate. Since my PhotoViewController is a subview, there's not a place to hook up the viewController like that.
Here's how I bring up the PhotoViewController:
(IBAction) photoButtonPressed: (id) sender {
viewController = [[PhotoViewController alloc] init];
[self.navigationController pushViewController:viewController animated:YES];
}
I know I must be just "this close" to having it all hooked up right, but I don't understand the relationship of the xib to the code well enough to know how to debug it. I'm not even sure if I know enough to ask the right questions.
Try changing viewController = [[PhotoViewController alloc] init]; to
viewController = [[PhotoViewController alloc] initWithNibName:#"PhotoViewController" bundle:nil];
(of course change the text string to whatever you called your xib file).
I'd like to place an image behind the tableView in my UITabBarController moreNavigationController. I have tried inserting a subview like so when first setting up the TabBar:
UIImageView* imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"background3.png"]];
[self.tabBarController.moreNavigationController.topViewController.view insertSubview:imageView atIndex:0];
But this places the image over the top, presumably because the tableView isn't there at the time. Is there a better time when I can call this in order to have it work properly, or an easier approach?
With some assistance from this question, I figured out how to do this. Basically, the viewController in the moreNavigationController is a single TableView, so adding a background image won't work. What I need to do was to create a new view, add the background image, and then add the moreNavigationController view on top of that. I did this by overriding viewDidLoad in a subclass of UITabBarController, but I expect it could be done elsewhere as well.
- (void)viewDidLoad {
[super viewDidLoad];
UINavigationController *moreController = self.moreNavigationController;
if ([moreController.topViewController.view isKindOfClass:[UITableView class]]) {
UIView* newView = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,367)];
UIImageView* imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"background3.png"]];
imageView.opaque = NO;
imageView.alpha = 0.4;
[newView addSubview:imageView];
moreController.topViewController.view.backgroundColor = [UIColor clearColor];
moreController.topViewController.view.frame = CGRectMake(0,0,320,367);
[newView addSubview:moreController.topViewController.view];
moreController.topViewController.view = newView;
}
}
You could probably be smarter with the frame sizes, etc, but this works for me. Hopefully it helps someone else too.
Now you can acess backgroundView property from UITableView subclasses .
UIViewController *moreViewController = tabBarController.moreNavigationController.topViewController;
img = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"BG_MORE+1.png"]];
//Got some crashs in initialization !! Need to check .
if ([moreViewController.view isKindOfClass:[UITableView class]]) {
UITableView *moreTableView = (UITableView*)moreViewController.view;
[moreTableView setBackgroundView:img];
}
Besides all the dotty mess here, you can use UIView's bringSubviewToFront: and sendSubviewToBack: to organize your subviews. Basically this should help, although if you have more subviews you will need to play around with it a little bit:
[self.tabBarController.moreNavigationController.topViewController.view addSubview:imageView];
[self.tabBarController.moreNavigationController.topViewController.view pushSubviewToBack:imageView];
//or [self.tabBarController.moreNavigationController.topViewController.view bringSubviewToFront:tableView];
Is it possible to allow user input text on a UIImageView, just like the text tool in painter?
I cannot find any resource on this topic?
UIImageView is not designed to hold any text, but you could add a UILabel or UITextField either within it or on top / below it, depending on what you want to do.
For example, suppose you want to allow the user to edit a piece of text inside an image. You could do something like this:
UIImage* image = [UIImage imageNamed:#"my_image.png"];
UIImageView* imageView = [[UIImageView alloc] initWithImage:image];
imageView.userInteractionEnabled = YES;
UITextField* textField = [[UITextField alloc]
initWithFrame:CGRectMake(10, 10, 50, 20)];
textField.placeholder = #"type here";
[imageView addSubview:textField];
// You might also want to set the imageView's frame.
[self.view addSubview:imageView];
If you add a UITextField as a subview of a UIImageView, it's important to set the userInteractionEnabled to YES, since it defaults to NO for that superview (it's usually YES by default in most UIViews).
Addendum
If you want the user to be able to click anywhere in the image to edit the text, here is one way to do it: subclass UIControl and add a UIImageView and a UITextField as subviews of it, and connect the clicking action of the UIControl to the UITextField. Something like this (WARNING: not tested code, but it conveys the general idea):
#interface ImageAndTextView : UIControl {
UIImageView* imageView;
UITextField* textField;
}
#property (nonatomic, retain) UIImageView* imageView;
#property (nonatomic, retain) UITextField* textField;
- (void) click;
#end
#implementation ImageAndTextView
#synthesize imageView, textField;
- (id) initWithFrame: (CGRect) frame_ {
if (self = [super initWithFrame:frame_]) {
UIImage* image = [UIImage imageNamed:#"my_image.png"];
self.imageView = [[[UIImageView alloc] initWithImage:image] autorelease];
imageView.userInteractionEnabled = YES;
[self addSubview:imageView];
CGRect textFrame = CGRectMake(10, 10, 50, 20); // whatever frame you want
self.textField = [[[UITextField alloc]
initWithFrame:textFrame] autorelease];
[self addSubview:textField];
// Now register an event to happen if the user clicks anywhere.
[self addTarget:self action:#selector(click)
forEvent:UIControlEventTouchUpInside];
}
return self;
}
- (void) click {
[textField becomeFirstResponder];
}
#end
This is not possible with the current iPhone API (3.1). You will need to create your own custom uitextfields and your own image rendering methods to combine the layers into a captioned photo.