Width and height not adjusting with Xcode Auto Layout - ios

I have created an interface for my app in Storyboard under the Any x Any layout setup, when I run my app the layout is still sized for the square Any x Any and not the phone screen. I want the app to adjust to all sizes and not use a set layout for set screen sizes. How can I do this?
Here are pictures to show my design, and the outcome of running the app.
Storyboard View
Simulator View
The table view is also cut off here

If your ViewController is subclass of UIViewController then add leading, trailing ,top and bottom constraints to UITableView, and contains to your custom navigation bar. or If its subclass of UITableViewController. No need to add any constraints. Just embed your TableViewController into NavigationController.
Hope this will help you

what exactly are you trying to achieve? Your tableview to be entirely on the screen, so not scrollable?
If so, then you should override the layout of your tableview and its corresponding cells. As those cells (and the number of them) define the height of your tableview.

From what I can see it appears that you have manually added a UINavigationBar. I personally find it much easier to embed your view controller into a navigation controller. This will provide you with a navigation bar that will automatically resize depending on the hardware, or size class, of the device. To embed it go to: Editor -> Embed in -> Navigation Controller.
Your TableView seems to be fully in the screen as well? If you have layout issues with your cells not adjusting then I will be more than happy to help you once you clarify what is not quite right.
Hope this helps.

Yep. Been there, done that. Just because something is centered in the Any x Any view in interface builder does not mean it will also be centered e.g. in an iPhone simulator. You always need to make your layout choices explicit with constraints, i.e. in the this case add a "center horizontally in superview" constraint or align the right and left edge with the superview (I really would need to know more about your view controller in interface builder to tell you exactly).
Are you familiar with constraints or should I add some more detail on how to solve this?

Related

Horizontal scroll view not scrolling

I've just vertical scrolling a few times in the past, but now I'm trying to implement horizontal scrolling but when I run it it doesn't scroll.
What is the problem with it?
P.S. is it possible to design and layout views using a storyboard for scrolling? In this example the blue view is still visible within the screen representation, so its ok to deal with, but suppose I wanted to add another view which is further to the right and thus not visible within the screen representation? Is there anyway of visually designing a scroll view where you can see all the entirity within the storyboard what it will look like?
You don't have a trailing constraint on the scroll view's direct subview, so the scroll view cannot compute the correct contentSize.
Also, it's easier to understand the constraints in the document outline if you give each view a unique label. You have two views labelled “View” so it's difficult to be sure which constraints connect to which “View”.

Cannot change custom UICollectionViewCell in Storyboard

I have a UICollectionView with custom UICollectionViewCells. I used Interface Builder (via XCode 8) to size the collection view and cells when first making it.
Now, I'm trying to adjust the size of the cells and I'm unable to do so in Interface Builder (using XCode 9). I cannot adjust the width or height of the cells on either the collection view itself or on the custom cell. The up/down arrows don't do anything and neither does typing in a value. It just stays set at 145.
I saw some answers about not being able to do this with a UICollectionViewController via Interface Builder, only a UICollectionView, but it is a collection view and not UICollectionViewController.
I'm sure there's some new setting/config in XCode 9 that I'm missing, but I can't figure out why I can't adjust the custom value.
I ran into the same problem.
Turned out that the item size was defined by the contained flow layout. So editing the item size in the flow layout, and the parent collection view had its item size changed accordingly.
I tried Jonny's answer, but I use a custom FlowLayout and couldn't edit it's cell size either. I had to manually edit the size of the collection view, the cell and the layout in the storyboard source code (right-click on the storyboard in project view and select "open as / source code").
Now the size is correct but still not editable from the UI ¯_(ツ)_/¯
Same problem, width would not change. But I changed the height to something different and it then let me edit the width.
Xcode 12.3. I had the same issue and what fixed it for me was changing the collection view scroll direction from vertical to horizontal to make the change, then obviously reverting back to vertical (my intended direction) once I was done editing the values.

Scrollview won't scroll all the way down

