Auto-layout in UITableViewCell: make UITextView appear only if content not null - ios

In my project, I have three types of custom UITableViewCells. One for text-only, one for text + url and one for text + image. I am using auto-layout with IOS 8.0 and am trying to use constraints to make the text block only appear if not null. The text being before url and image I don't want to get an extra useless space.
Is it the right way to go or should I implement two new types for image-only and url-only?
I have been trying to set up height >= 0 for the text block in the constraints but it keeps be displayed.

If you don't want the text view to take up space, remove it from the cell for that row. Of course, for rows where the text view is needed, if it is absent, you will have to add it. Making the constraints correct will also be up to you.

Related

minimum number of lines UILabel in iOS development

I was trying to make a cell in uicollectionview. please see these two images
Thats the cell of a collectionview and the first uilabel's number of line is 2. what I am trying to do is the uilabel will always take 2 lines of height regardless of the content of the uilabel, is it possible? if the text is short, second line will be blank.
If I add height constraint, the text is vertically centred. How to make it top-aligned?
There are 2 steps.
First select your label, click the add new constraints, and check the height constraints, as grow4gaurav said.
Next, go to the attributes inspector and set the number of lines to 0. This makes it so that the text uses as many lines as it wants. So, if the text is short, and it only uses one line, it will just use the top line. If it is longer, it will use the bottom line too.
Hope this helps

Autolayout vertical spacing of group of textlabels when one is empty

I have a group of text labels that are vertically spaced to each other 15 pixels.
The problem is that when one of the labels is empty, then there is extra space between the other two labels above and below the empty one (30 pixels).
I know that one solution would be to constraint all the text labels to the top and to the labels above and then I can just delete it and everything should look aligned but the problem is that I reuse the view and sometimes all the labels have text and sometimes some are empty. So if I delete the label, I would have to recreate it and readjust the constraints manually.
Is there a way to delete the extra vertical spacing when one of the labels is empty without deleting it?
Edit 1: The labels don't have any Height constraint so the empty one will be 0 pixels high
Edit 2: I need to support iOS7+
Possible options:
do not use multiple labels, but a single one, possibly using an attributed string if you need different formatting for the different parts
add an outlet to each of your constraints, and adjust the constant based on the label having text or not
There are quite a few others, including the use of table views, stack views (iOS 9+), and probably more...
If you are ok with supporting iOS 9 and above then you can use stack view and set the constraints for the labels within the stack view. But instead of emptying the label you should hide the label. When the label is hidden the stack view automatically brings up all the labels below it. You should get the desired behaviour using this method.
My rule of thumb is if layouts get overly complicated to do in Interface Builder, then it's better to just write code to do it. In this case I'm not even sure it's possible to define in IB. But even if it was, I'd do it in code. It's not a complicated layout, it will be more reusable, it will be cleaner in code.
A few options:
A - You could modify constraints in viewWillLayoutSubviews - it's kinda messy to hold on to so many top constraints. Somewhat less messy if you add them all to an outlet collection (array of outlets, basically).
B - You could manually adjust frames in viewDidLayoutSubviews - although it then begs the question, why even use AutoLayout at all if you're doing almost all the work manually anyway.
C - Use SnapKit and generate those constraints in viewDidLoad and / or update them whenever the text changes. I highly recommend SnapKit. Think of it as a sane way of programmatically creating AutoLayout constraints. It's very clean, and very simple.
See http://snapkit.io

Fill UIScrollView with its content using autolayout in iOS

