Creating an UIImageView on UIButton click - iphone

I have a button setup in one class and on clicking it, I am calling a method which is in another class and in that method I have setup code for UIImageView.
the method is getting called, But somehow the ImageView doesnt seems to get created, I dont understand why, And therefore I cannot add any Image to that ImageView.
Here's some code of what I am trying to do:
In my first viewControllerClass I have this method which fires on a button click:
- (IBAction)buttonClicked:(id)sender {
[secondViewController createNewImageView];
}
and then in the second viewController I am calling that createNewImageView method, in which I am creating an ImageView at runtime:
-(void)createNewImageView {
newImageView = [[UIImageView alloc] initWithFrame:CGRectMake(100,100, 100, 100)];
newImageView.backgroundColor = [[UIColor yellowColor] colorWithAlphaComponent:0.4];
[self.otherNewView addSubview:newImageView];
}
But somehow the ImageView is not getting added on my view, Any Ideas why this is happening ?
What am i missing here ..?
Thanks for your time :)
EDIT : The class which holds the button is UIPopOverController.

Have you allocated secondViewController before doing,
[secondViewController createNewImageView];
I think you have not created an object for secondViewController.
So before calling the function create the object for the class.

Related

ViewDidLoad method calling behavior [duplicate]

This question already has an answer here:
Method calling via performSelectorOnMainThread Vs Normal method calling
(1 answer)
Closed 9 years ago.
In my viewDidLoad, I call a function:
[common startActivityIndicatorOnView:self.view];
This method adds a view with Activity indicator, in the center of self.view.
My current view is pushed on a Navigation Stack. This is how the view looks after this method returns (the activity indicator view is not in center):
However, if I call the same method this way:
[common performSelectorOnMainThread:#selector(startActivityIndicatorOnView:) withObject:self.view waitUntilDone:NO];
The view looks like the following image (the activity indicator view is in center):
I do not get, How does it make a difference if the calling line is written in viewDidLoad.
If any one can help me get this, thanks in advance.
Just for reference,
the method looks like this:
-(void) startActivityIndicatorOnView:(UIView *)view {
if ([NSRunLoop currentRunLoop] != [NSRunLoop mainRunLoop]) {
[self performSelectorOnMainThread:#selector(startActivityIndicatorOnView:) withObject:view waitUntilDone:NO];
return;
}
view.userInteractionEnabled = NO;
activityBgView = [[UIView alloc] initWithFrame:CGRectMake((view.frame.size.width/2) - 50, (view.frame.size.width/2) - 50, 100, 100)];
activityBgView.center = view.center;
activityBgView.backgroundColor = [UIColor grayColor];
activityBgView.alpha = 0.8;
spinner = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake((activityBgView.frame.size.width/2)-10, (activityBgView.frame.size.width/2)-10, 20, 20)];
spinner.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
spinner.center = view.center;
[view addSubview:activityBgView];
[view addSubview:spinner];
[spinner startAnimating];
}
ViewDidLoad is called when you load viewControllers (via nib/xib or created programmatically in the loadView method), meaning xcode create all views and instantiate and alloc all objects in xib...
but, your viewController view (and subViews) are still not added in any view...
yourViewController.view.superView = nil;
so, its view has got the frame that you set in xib, but if you tell it to resize inside its superview, when you add it (e.g. with a push or an addsubview), its frame changes, but your
spinner won't change its position.
calling a performSelectorOnMainThread just will call your method later, when your current thread step ahead and may have pushed your viewController.view, so, when executed, yourViewController.view.superView exists, and so view.frame has already changed.
try to move your call to
[common startActivityIndicatorOnView:self.view];
in a viewWillAppear method: at that point yourViewController.view should been already resized to fit its superView
EDIT:
# pavel question:
after what moment yourViewController.view.superView will be not nil?
banally: when you add its view to a view. that is, firts you allocate and init it (init with a nib or via code)
something like:
yourViewControllerInstance = [[YourViewController alloc]initWithNibName:#"yourViewControllerNib" bundle:nil];
at this point the method viewDidLoad in your class is called (but yourViewController.view.superview 0 nil)
later, you usually use your new viewController, so you "push" it in the stack of a navigationController, or you just add its view to the current viewController.view... something like:
[currentViewController.view addSubview:yourViewController.view];
after this line, as you may imagine, yourViewController.view.superView = currentViewController.view, and the method viewWillAppear of yourViewController is called, so you can use superView inside it.
Notice that at this point your viewController.view is still not visible on screen, so you can adjust sizes, move or add views here without users see any changes.
after this, yourViewController will show, and at the end, and the method viewDidAppear of yourViewController is called (for any other code, in case)

SSCollectionView SSCollectionViewItem - no Items displayed

I ran into difficulties with SSCollectionView and SSCollectionViewItem.
First of all I'd like to get it initialized from IB. But that won't work for me.
I have a SelectFooViewController which is:
#interface SelectFooViewController : SSCollectionViewController { ... }
and am using it as filesOwner of the corresponding XIB.
SelectFooViewController* selectFooVC = [[SelectFooViewController alloc]
initWithNibName:#"SelectFooViewController" bundle:nil];
But since it wont work I had to initialize its properties inside viewDidLoad() myself.
Furthermore I am not able to display anything except the backgroundColor of my SSCollectionViewItems. What I want is a textLabel and an image .
- (SSCollectionViewItem *)collectionView:(SSCollectionView *)aCollectionView itemForIndexPath:(NSIndexPath *)indexPath {
SSCollectionViewItem *item = [[[SSCollectionViewItem alloc] initWithStyle:SSCollectionViewItemStyleImage reuseIdentifier:itemIdentifier] autorelease];
SSLabel* label = [[SSLabel alloc] init];
[label setText:#"foo"];
item.imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"foo.png"]];
item.textLabel = label;
[label autorelease];
return item;
}
I can confirm that the delegate methods (for determining the number Of rows, sections and such) are implemented and working as expected. But my items are all empty - but react onclick with the expected popup.
Does anyone see an error in what I did? - Thanks...
EDIT: I was also not able to display a local image by changing SSCatalog project
I just figured out, that I have to set the frame of each property (textLabel, detailTextLabel and imageView) myself. That fixed it.
When you create instance SelectFooViewController just insert this line
selectFooVC.view;
or
selectFooVC.view.hidden = NO;
And then add it to the view.
This is because the view is not initalised until you explicitly access it. Hence your items are loaded only when you click it and not immediately. You can call it a hack but i don't call it one. :-)

uniimageview not updating after views tranistion

I have one main view where I display an image, in the method viewDidLoad:
ballRect = CGRectMake(posBallX, 144, 32.0f, 32.0f);
theBall = [[UIImageView alloc] initWithFrame:ballRect];
[theBall setImage:[UIImage imageNamed:#"ball.png"]];
[self.view addSubview:theBall];
[laPalla release];
Obviously, the value of posBallX is defined and then update via a custom method call many times in the same class.
theBall.frame = CGRectMake(posBallX, 144, 32, 32);
Everything works, but when I go to another view with
[self presentModalViewController:viewTwo animated:YES];
and come back with
[self presentModalViewController:viewOne animated:YES];
the image is displayed correctly after the method viewDidLoad is called (I retrieve the values with NSUserDefaults) but no more in the second method. In the NSLog I can even see the new posBallX updating correctly, but the Image is simply no more shown...
The same happens with a Label as well, which should print the value of posBallX.
So, things are just not working if I come back to the viewOne from the viewTwo... Any idea???????
Thanks so much!
You should use dismissModalViewControllerAnimated: to switch back to viewOne from viewTwo instead of trying to present viewOne modally.
Also note that viewDidLoad is called only once - after the view controller's view is loaded into memory. If you want to perform an action once a view comes back on screen, you should do so in viewWillAppear:.
Both of these points are discussed in the UIViewController class reference and in the View Controller Programming Guide.

passing handles between a ViewController and a View

I have an array of booleans (soundArray) that is modified based on user input. Therefore it is owned by the main UIView that the user is interacting with. Meanwhile, in another separate controller (GestureController), I need access to this soundArray, so I can pass it as a parameter in a method call.
I'm pretty sure a ViewController shouldn't be digging out properties of a UIView it doesn't own (correct MVC), so I've created another pointer to the soundArray in the ViewController (MusicGridController) that owns the main UIView (MusicGridView).
In GestureController, I have the following code:
// instantiate the sound thread
NSArray *soundArrayPointers = [NSArray arrayWithObjects:self.musicGridViewController.soundArray, nil];
[NSThread detachNewThreadSelector:#selector(metronome:) toTarget:[MusicThread class] withObject:soundArrayPointers];
(eventually I'll have more soundArrays in that array).
Now, in MusicGridController, I need to set the pointer to the SoundArray in the UIView MusicGridView... so I did this:
- (void)viewDidLoad {
[super viewDidLoad];
self.view.frame = CGRectMake(20, 0, 480, 480);
MusicGridView *tempview = self.view; // this line gives me a warning that I am initializing from a distinct Objective-C type, which I don't understand.
self.soundArray = tempview.soundArray;
}
I tried self.soundArray = self.view.soundArray, but it threw an error, and I don't understand why. So my question is: Is this a correct implementation? How do I get from one viewController to a property of a given UIView?
I'm not sure I understand who the NSArray belongs to, or who it should belong to, but you can try utilizing the AppDelegate if it's supposed to be a global object (accessed by more than one view and/or controller).
Now, to solve your problem. Your implementation is not wrong, and the warning will go away if you add (MusicGridView *) before self.view. This is related to the error you got when you tried self.soundArray = self.view.soundArray, and the reason is simple: UIView doesn't have a soundArray property, and self.view is a pointer to a UIView. By casting self.view to a MusicGridView *, you get rid of the warning, and your code should work fine.

IB objects vs manually allocated objects in init/viewDidLoad

When I programmatically allocated a UILabel in my custom initWithNibName method, and later in viewDidLoad, tried to assign a string to it, the label was not pointing to anything. I didn't release it; the label shows on the screen. If I create the label in IB, and assign text to it in viewDidLoad, it works.
Is it against a rule to set up manually allocated objects in viewDidLoad?
Why is it not pointing to anything, even though viewDidLoad is called after my init?
From the doc of viewDidLoad:
This method is called after the view controller has loaded its associated views into memory. This method is called regardless of whether the views were stored in a nib file or created programmatically in the loadView method. This method is most commonly used to perform additional initialization steps on views that are loaded from nib files.
In my init:
_descriptionLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 218, 280, 10)];
_descriptionLabel.numberOfLines = 0;
_descriptionLabel.lineBreakMode = UILineBreakModeWordWrap;
_descriptionLabel.font = [UIFont systemFontOfSize:12.0];
_descriptionLabel.adjustsFontSizeToFitWidth = NO;
_descriptionLabel.text = #"Description not found.";
_descriptionLabel.backgroundColor = [UIColor clearColor];
In viewDidLoad, the variable's value is 0x0.
It's the same with my manually allocated UIButton, which is fully working once the view loads.
If you want to create the UILabel programatically you can, but you still do it in viewDidLoad (as opposed to initWithNibName).
Don't be afraid to do UI setup in viewDidLoad. It is provided to add any static UI elements BEFORE the view appears on screen.
The view will not appear until just before viewDidAppear:(BOOL)animated is called.
If you have dynamic content configure it in viewWillAppear:(BOOL)animated. (This looks like your situation)
Then make sure you add it to the view:
[self.view addSubview:myLabel];
If you need future access to your new label, you will need to create an ivar to hold a pointer to it.
In the code posted, the _descriptionLabel UILabel is not retained and will be released before the view is drawn.
Try
_descriptionLabel = [[[UILabel alloc] initWithFrame:CGRectMake(20, 218, 280, 10)] retain];
Make sure you put [_descriptionLabel release] in dealloc. This assumes _descriptionLabel is an instance variable.
This basically applies to any object you create with alloc, copy, or new.