I have a scroll view which works fine. Almost. I'm building in Any/Any. The problem is that the scroll view won't scroll past the view controller. I have a switch that is mostly in the view controller window, but the rest is off the box (not really sure how to describe it; it's in the view in the scroll view, but the view is longer than the view controller so part of it is hidden).
The scroll view will scroll down until it hits the part where the view controller would end if you were looking at it in Xcode. There is some more stuff under the switch (labels and another switch). To view these you have to forcefully scroll down. Xcode shows no constraint errors (little red circle with white arrow).
Hopefully this makes sense
A ScrollView needs to know the height and width of the content it is holding in order to know how much to scroll and which direction. Here is a quick read on how ScrollViews work in iOS: https://www.objc.io/issues/3-views/scroll-view/
You can set this programmatically using the contentSize property, but this requires you to know and or calculate the contentSize, which is pretty tedious in most cases.
The correct way of defining the contentSize in iOS is to define AutoLayout constraints in your View. Here is an excellent tutorial on doing just that:
https://www.natashatherobot.com/ios-autolayout-scrollview/

Why content insets of a UITableView inside a UIPageViewController get messy right after an interaction?

I've created a Page-Based Application and hacked it a bit for some experiments; my simple aim is to have a UIPageViewController whose pages will contain a UIViewController holding a UITableView (after further inspection, the outcome of my experiment is the same if I use a UITableViewController instead).
To do this I've simply edited the project template, and added the UIPageViewController as an embedded view of the RootViewController using Storyboard's ContainerView object, as you can see in this screenshot:
Every controller is configured via storyboard to automatically adjust scroll view's content inset, and if I start the project with this configuration everything looks fine, and the DataViewController's tableview has its content insets properly adjusted right under the navigation bar as expected; however, as the user makes an interaction with the tableview, the content insets break and the tableview underlaps the navigation bar:
I have been able to fix this by manually setting the content insets in DataViewController's viewDidLayoutSubview method, and by disabling Adjusts Scroll View Insets on any controller, so I don't need this as an answer to solve my problem.
My question is why the content insets are properly set right after the first controller gets loaded from the storyboard the first time, and why they break after any kind of user interaction.
If you need to test it directly, here's a link to the project
I'm not 100% sure it's what you're running into, but here's some explanation regarding your setup:
By default, UIViewControllers tend to be configured to extend their content behind non-opaque bars, and to adjust scroll view insets. In your setup above this means that the container VC:
Extends its content so as to appear behind the navigation bar
Sets its scrollview's .contentInset and .scrollIndicatorInsets to be the same height as the navigation bar
"But, ah!" I hear you say, "that container view controller doesn't have a scroll view". Well this is the tricky bit:
It seems UIViewController's definition of "my scroll view" is rather simplistically, "the first scroll view I come to when searching down through my view hierarchy".
UIPageViewController happens to be implemented using a scroll view. So the container VC finds that scroll view, and adjusts its top insets. This is not really what you want; it confuses the page controller, and tends to upset layout at some point.
The simple solution there is simply to turn off .automaticallyAdjustsScrollViewInsets for the container view controller.
You then need to solve the next problem of your table view needing some kind of top insets to account for the navigation bar. So far it seems to me the best way to do this is manually either in the storyboard, or code.
Found an elegant solution:
From your storyboard, select your UIPageViewController
In the Attributes inspector, uncheck the option ViewController => Extend Edges => Under Top Bars
That's all, no weird UI hacks
Have you tried fixing the Auto Layout constraint in the container view of the Root view controller in the Storyboard (that is, the top space constraint should be set related to the Top Layout Guide and not the Superview, with constant = 0)?
You will only lose the effect of the Table View scrolling under the Navigation Bar

Uibutton contraints in two layouts

I’m still trying to get my head around constraints and the objective c best practises in general.
I need to dynamically create between 1 to 6 UIButtons depending on a variable. I’m ok with this part but confused with how to position them given that:
The number of buttons could be anything from 1-6.
The buttons have to be of equal size.
Landscape and Portrait orientations will have different layouts.
They have to ‘float’ left in the landscape view and vertically align to the top in portrait view.
I'm guessing I'll need one container that sits at the bottom of the view and changes height depending on the orientation, then have rules for the buttons inside depending on the container width. But how to go about it I have no idea.
In the long run it will be better to use the UICollectionView. Subclass UICollectionView and add it in your Storyboard. Make an outlet of the collection view to your view controller and set its delegate and data source. Add the <UICollectionViewDelegate> and <UICollectionViewDataSource> to your view controller and implement the delegate methods. For the buttons, make a custom UICollectionViewCell with a UIButton as its subview. Then in cell:ForRowAtIndexpath: method, initialize the UICollectionViewCell subclass, and set the properties of the UIButton. This might not be the answer you wanted, but UICollectionView offeres much more flexibility as far as layouts are concerned. You can read more about UICollectionViewDelegateFlowLayout here.

Resources