Cannot move content view in cells in Interface Builder - ios

I can't change a position and size of title and subtitle label in Interface Builder. What should I do?

You can't edit the position of the default UITableViewCell subviews in interface builder. You can change the text alignment, content insets, and other related properties but you can't explicitly change their frames. You can do this in code when you are displaying the cells themselves as some other answers point out, but I recommend against doing this as it can cause some other side effects when Apple makes changes to these components.
If you need to customize the position of these subviews, you should instead just build them manually. You can do this in interface builder by selecting the cell, then selecting the 4th tab on the right (Attributes Inspector), then change the Style to Custom. Once you do this, the default subviews will disappear in interface builder and you can just add your own.

You have chosen the default cell style for your cell. The Title and Subtitle labels for the chosen style you see are some basic UI controls that are meant to be used for typical scenarios of displaying content in a tableView usually. If the framing of the labels are comfortable and okay to you, then it is fine. If not, you need to make your own custom style cell.
Basically you cannot modify the default cell style that Apple provides. Just make the cell style Custom and do whatever you want with the layout.

Related

Dynamic type "Body" style doesn't work in a UITableView with static cells

I'm designing a table view with static cells in Interface Builder, and I want the text size to change to support dynamic type. I've created a cell with "Basic" style, which means it contains one automatic label, and set the size of the label to "Body". But the font is always 17 points regardless of the dynamic type setting. This doesn't happen with labels I manually add to "Custom" style cells.
Screenshot:
The cell at the top is the problematic one. It's 17 points even though I've turned the dynamic type font size all the way down. The second cell was created by manually adding a label to a "Custom" style cell and setting the font size to "Body"; this is what the first cell should look like. The third label is a "Basic" style cell fixed at 17 points, for comparison.
MVCE is available here: https://drive.google.com/file/d/1-3di9-WWVsjcbktD6mxAyU4BrLR_g6nG/view. I unfortunately can't paste the code into the question because there is no code, only a storyboard. Here's how I made it:
Create a new single view project
Delete the view controller from the storyboard
Add a new UITableViewController, set it as the initial view controller
Select the table view and change "Content" to "Static Cells"
For the first cell: change "Style" to "Basic", then select the label and change Font to Text Styles - Body
Second cell: leave Style as Custom, drag in a label, and change Font to Text Styles - Body (same as above)
Third cell: change Style to Basic and don't change text size
Actually, the only solution I figured out on my side for this problem is to switch the style to Custom ⟹ you can't use the Dynamic Type feature as expected with Basic static cells. 😨
Other use cases have encountered this situation as explained in this stackoverflow answer:
Dynamic type does work with static tables, but in my tests, just not with "Basic" cell type.
Change it to a "Custom" cell type, add your label and the four constraints, and make sure to choose one of the dynamic fonts.
... and this site details every steps to get the result with illustrations if need be: 😉
To overcome this problem we must set the table view cell style to ‘Custom’ and drag a label (or labels) in ourselves.

hide/ show controls in View controllers

My application gathers input from users and hence it is full of Labels, text boxes and buttons and I have to show or hide set of labels and text boxes based on certain conditions.
To accomplish it, I did the following.
Set fixed height (lets say 30) for all the controls
Set height constraint on each of the controls and created an outlet to the height constraint in the ViewController
Alter the heightConstraint.constant value programatically (between 0.0 and 30.0) based on the scenarios.
Having programmed like this, it is very difficult for me if there is any change in layout. (i.e., if user requested to add/remove any particular control from the view Controller).
I am using Auto Layout constraints. Could anyone suggest if there is a better way to accomplish my goal.
I am using IOS9 and Swift.
Many thanks in advance.
You can use UITableViewController with static cells for this case.
For hide/show row or section, you can change the size in the tableView:heightForRowAtIndexPath method.
UITableViewController automatically manages the layout and with static cell you can even create outlet for all the controls.
Have you considered using a table for this? It has mechanisms for inserting and deleting rows and would manage the layouting for you - only part you'd need to care about are the contents of the cells.
Instead of making IBOutlets to the height constraints of all the views that you might need to hide, you can just use the hidden property of UIViews to hide/show the view.
In case you need the view to make space for other views, you could set a simple animation and move the view out of screen bounds. You might face issues with layout constraints but it's surely worth the effort from a UI/UX perspective.
Additionally, if you know that you don't need a view any more you can even remove the view from it's superview.

Must I use -[UITableViewCell contentView] for uneditable cells?