I am making a form based UIScrollView, which will contain some labels and text fields.
My ScrollView Height will increase as per the iOS device height.
PS: I do not want to add constraint to each and every element of the Scrollview, because in my case there could be 100 form fields.
What I want is, the inner content to fully occupy my scrollView like this:
Till now there a are no special constraints, the button is tagged with the bottom edge and the scroll view is pinned from the top edge. Also, the vertical spacing between scrollview and button is defined.
This is the autolayout constraint screenshot.
If the number of labels is variable, I recommend doing them in code, rather than in Interface Builder.
In code, you can use a loop to set every label to have the same width/height as the one above it. You may want to set their height to be >= a minimum value. Be sure to anchor the first label with the top, and the last label with the bottom.
But this can be cumbersome, why not just use a UITableView? you may modify the row height to let the cell fully occupy the view.
- tableView:heightForRowAtIndexPath:
- tableView:estimatedHeightForRowAtIndexPath:
I just face the same issue and already write a pod called TLFormView that do exactly that: a form based on UIScrollView.
It also has some nice features like:
declarative form taxonomy with TLFormModel Just extend it, add the properties you want and that's it. No delegate, no event handling, no boilerplate.
a nice way to handle different layouts for iPhone and iPad
conditional visibility with an NSPredicate that can access all the values in the other fields (e.g: show field A when field B has certain value)
in place help with a popover
all the fields are TLFormFields that extend UIView so you can place whatever you need.
You can try it right from the command line with pod try TLFormView.
If you want to know more I wrote some blog post about it here.
Please let me know your thoughts about it here or as a comment in the blog posts. Also any contribution is extremely welcome in the GitHub repo

How to make a fluid layout in iOS?

What is the proper way to make a fluid layout in iOS, in the sense that hidden elements do not take up space anymore?
I have a table view with in each cell a customized detail-type of view with title, subtitle and a row with some extra information:
The extra information can be up to three pairs of an icon and a label with a value. The layout of all views inside the cell is done using AutoLayout with no missing or ambiguous constraints.
What I would like to achieve is that when the value is 0, the icon and the label are not displayed and the views on the right are shifted to the left.
If I just use the setHidden: method, the width of the hidden parts are not changed, so that there is just whitespace, but no views are moved. Example:
It should look like this:
The following questions are related but do not seem to fit my case:
Fluid UI layout on iPhone
AutoLayout with hidden UIViews?
I have tried to follow the approach with creating layout constraints for the four frames that need to be set to zero: the width of the heart-shaped icon, the width of the label containing the value, the whitespace in between those and the whitespace between the label and the next icon. This did not work because I could not bind the layout constraints to the outlet in the code, and besides it seems a cumbersome method for something that should be a common scenario.
EDIT: I fixed the problem with the outlets to constraints: to do this it is necessary to create a subclass for the table cell and creating outlets for the constraints there.
With "common scenario" I refer to doing something similar in web design, where setting the display style to none is simple and has the desired effect. I expect that there is something similarly simple for this in iOS.
I have been thinking of using a collection view with reusable cells, but then I need to set up a delegate and a datasource and everything, and before I would go this way I wanted to make sure that that is the way to do it.
There is no need to remove a hidden view. Connect the constraint to an outlet in the code, and when you determine a view is hidden, subtract from the constraint's constant. Then, in the cell's prepareForReuse, remember to return the constraint's constant to the correct value.
Hidden views maintain their frame, so auto layout will have no reason to adjust the view. The correct way to do this would be to remove the views from the superview. The last thing you must do is double check the constraints. Since you will be removing views, you cannot use those views for auto layout. This will require quite a bit of constraint setting on your UI.

Reposition images within view based on size of text - iOS

I have been recently getting into iOS development, and I'm trying to build something that looks (very roughly) like this: http://falkendev.com/downloads/ios-sample.png
Basically, it's a page that shows simple text -- large header text that may span multiple lines, a separator line, and then smaller descriptive text that may be a variable length. This text does not need to be editable. I'm working using interface builder, but I imagine that what I want done may need to be done programmatically?
Two questions:
-- How do I go about creating these text fields so that they adjust their height based on the content? I'm assuming I would be using a standard "text" field for each, make them not editable, and then programmatically change their height? And then based on the height of the various text fields, I would need to adjust the positioning of the text fields and the divider line between them?
-- How do I go about making the page scrollable? It's possible that the descriptive text will be long and would extend off the edge of the screen. I would want the whole page to be scrollable, not just the descriptive text section. I'm assuming I would place all my elements within a scroll view... but currently when I do that and view it, the view just gets centered (cutting off both the top and the bottom) and I can't scroll it at all.
Thanks for any help!
set the scrollview content size to greater than its actual size to
make it scrollable like this :
scrollView.contentSize = CGSizeMake(YourWidth ,YourHEight ); // Here you can change either of height and width to make it more scrollable in that direction.
You can use UITextView object to have a scrollable text field...
which can scroll to show additional text..just set its editing
property to NO.
Otherwise to dynamically update label height yourself...use
NSString sizeWithFont method

Resources