I'm midway of finishing my app. I noticed that one of my views needs extra vertical space so I need to add a UIScrollView. Yet when I add that scroll view it overlaps everything else in the view. In simple words if I need to get it to work properly I have to delete everything off the view , add the scroll view, and then re-add everything back! Is there anyway to send this scroll view to the background of the view? This is all the code that concerns the scroll view
#IBOutlet var scrollerForPOfFourBar: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
/* non related code here*/
scrollerForPOfFourBar.userInteractionEnabled = true
scrollerForPOfFourBar.self.contentSize = CGSizeMake(320, 400)
}
I'm assuming you're using Interface Builder since you marked your scrollView as an IBOutlet.
On the view list, on the left, the order of the views specifies their Z order, with the views at the bottom being the ones drawn on top (with the largest Z).
To move your scrollView to the back, drag it just underneath of the view, and drop it there.
Keep in mind that you will have to drag all the views you had in your view into the scrollView (the easiest is to do it in the views navigator as well), and you'll have to set up any Auto Layout constraints again, which will be a pain.
Are you just want to move scrollerForPOfFourBar to back? Try this:
self.view.sendSubviewToBack(scrollerForPOfFourBar)
Related
I'm trying to make a ScrollView so that its size adjusts to the size of the text. I placed all the necessary constraints
, but when the application is displayed on the simulator, the content view starts from the safe area and also ends up to the safe area. Although I have pinned scroll view to superview and content view to scroll view.
I want the content to start not from the safe area like here ,
but from the start of the screen like here
in other words, I want to remove the blue bar from the top and bottom
Do you have any ideas how to do it?
Sometimes UITableView & UIScrollView can still show safe area even though you attach your View to top of Super View. You just need to add one line to solve this issue but make sure your ScrollView is connected to superView not safe area at the top.
Add scrollView to your ViewController and in viewDidLoad() just write:
scrollView.ContentInsetAdjustmentBehavior = .never
Check this answer for further details: Make UITableView ignore Safe Area
In an app I created, I drag and dropped a 'Scroll View' to the main storyboard. This automatically creates a NSScrollView, inside of which is an NSClipView, inside of which is an NSView. Fine.
What I would like to achieve is to dynamically add checkboxes to that scroll view. I don't know how many checkboxes there will be in advance (which is why I need a scroll).
adding a subView to either the NSScrollView or the NSClipView actually displays some checkboxes, but the scroll is not enabled. Adding a subView to the NSView renders nothing.
Edit: I have also tried to modify the NSScrollView, NSClipView, and NSView's height, with no luck.
How can I enable the scrolling when too many checkboxes are added to the view?
So the trick to this is creating a container view (i.e. NSView) to hold the buttons. When you create a NSScrollView in the storyboard, it creates NSClipView and NSView for you. After you add or remove a button to the NSView (you can create your own, or use the one provided), set the documentView of the scroller to the view that contains your buttons. That resets everything properly in the scroller, and you should be scrolling! If you change the size of the view that represents the scrolling content, you just reassign that view to scroller.documentView and it will update everything accordingly.
Here is a horrible example of adding 20 buttons to a scroller that will scroll:
let documentView = NSView(frame: CGRectMake(0,0,200,1200))
for index in 0..<20 {
let offset = CGFloat(index * 50)
let button = NSButton(frame: CGRectMake(0, offset, 150, 50 ))
documentView.addSubview(button)
}
scrollView.documentView = documentView
The Apple documentation on this gives more detail and further options you may want to set.
Hope this helps!
I am pretty sure this has something to do with the dreaded AutoLayout. (been trying since 2days to get hang of it)
So I mastered it somewhat, but now I have problem where my UIScrollView is not scrolling fully down, pictures are much better at explaining these things
this is the scroll view
this is the content view
so the problem is the scrolling is happening but then again it springs back up. So I am not able to click on the signup button
EDIt 1
Edit:
I have created a little example on github for you to look at, here. The project illustrates the answer below and uses the techniques I describe and nothing else.
Original Answer:
couple of things I would advise here.
First, I know you've been trying for a while but remove all the current constraints (painful I know but). Do this for clarity as ....
The view should be the size of the scene, it looks like you want the scrollview to be the full screen so that too needs to be the size of the scene.
e.g. if you are designing at 6Plus by default the scene size is 414x736 so the view and the scrollview it contains should also be 414x736.
Only the content view needs to be the size of the real content you wish to show. Let's say for arguments sake that the content is 414x1000.
Now the constraints for the scrollview are simple. It needs zero spacing to all it's edges.
You can add the content view to the scrollview in a couple of ways. The way I try to do this varies from project to project and depends mostly on how complex the scene is. If it's a really busy scene I keep the content view outside of the scrollview in interface builder so that I can work on it easily and visualize the whole of the view. Then I add the content view to the scrollview in code.
If its a simpler view You can add it inside the scrollview in interface builder. Ultimately whichever way you do it, you can lose visibility of the content view in interface builder because the contentview is larger than the scrollview and the content gets obscured. So play about and find a good way for you.
Define the content view and all it's subviews. The content view needs to be taller than the scrollview otherwise it wont scroll. All of the content view's subviews need to have defined heights from top to bottom and widths from left to right. In your case the scrollview is scrolling vertically not horizontally so all the widths need to add up to the width of the scroll view BUT the heights need to add up to the full height of the content view.
Note: if you do this proportially your life will be easier later. If you do all this with fixed heights the storyboard will break on different device sizes.
Now the "tricky bit" and it's a bit counter intuitive. You need to pin the content view to the scrollview, remember the height of the content view is taller than the scrollview. In all other circumstances in Interface Builder pinning a view to a superview (0 padding) will adjust the height (or width) accordingly. For the relationship between a scrollview and it's content view this doesn't happen.
First pin the contentview
Notice the -400? Remember the content view is taller than the scrollview and we will change this immediately.
Select the bottom constraint (-400) that we have just created:
Select the drop down arrow next to the constant value:
Select Standard Value and type in 0 for the constant.
You should now have a storyboard with no broken constraints and if you build and run you should get a scrollview as desired.
Your bottomspace to superview on your content view is set to -74.0, I don't know if there is a reason you had to do that, but try setting it to -8.0. I think your scroll view is scrolling up to the 0.0 mark automatically
I have a UIViewController that I designed in Interface Builder. near the top of the View it has a UIImageView and then some other Views (Text etc) below. These are set to anchor to the top of the view.
In code when the view loads I remove the UIImageView in certain circumstances but it still seems to take space or the view's below don't spring up to the top based on their Anchor.
How can I make the Views below move up if the View above is removed?
You can change the frame of the other elements in the view.
in the viewDidLoad method you can use something like that:
-(void)viewDidLoad{
if(imageVisible){
otherElements.frame = CGRectMake(....);
}else{
otherElements.frame = CGRectMake(....);
}
}
I don't know what is the structure of the view, but you might consider nesting all of the other elements in one view so you could change all the elements positions in one command.
Unlike the Android view hierarchies, iOS view hierarchies are all developed in absolute coordinates. When you say a subview is anchored to the top, that means that if the size of the parent view changes, your view will stay in the same relative position to the top of the screen.
In order to make your views below the image view move up when the image is hidden or removed, you will have to manually arrange them yourself to account for the offset
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).