how to add uiview as a subview to existing view - iphone

I want to add a UIView of smaller frame as subview to parental view but I am not getting the needed.
UIView *view = [[UIView alloc] initWithFrame:something];
[self.view addSubview:view];
Can anyone suggest me the answer?

Here you are adding a blank view to another view. Maybe you don't see it because it is blank?
What is "something"?

Have you tried - (void)bringSubviewToFront:(UIView *)view? It might be that you're adding this subview somewhere in the view hierarchy where it's obscured. In your code fragment there, you would add:
[self.view bringSubviewToFront:view];
Of course, without supplying more code (preferably directly from your project, and which actually compiles), I'm just guessing. What were you expecting to happen? What actually happened?

Related

Best practices for framing a hierarchy of views

From other stack overflow questions, I understand that in your view controller, you can use the viewDidLoad method to initialize subviews and the viewWillLayoutSubviews method to set the frames. This implies that we need to keep a reference of all the views within the view controller instance (as below). This is all fine and great and handles device rotations, etc.
UILabel* myLabel;
- (void)viewDidLoad
{
myLabel = [[UILabel alloc] init];
[myLabel setText:#"Hello"];
}
- (void)viewWillLayoutSubviews
{
[myLabel setFrame:CGRectMake(0, 0, self.view.frame.size.width, 21)];
}
My question is what if you have a complex hierarchy of subviews. For example, what if you have a subview which is a UIView and you add subviews to that UIView (and potentially it even goes deeper). Do you have to keep a reference to every view in this whole view hierarchy so that on viewWillLayoutSubviews, you can modify the frame of each view? This seems like the only way. Are constraints the best way so that you don't have to modify frames as often? Is the best answer to build tons of custom UIViews to make managing this hierarchy more manageable and self-contained within each custom view?
Hopefully this is a clear enough question..thanks in advance.
Anytime you manipulate a view or subview, in a way that could change the layout constraints, you have to call
[view layoutSubviews];
this will remake the constraints with the new property settings. When the viewController is loaded, you would set all properties not dealing with the frame or bounds and then with in the viewWillLayoutSubviews you set the frames of the views this is so all the constraints are made and ensured that they are met.
Any object you put in the storyboard that you want to use, should have a property this will hold a reference to that object. This is a good coding practice, especially if you follow the rules of test driven development.
Now to answer your questions, if you create the complex hierarchy in the storyboard then everything should be fine as long as your constraints are fine, if you make it in code just be sure to call layoutSubviews when ever you call addSubview
Example:
UIView* view1 = [[UIView alloc] initWithFrame:CGRectZero];
UIView* view2 = [[UIView alloc] initWithFrame:CGRectZero];
[view1 addSubview:view2];
[view1 layoutSubviews];
More views does not make the structure better, but if you have 100 subviews... lets be real.. something needs to be categorized in a separate view..
Constraints let you define the frames of views perfectly. You might not notice the differences at first, but if you compare it to Autoresizing Mask then you will see the differences. Also, here is a guide that blatantly shows you the differences.
LayoutConstraints and Autolayout
Also worth considering is using child view controllers if you wish to compartmentalize some of the logic and reuse components.

Storyboard UIScrollView contentSize?

I feel like I have touched on every single possible cause for stopping this, but I have a UIScrollView in my Storyboard hooked up with an outlet and in the viewDidLoad I set the contentSize so that I can scroll (yes bigger than my frame size)!
However, whatever I change, I just can't scroll! I have a couple of textfields in my scrollview and bouncing enabled so I can see that when testing its moves up and down with my subviews in it but whatever I set the contentSize to I just can't scroll.
Anything I might be missing/should check? Is this a known issue with UIScrollView being used in a storyboard?
Whats even stranger is, I can do something like this:
[scrollView setBackgroundColor:[UIColor blueColor]]; and I have a blue scroll view! But setting content size fails.
Edit
My only code (otherwise scrollview is just dropped into storyboard view controller):
-(void)viewDidAppear:(BOOL)animated
{
[scrollView setContentSize:CGSizeMake(320, 640)];
}
Logged frame, comes out as expected:
width: 320.00
height: 504.00
Edit 2
Turns out that removing any subviews of the scroll view in my storyboard lets it scroll just fine. If I add any subview to it at all via the storyboard, even a blank brand new UIButton it just won't apply the contentSize/allow scrolling.
use ViewDidLayoutSubview
- (void)viewDidLayoutSubviews
{
[_scrollView setContentSize:CGSizeMake(320, 500)];
}
UIViewController's method invoke sequence is as below
awakeFromNib
viewDidLoad
viewWillAppear
viewWillLayoutSubviews
viewDidLayoutSubviews
viewDidAppear
viewDidLoad is not a good place to put code that relies on frame sizes of IB objects. If you log the contentSize of your scroll view in viewDidLoad, you will see that it's (0,0). Move the code (where you set the content size) to viewDidAppear, and it will work properly.
Check these
User Interaction enabled
Outlet connected
Included contentsize greater than bounds
scrolling Enabled
eg
scrollView.contentSize = CGSizeMake(320, 640);
My storyboard looks like this for scrollview [working]
I had exactly the same line of code in viewDidAppear and it did not work
Moved it to viewDidLayoutSubviews and it worked correctly.
[scrollView setContentSize:CGSizeMake(320, 500)];
Thanks trick14 for the answer.
The issue is most probably with Auto Layout. UIScrollView needs special attention when using AutoLayout.
Quick-fix - bind one of the scroll's subviews to the top AND bottom space of it's superview (the scroll view).
Long story:
Questions on SO:
UIScrollView not scrolling regardless of large contentSize,
UIScrollView will not scroll, even after content size set,
UIScrollView doesn't use autolayout constraints
Apple's Documentation:
https://developer.apple.com/library/ios/technotes/tn2154/_index.html
Trip14's answer worked for me. In swift I coded it as:
override func viewDidLayoutSubviews() {
(self.view as! UIScrollView).contentSize = CGSizeMake(600, 600)
}
This seems to be a similar issue. Other Story
It might be an issue with auto layout or constraints in the storyboard.
the best way with the storyboard.:

Best way to create a menu that scrolls up from the bottom?

I'm fairly new to iPhone programming, and I'm making a fairly basic app. Anyway, I just want to know how to go about creating a menu that scrolls up from the bottom (beginning at the top of the tab bar) that displays a few options. I've attached a picture that better helps portray what I mean. I'm assuming I should create some sort of subview and then add some animation to it, but I'd like to get your advice on the best way to start.
Thanks
The simplest solution would be to use a UIActionSheet, unmodified.
If that's not what you're looking for, using a modal view controller is always an option.
If, however, you want something that won't cover the entire screen, and can have a custom look, the basic idea is this:
Create your view with a frame that's just at the bottom of your main view (e.g. at 0,406).
Optionally disable user interaction with the main view
Use UIView animations to move it up
The code would look something like this:
UIView *customView = [[UIView alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height, self.view.bounds.size.width, kCustomViewHeight)];
[self.view addSubview:customView];
[UIView animateWithDuration:0.2 animations:^{
CGRect f = customView.frame;
f.origin.y -= kCustomViewHeight;
customView.frame = f;
}];
I didn't do it myself, but saw a cool source-code, where it was performed with the helped of UIScrollView (by default positioned "below" the screen), containing UITableView and a button (wich was shown at the bottom of the screen). ScrollView was getting a command to move after the press of this button (in IBAction of it).
Being shorter, try to look at UIScrollView (play with UITableView in it).
I've done something similar, popping up some object from the bottom of the screen by subclassing UIActionSheet and adding my own controls as subviews. I imagine a similar method could be used in your situation.
Create a subclass of UIActionSheet implementing the UITableViewDelegate and UITableViewDataSource protocols. In the - (id)init method of that class, add a UITableView as a subview with self as the delegate and data source.
Then from the main view, call your custom UIActionSheet with showInView:.
Use delegates to call back to the main view to let it know when the user selects an option, then use [myCustomMenu dismissWithClickedButtonIndex:0 animated:YES] to hide the menu.

Add UIStuff in an UIView

I want to add my buttons in a UIView, like then I can hide or not them.
My button's code:
carte1J1=[UIButton buttonWithType:UIButtonTypeCustom];
carte1J1.tag=11;
carte1J1.frame=CGRectMake(60, 240, 50, 73.0);
[carte1J1 setImage:[UIImage imageNamed:[NSString stringWithFormat:#"%#",imagecarte1] ] forState:UIControlStateNormal] ;
[carte1J1 addTarget:self action:#selector (clicCarte1J1) forControlEvents:UIControlEventTouchUpInside];
[self.view insertSubview:carte1J1 atIndex:1];
My view is viewJoueur1, I try to add my button in the view like this.
[viewJoueur1 addSubview:carte1J1];
And to test I try to hide viewJoueur1:
viewJoueur1.hidden=YES;
But the button is still visible and I don't understand why
In the first section of code that you listed, you have:
[self.view insertSubview:carte1J1 atIndex:1];
In the second section, you have:
[viewJoueur1 addSubview:carte1J1];
So, you've added cartelJ1 to two views if I'm understanding correctly.
Then, you hide one of those two views, but self.view is still visible, and it contains cartelJ1, so cartelJ1 is still visible.
Please correct me if I'm misunderstanding your code...
You’re right, that isn’t the documented behavior:
Hiding a view with subviews has the
effect of hiding those subviews and
any view descendants they might have.
You’re adding carte1J1 as a subview of viewJoueur1; is viewJoueur1 a plain UIView or a custom subclass? If it’s a subclass, have you overridden -setHidden:?
If it’s a standard UIView, then this behavior is not as documented and you should report it as a bug.
One thing that I notice is that when you create the button, you add it as a subview of self.view, then later add it as a subview of viewJoueur1. Views can only be a subview of one view at a time, so the first one is redundant.

Sending view to back

When I try to send a view to the back, it hides some of the buttons and labels in my view controller. The view I am sending to the back is a UIImageView. Does anyone have an opinion of what might be the problem?
Here is the code I am using:
UIImage *image = [UIImage imageNamed: #"background.jpg"];
UIImageView *backImage = [[UIImageView alloc] initWithImage: image];
[self.view addSubview: backImage];
[self.view sendSubviewToBack: backImage];
Then, when I am adding controls to self.view, they does not always show
I managed to get it roght by moving my code from init to loadView. I don't understand why that should make a difference, but hey.. it works!
If you are using UIView's sendSubviewToBack: or a similar message, you probably have your buttons inserted in the hierarchy under the UIImageView. When a view moves in the hierarchy, all of its subviews move with it.
To fix this, you need to add your controls as subviews of the same view (possibly the UIWindow) you added the UIImageView to initially.
Without seeing your code, it's very difficult to be more precise.
By not having to add it programmatically and adjust the views, much easier to layer each one in the interface builder. Make sure the image view, if this is set as the background, make sure it is the first to be listed.
Agreed. Not quite sure by what you mean by "send to the back" but here's a guess...
If you are adjusting the layering within your main view, be sure you are not sending a view "to the back" (changing it's layer) that has number of subviews... or else they would all go to the back (their layering would change) at the same time.
If this is totally not what you meant, just let me know, and I'll delete this answer.