I'm building something similar to the compose page of the native iPhone Mail app.
But, I'm putting two text fields on one row, and I want to separate them with a vertical divider (an additional view) that's the same color & weight as the horizontal cell separators.
Apple's docs say:
If you want to customize cells by simply adding additional views, you should add them to the content view so they will be positioned appropriately as the cell transitions into and out of editing mode.
But, what if I know, like in this case, that my cell will never go into editing mode?
Also, the horizontal cell separators are subviews of the cell, not the cell's content view. So, I think it'd also make sense if I added the vertical divider to the cell, not the cell's content view.
Can I just add additional views to the cell itself, instead of its content view?
You can add additional views directly to the cell, but it's best practice to add them to the cell's content view. Even if you're cells never go into editing mode, this is what Apple and other developers that may be working on your code (or you in the future) are expecting. So, this will make it easier for them to work with your app.
For example, what if Apple hypothetically decided to put gutters on the left & right side of plain style table views in a future release of iOS? Then, they would probably inset the cell's content view but not the cell itself. That way, if you position your additional views relative to the content view, your app has a better chance of looking good and the additional views have a better chance of not getting clipped by Apple's hypothetical gutters. OK, I doubt Apple would do such a thing, but the point is that if you add your additional views to the cell's content view instead of the cell itself, you're code will be more robust.
For your specific case, I still recommend adding the vertical divider to the cell's content view because you can. You might even consider setting the tableView.separatorStyle = UITableViewCellSeparatorStyleNone and redrawing custom separators by adding a separator view to the bottom of each of your cells' content views. This way, you can be sure that the style of the vertical divider you add will always match that of the separators. Again, this will make your code more robust and protect you if Apple decides to change the style of their separators. Sure, you can use cell.separatorColor. And, you can guess the separator weight with cell.frame.size.height - cell.contentView.frame.size.height. But, such cleverness might get you in trouble.
As the Buddha admonishes Siddhartha, "Beware of too much cleverness!"

What do these settings do in Interface Builder?

This is for a UIButton specifically. I understand that the alignment options pertain to the label inside the UIButton, but what does the 'content' settings do? They seem like they correspond to the setEnabled:, setSelected:, setHighlighted: methods of the UIButton class, however clicking Highlighted or Selected doesn't seem to change the button's behavior outside of interface builder. Also, what would be the use-case for having a button always show highlighted or selected?
There are several practical uses for these methods. As #MHUMobileInc. pointed out, it can be used for a game like Minesweeper. It can also allow you to use the button as a sort of switch, where the selected button has "ON" and the non-selected version has "OFF". It seems that Apple wants developers to shy away from this, and to use either UISwitches or a custom view. However, Apple does contradict itself in some of its apps.
These settings set the initial state of the UIButton- so if in your viewDidLoad you set it not selected nor highlighted, this Interface Builder setting will not be seen on screen when you run the app. If you want to ensure that these settings are kept, it might be easier to say so in code (viewDidLoad) rather than Interface Builder.
It may be easier not to use these settings too much. They can lead to confusion for you (the developer), other programmers who are working on the project (if any) and the user. Use the built-in UIKit views when it works and create your own subclasses when there is nothing that fits best for the situation.
The upper portion addresses the alignment of the content within the view. For example, if you have a large UIButton with an image that's smaller than the bounds of the button, by default the image will be centered vertically and horizontally inside the button. However, if you want the image to hug the left/right/top/bottom, you can set the alignment using those options.
All of these controls pertain to the UIControl, not UIButton, as indicated by the header in that screenshot.
Alignment refers to contentHorizontalAlignment and contentVerticalAlignment. Many controls return a fixed width or fixed height, or both, from sizeThatFits:. For example a UISwitch object has a fixed size, whereas a UISlider object has a fixed height. If you assign a frame to a control object that does not correspond to these fixed dimensions, these properties determine where in that frame the control interface should be drawn. Instances of UIButton do fill their frame, so the UIButton class interprets these properties differently to apply to the button's content, but the properties themselves are not specific to the UIButton class.
Similarly the selected, highlighted and enabled properties are defined by UIControl not UIButton, not all subclasses of UIControl utilise them.

How to create a hidden cell in UITableView in interface builder

I want to create a 'hidden custom cell' effect like that used in the popular 'pull to refresh' pattern (http://stackoverflow.com/questions/9076905/uitableview-hide-first-cell). I'm not creating a pull to refresh interface but I want a special cell at the top.
I can work out how to do this using the many pull-to-refresh examples but they all create the hidden view in code. I would like to create this in interface builder.
How can I do this? I would like to use storyboard if at all possible.
the concept is very simple. The idea is to set a negative edge inset for your tableview. SO assume your first cell is 44 px in height:
[self.tableView setContentInset:UIEdgeInsetsMake(-44.0, 0, 0, 0)];
the following code will cause the table to start showing the content 44 pixels down, which will create that hidden cell effect.
You can achieve the same thing with interface builder. It is in the size inspector under 'Scroll View Size'. You will have to set the Content Inset for the 'Top' attribute to a negative number.
hope this helps

Resources