Programmatically added view objects not showing up in storyboard - ios

I can't see any of the view objects I've added programmatically. I need to link them to IBAction and/or IBOutlet, but without being able to ctrl-click-drag, I can't.
For example, I have this in viewDidLoad:
imageView = [[UIImageView alloc] initWithFrame:CGRectMake(789, 60, 215, 72)];
[imageView setAnimationImages:imgListArray];
[self.view addSubview:imageView];
The animation shows up in the simulator, but not in the storyboard.
How can I either make these objects show up in storyboard (preferred), or link them to IBActions/Outlets programmatically?

As #vikingsegundo said, Image Builder allows you to add objects to views and then connect them to IBOutlets and IBActions in your classes, but if you add things programatically then you are on your own in terms of Image Builder/Storyboards.
You can still create an iVar or property (preferred) to store the reference to your object, but you don't need the IBOutlet tag, so
#property (strong,nonatomic) UIImageView *imageView;
and then
self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(789, 60, 215, 72)];
[self.imageView setAnimationImages:imgListArray];
[self.view addSubview:self.imageView];
You can also add action handlers to objects through code (the equivalent of ctrl-dragging to an IBAction method)
[self.aButton addTarget:self action:#selector(buttonEventHandler) forControlEvents: UIControlEventTouchUpInside];

To set a code-instantiated object as an instance variable, just set it. Like this:
// your code
imageView = [[UIImageView alloc] initWithFrame:CGRectMake(789, 60, 215, 72)];
[imageView setAnimationImages:imgListArray];
[self.view addSubview:imageView];
// and then:
self.myImageView = imageView; // assumes you've got a `#property` called `myImageView`
That's exactly the same thing that constructing an outlet connection in the storyboard does, but now you're doing it yourself.
To set a code-instantiated control's action, call addTarget:action:forControlEvents:.
That's exactly the same thing that setting up an action connection in the storyboard does, but now you're doing it yourself.

Related

How do I make an image cover the screen when a view is loading?

I have a webview and when you click a link on a webpage, I want the screen to show an image for the duration of the time that the page is laoding (it sounds weird, but it's for a good reason).
I'm new to XCode and have done a few tutorials, but it's still murky to me how to make things happen in XCode (and objective C in general).
It seems that the process should be this - in the webViewDidStartLoad method, I call a class, which is a UIImageView. In that class is the image. And in webViewDidFinishLoad, I then either remove the image, or lower it on the stack.
I just am confused as to all the things you need to do to make this happen. Here's what I have so far:
A class called loadingView which has a method in it called showLoadingScreen. In this method I have the code:
UIView *view=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 480)];
[view setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"Icon-76.png"]]];
Then I go to the storyboard and insert a new UIView over the webView, and give it the class loadingView. And then I control clicked from this UIView to the ViewController.h, and dropped it in the view controller, creating the code:
#property (strong, nonatomic) IBOutlet UILabel *loadingPageView;
and imported loadingView.h.
Is this correct? If yes, then I need to put this method into webViewDidStartLoad, but I can't figure out what code to put there. It seems I to do something like:
[self.view addSubview:imageView];
But I don't know how to customize this to my code.
If you want a view to cover the screen, use:
[[[UIApplication sharedApplication] keyWindow] addSubview:myImageView];
This will add your UIImageView to your key UIWindow, which will show over any UIViewController. Otherwise, add your UIImageView as a subview of your UIWebView. If you want to guarantee that your UIImageView is at the top of the view stack, call:
[self.webView bringSubviewToFront:myImageView];
Either way, maintain your UIImageView as a global property/ivar so you can later call:
[myImageView removeFromSuperview];
Step 1: Declare an imageview property somewhere:
#property (strong, nonatomic) UIImageView * coverImageView;
Step 2: Show Image view in webViewDidStartLoad
- (void) webViewDidStartLoad:(UIWebView *)webView {
if (!_coverImageView) _coverImageView = [[UIImageView alloc]init];
_coverImageView.frame = self.view.bounds;
_coverImageView.image = [UIImage imageNamed:#"Icon-76.png"];
[self.view addSubview:_coverImageView];
}
Step 3: Remove Image View in webViewDidFinishLoad
- (void) webViewDidFinishLoad:(UIWebView *)webView {
[_coverImageView removeFromSuperview];
}

Does removefromsuperview remove subviews?

If I have nested subviews, will all subviews get disposed if i call removefromsuperview?
Pseudocode:
UIView *viewA = [[UIView alloc] initWithFrame:CGRectMake(0 , 0, 100, 100)];
[self.view addSubview:viewA];
UIView *viewB = [[UIView alloc] initWithFrame:CGRectMake(25 , 25, 50, 50)];
[viewA addSubview:viewB];
UIButton *buttonC = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[viewB addSubview:buttonC];
And then buttonC is pressed:
[viewA removeFromSuperView];
All views are removed from the screen, but are they removed properly?
Do I need to remove all views manually?
All views will be removed. If you maintain a strong reference to viewA then all of the views will still be there and can be added again later. If you don't, they will all be destroyed.
As long as you have no other references to your views A..C, they will be removed and destroyed
You can check it easy. Create subclass of uiview, overide it dealloc method and set brakepoint there. Than create instance of this class and add it to your view as subview.
When you`ll call removeFromSuperview in your view brakepoint will be activated.
That`s it.

UIView addSubview works once but not twice

I would like to add a UIButton in a UIView from my xib file.
In my xib, I declare a UIView outlet named "content" with interface builder: here is the generated code :
#property (weak, nonatomic) IBOutlet UIView *content;
I would like to add a button, here is the code for this:
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setTitle:#"Show View" forState:UIControlStateNormal];
button.frame = CGRectMake(0, 8, 141.0, 56.0);
[button setBackgroundImage:[UIImage imageNamed:#"TAB_NORMAL"]
forState:UIControlStateNormal];
button.frame = CGRectMake(0, 8, 56.0, 141.0);
[self.content addSubview:button];
If I put this code in -viewDidLoad method, it works, but if I put it in a function called later, the button is never displayed.
What could be the reason ?
Thanks for your help.
If your UIView content is a top level item, that is, not contained in your main view - then it has to be strong. Only items that are not top-level can use weak, since the containing view would keep a strong reference to them. I also assume that content was immediately added to the primary view, which kept a strong reference to it (it in viewDidLoad happened before ARC nil'ed out content.
If for some reason changing the property to strong does not fix the problem, then for sure add a NSLog (or assert) to insure that content is non-nil.

Duplicated uiview added programmatically

I'm currently making a photo decoration app. The *holderView is the sticker that has been chosen by user. Whenever I try to load a photo from photo library or take a photo and then load back to this page, additional *holderView added programmatically, which is the sticker that I've previously chosen before taking a photo, duplicated sticker appears after that, which is not what I want it to be.
How should I write the code for not letting this happen?
Thanks a lot.
- (void)viewWillAppear:(BOOL)animated {
UIView *holderView = [[UIView alloc] initWithFrame:CGRectMake(0, 50, _imagePicker.selectedImage.size.width, _imagePicker.selectedImage.size.height)];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:[holderView frame]];
[imageView setImage:_imagePicker.selectedImage];
[holderView addSubview:imageView];
...
}
Your problem seems to be that your using the viewWillAppear method instead of the viewDidLoad. This will cause multiple "imageViews" because your adding a new one every time you hide then show the viewController it's presented in. what you want to do is move the creation of the imageView (if there really is suppose to only be 1) to the viewDidLoad method and make that imageView accessible to the entire class, then in the viewWillApear simply change the image inside the imageView to the newly selected one.

Setting Background Image Programmatically In A Xib

I have a XIB file with UIControl and UIScrollView elements inside of it. I would like to add a background image to the view. I tried adding an ImageView in IB but I could not get it to be present as a background and it obscured the control elements. Sending a sendViewBack message doesn't seem to do anything either.
When I create a UIImageView programmatically, it doesn't show up.
Below is the code I attempted:
Programmatic Creation
UIImage *imageBackground = [UIImage imageWithContentsOfFile:#"globalbackground"];
UIImageView *backgroundView = [[UIImageView alloc] initWithImage:imageBackground];
[[self view] addSubview:backgroundView];
[[self view] sendSubviewToBack:backgroundView];
Dealing with the NIB file
[[self view] sendSubviewToBack:background];
where background is an IBOutlet declared in the header file and connected to the NIB's image view in IB.
Is there a step I'm missing here?
Set the frame and dont use sendSubviewToBack:. If you are working with UIImageViews you have to use [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"imageName.png"]];
UIImageView *backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"imageBackground"]];
backgroundView.frame = self.view.bounds;
[[self view] addSubview:backgroundView];
hope this was the deal.
Don't add the image view as a subview of the scroll view, it needs to be a separate view at the top level of the hierarchy, then sent to the back of the Z-order.
You will need to set the background of your scroll view to [UIColor clearColor], and ensure that the scroll view is not marked as opaque. You can do this in code or in interface builder.
Don't use imageWithContentsOfFile and then just pass it a filename with no extension (I'm assuming .png) - this is probably returning nil. Use imageNamed: instead (you don't supply an extension in that case, iOS4 and above)
Depending on the nature of your image, you can also generate a colour with it and use that as the background colour of your scroll view. I'm assuming self.view is the scroll view:
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"globalBackground"]];

Resources