tvOS: Load UIView inside another UIView as a subview programmatically - swift

I have a UIVisualEffectView which will act as a "container" view. Have set autoLayout to the container view. I have another 3 UIViews each having separate frame size and elements, ( view 1 has a Label and image, view 2 has a tableView and a label, view 3 have few more uilabels ).
I want to add each of these uiview's to the container view based on some button action.
Am trying to add the subviews using addSubView at each of the button actions.
I have added the sub uiview's in the storyboard under the container view's hierarchy and currently my logic depends on hiding the irrelevant uiview's and showing the subview which is relevant.
Though I have tried adding the uiview's using addSubView to the container's view, it does not load the views. Have tried doing the same flow using separate .xib but for no effect.
The container view needs to resize based on the subview's height and also load the subView.
Am I doing something wrong or is there some other way to do these design.

Related

iPhone: Make UIScrollView from UIView

I have a UIView with labels and textfields and I tested it in the simulator and noticed that I cannot scroll to see the rest of the view, how can I make the view into a UIScrollView and what do I need to do so I can make the view scrollable? I don't want to move labels and stuff or delete the UIView, is there a simple way?
Take a UIScrollView in Xib file outside your view. drag your view into this scrollview. The subviews inside your view remains same. and set the scrollview's contentSize

Resizing content in a UIScrollView

I am creating a scrollview programmatically and adding subviews to it programmatically. The subviews are created programmatically as well.
I am just wondering how to rotate / resize the subview so that it remains visible in landscape mode.
I have set the scrollview to autorotateSubviews:YES and in my subview i have set the mask to be flexiblewidth|flexibleheight is this correct?
I am used to doing this in IB with the springs and struts section of the inspector.
Thanks
Your scroll view is probably contained in a view witha corresponding controller that receives willAnimateRotationToInterfaceOrientation:duration: and didRotateFromInterfaceOrientation: notifications. Use these opportunities to resize the subviews of the scrollview.

How should child views of UIScrollView report their bounds for contentSize?

I'm looking more for advice on the correct design for a view.
What I have is a UIScrollView that contains one or more custom Views I have created. My problem is, who reports to the scrollview what it's contentSize should be? I have the following:
UIView
+-UIScrollView
+-CustomView 1 with dynamic height depending on data
+-CustomView 2 with dynamic Height depending on data
The UIViewController creates new instances of the custom views with data and then adds them as subviews to the UIScrollView. The problem I'm having is how to set the value of the scrollview's contentSize? Right now, I'm not doing that and the contents of the scrollview are clipped with no scrolling possible.
Should the custom view call [parent setContentSize:] in its drawRect:?
Should the UIViewController query the custom view after creation to get its bounds and then call setContentSize?
Should I subclass the UIScrollView to override addSubView to query each subview's height?
Is there something else I'm missing?
I hope I explained that properly. I'm new to this and still getting a handle on things.
The contentSize of the scroll view should be the size of the union of the frames of all your custom views. Whenever the size of a custom view changes, or one is added or removed, the view controller should calculate the new contentSize and apply it.
Setting it from drawRect: could essentially set up an infinite loop.
Using the bounds does not give the coordinates within the parent view.
You could subclass UIScrollView if the custom views do not change size.

Adding UIScrollView using interface builder

I am adding a UIScrollView as a subview to the controllers view. After that i am adding 2 views to the scroll view as the content view.
When I am printing the subviews of the scroll views using NSLog(#"Scroll View Subviews : %#", [scrollViewObj subviews]);
then it is displaying 4 subviews , 2 for the views added to the scroll view and it is automatically adding 2 image views ?
I cann't get why the image views are added as subviews to the UIScrollView ?
I am adding the Scroll view and 2 views to the scroll view using the interface builder.
thanks.
I bet those are used for the scroll indicators to the right and bottom of the view.
The two extra subviews are indeed for the scrollbars. You'll only see those in there if you opt to use anything other than the default scrollbars.
If you want to know the number of your own subviews, set the tag property on each one before adding it in (to a positive integer, for instance). That way you can walk the subviews and see which ones have a tag value > 0.
I'm sure UIScrollView has a bunch of child views that are part of how it functions. I wouldn't worry too much about it.

Difference between directly setting a controller's view and adding view as a subview

I have just started learning objective-C and the iphone sdk and I have a question that I hope someone can help shed some light on.
What is the difference in the following:
self.view = someView;
and
[self.view addSubView: someView];
Say for example, in a simple app, where we have only one controller and one container view (has a few image subviews).
What is the difference between the two statements? The reason that I'm asking is because I was tinkering around in some sample code and I noticed the view was being initialized with images as subviews like so:
if (self = [super initWithFrame:CGRectZero])
{
//adds some images as subviews here
}
As I understand it the initWithFrame: CGRectZero, creates a frame with size at [0,0,0,0] (essentially invisible).
When I directly set the view with
self.view = someView;
I notice the view actually displays the image. But when I add the view to as a subview of controller's 'default' view, it doesn't. So basically my question is, whats going on behind the scenes? Why is the first method "resizing" the frame and the second one not doing the same thing.
What you see on the screen of your iPhone is almost always a hierarchy of views.
When you look at, say, your inbox in Mail, you're seeing a bunch of views. There's a big containing view.[1] Within that, there's a navigation bar view, a table view, and a toolbar view. Within the navigation bar view, there's a button view on each side and a label view in the middle. Inside the table view, there are a bunch of table cell views, and each of those cells has several label views. The toolbar has five button views. I could go further and talk about the views inside those buttons and so on, but I'm sure you get the idea.
The view above any given view is its superview; the views below it are its subviews. So a table cell view has a table view as its superview and a bunch of label views as its subviews. The top view, the one that has all the other views inside it, is called the root view.
Each view has its own drawing surface. The rectangle formed by that drawing surface is called the frame. The frame of a view is relative to the frame of its containing view. So if one of our table cell's label subviews has its frame at (0,0), that means it will be in the table cell's top left corner, even if the cell is halfway down the screen.
When you're writing a view controller, self.view is that root view I mentioned earlier; all the other views are subviews of that one (or subviews of its subviews, etc.). One of the features of a view controller is that it automatically resizes its self.view to fit the screen. (The available area will be smaller in the middle of a phone call: the status bar is twice as high then, so there's less space for your app. It will also be smaller if your view controller is being managed by a navigation controller or tab bar controller, but that's a different story.) But just because you resize its root view doesn't mean that the root view's subviews will automatically resize. To do that, you need to set their autoresizing mask (a property which tells the view how it should react when its superview changes size):
someView.autoresizingMask = UIViewAutoresizingFlexibleWidth
| UIViewAutoresizingFlexibleHeight;
(There's a graphical way to set up the autoresizing mask in Interface Builder—click the ruler icon in the inspector window and look at the "Autosizing" section.)
Even that's not enough, though, if someView isn't the right size to start with. To do that, adjust its frame before you add it as a subview of self.view:
someView.frame = CGRectMake(
0, // all the way to the left
0, // all the way at the top
self.view.frame.size.width, // same width as the root view
self.view.frame.size.height, // same height too
);
So why would you ever use subviews if you have to do all this twiddling that the root view does for you? Simple: you can only have one root view, but one view is almost never enough for what you need to do. If you really need only one view, of course, you can just set it as the root view and go on your merry way, but chances are, things are more complicated than that.
[1] I'm simplifying a bit here, but that's fine for right now.
When you add a view as a subview, you need to make sure that you're actually adding to an existing view.
self.view = view sets the controller's view. Without this (either in code or done with a XIB) you'll never see anything as the controller has no view to show.
[self.view addSubView: someView] assumes that self.view is already set. If it doesn't, you're adding someview as a subview of nil, and it will never get seen.
Basically, think of self.view as the big container, and all the subviews are just pieces inside of it. If you don't need any subviews, setting self.view to a UIImageView or UIWebView is fine. If you do need subviews, you'll need a big, empty container view in which to put them.
In your case, I'm betting self.view is never set, and you're adding your image views to nil.
Setting the view controller "view" property only changes the view it is managing.
Adding a view as a subview of another view, actually adds the subview underneath the other view.
They are very different things, as one adjusts a view controller and the other alters a view hierarchy.
As a guess, the reason you didn't see anything the first way was the frame for the subview you were adding was CGRectZero (0 in size).