Laying out UITableView contents - ios

The title itself might a bit misleading and I believe the problem is best explained with an example.
Take Facebook's feed, for instance. Every item consists of the following:
Header (user's name, etc), static height
Main content (text, attachment), dynamic height
Footer (number of likes and a couple of buttons), static height
At a minimum, the main content has one of the following:
Title, optional
Textual preview, optional
Attachment (of variable height), usually an image, optional
So, a few possible combinations of parts:
Title
Title, text
Title, text, attachment
Text
Text, attachment
etc
I've come up with two approaches:
1. Sections for each post, cells for parts
Note: the UIKit-provided header and footer wouldn't do, as I need specific spacing between each item. Therefore, I'd use these to get the spacing needed.
Also, I'm using RxSwift. This approach breaks the simplicity of data binding to the table view, although there's always a more complex alternative.
2. Multiple cell types
Not sure. Separate cell type for each possible combination of the above? Seems like an overkill.
3. Single cell type
The easiest approach. But, considering all the optional parts, there's quite a few constraints to switch and tweak (depending on the attachment height). UIStackView is not an option evidently, since the attachment must take the whole screen width, whilst the other parts use custom padding on each axis.
I'm looking for an outside perspective here, mainly from those who happen to have solved a similar problem in the past. An example of code would also be lovely (especially if it's scalable).
Target: iOS 13+.
Will AutoLayout perform alright in each of these?
What approach would you use?

Related

How to wrap self sizing UICollectionViewCell

My goal is to have a Swift implementation of a UICollectionView with dynamic content where each cell hold parts of a sentence. Each part of the sentence can be edited by the user. The problem is that some parts of a sentence might be longer than the container itself. Using sizeToFit is not an alternative because all content should have the same font size to maintain readability throughout the collection view.
Right now the behaviour I get, when I have a part of a sentence longer than the container is the following:
As you can see the third row has leading ellipsis.
What I would like to achieve is the following, the overflowing part of the cell should wrap as analogous to a span tag in HTML, like so:
Is this possible? How can I achieve such a thing?
As far as I can tell, it's possible but complex - here are a few pointers of what I'd say you're going to need:
2 additional collection view cell types: in the first, only the left edges are rounded, in the second only the right
Use Core Text API to measure where your text needs to be wrapped
In your datasource, you're going to have to then recognize the situation before you create the cells and then instead of creating a single cell, you create two, using those new types you have.

XCode autocomplete

I'm new to IOS development, I have a few questions.
1) What's the purpose of property rowheight on table view cell, I mean it does nothing even if I change its value, it always takes the value from its parent view i.e a tableview property rowheight? It visually changes in the IB but nothing happens when I run the app.
2) What's the purpose of Content View why is it even there? Let's say If I have to make some image equal to the height of the cell it restricts me. Or is there any way a content view can be changed to be equal to the cell height & width? I have to put constraints on the image in relation with the cell which is not the immediate parent of the image and I don't know if this is the correct way to do it.
3)How does Xcode Autocomplete works? like if I want to write a function tableview(_:tableview didselectrowwithindex:IndexPath) and I type tableview it shows a list, what to do next? I mean I can't type the whole fucntion with params or find the func in the huge list.
The height of the cell set at the IB is primarily used for simulation, the views described at IB are normally resized when actually used. E.g. you can set rows height to be 100 for the table view, 30 for some of the cells and keep the whole controller simulating a nice screen of iPhone 6. The same view will be used for all devices and will be scaled accordingly as well as the cells with the help of your delegate.
The content view is there for the reasons directly related to your additional requests. It holds all the content while there other views that accompany your content and are part of the cell like separators, accessory views, slide action views. Without a content view the responsibility of managing all the additional parts would most likely fall on you as a developer and while you might think that that is fine at the simple layouts, a simple enhancement to it would make a huge impact.
Fuzzy autocompletion at Xcode seems to be something Apple is working on now. If you can't wait and find it too difficult to navigate through the list, there are Xcode plugins available that provide fuzzy autocompletion.
Answering the question in the topic:
example: tableview(_:tableview didselectrowwithindex:IndexPath)
if you write tableview it will show all the symbols that start with tableview. For functions, it will show all the functions sorted by the second parameter name (didSelectRowWithIndex).
[EDIT]
it will autocomplete as far as the answer is unique and then show you a list full of options. I don't know any tricks to skip looking through the massive list. But after a while you'll know what you're looking for and it gets faster.
[\EDIT]
when you press tab, it
by the way: the delegate functions names start with the name of the object they're related to.
So UITableViewDelegate functions start with tableview.
as for your first two questions there are tons of answers for those questions on SO. This one seems closely related to yours.

iOS, fast way to generate clickable, multicoloured text

I need to generate a text container that contains something like this:
This is some random text
where a few of the words are
coloured and clickable
The clickable words should have different actions bound to them and should be in a certain colour. The container will have a fixed width and I need to know the resulting height of the container given a certain text.
What I've tried: Tried making each word a separate UILabel, added actions where actions were needed, calculated line breaks myself. The problem with this approach was that it was too slow, especially UILabel sizeThatFits. I need to generate a lot of text for a scrolling UITableView and this approach killed the scrolling performance.
What I also tried: UIWebView. For a few different reasons, it's just not an option.
What I would prefer: A solution that does not require third party code. This is optional, though if they are open source. iOS 7-only solutions are acceptable.
Lastly, what needs to be fast is the generation of the text and the measuring of its height. Determining where to click is allowed to take some time.
See that https://github.com/mattt/TTTAttributedLabel
..but i not understood about height
If iOS only is an option, watch the WWDC 2013 session 210 "Introducing Text Kit". They show things that are at least very similar to what you are asking for.

Two Lines in UITableViewCell's textLabel with new line being determined ONLY by newline character in text

I want to format a cell's textLabel to display text on two lines, with a line break character determining where the second line will begin. My problem is that, since I do not control the text that will be in the first line, sometimes the text on the first line spills over to the second line and my second line text does not display at all. Specifying UILineBreakModeWordWrap actually sometimes even breaks a word in two to wrap it, which makes no sense (I use the first line for names). I need two lines and two lines only for this label, as that is all there is room for in this particular cell. I am already using the detailTextLabel for something else. I really do not want to create a custom cell for this. Is it possible to do what I am asking?
Here's what you COULD do:
You could take your long string, split into two with componentsSeparatedByString, take each piece, use an iterative sizeWithFont:constrainedToSize:lineBreakMode to calculate the longest string that fits with the default textLabel width, then take your two newly crafted strings and append them with a '\n' character. Use that as your textLabel text.
That should achieve what you're trying to do.
But what I HIGHLY recommend to you is that you do yourself a favor and go custom.
For a number of reasons:
Yes, custom cells typically do take longer to create. But, I'd argue that in this particular case, it would be faster to go custom than to implement the above. The implementation above doesn't even account for ellipses at the ends of truncated strings. You can throw that into the mix, but that's just gonna add even more time and complexity. With custom cells and individual labels, something like this becomes a gimme.
Custom allows you to easily give your two lines of text their own fonts/sizes. Using IB, basic styling on these fields becomes a breeze. And that's a pretty slick bonus. For your users especially. You mention that the first line of text is for names - why not make it bold to better distinguish it from the second line of text?
If you plan on creating and releasing iOS apps in the future, you're gonna be making A LOT of custom cells. Why not use this one as practice?
If you need guidance on creating custom cells, this is a pretty thorough tutorial.

iOS to display a headline and a paragraph

I want to compose a view in an ios app that includes a headline and a paragraph. It will look a lot like an HTML page with h1 tag and p tag, how do I make them look like that in iOS? What controls should I use? I would prefer the answer to work with UI Builder instead of dynamical objects in code.
What I tried is using labels, and it didn't work well.
The long-standing approach for doing this is with multiple labels (UILabel), each in a different style/font/color. This is not difficult, but with multiline labels iOS will try to center the text vertically for you, so you have to lay out the height of the labels in code, using sizeWithFont:forWidth:lineBreakMode:, and then you have to position the labels correctly in code.
I must stress that this is not hard to do. It is tedious but it works.
However, in iOS 6, the problem is completely solved: you can just use NSAttributedString. This lets you create one string consisting of multiple paragraphs in different styles/fonts/colors, which is a way doing for real the very thing we were trying to simulate earlier using multiple UILabel objects. You get to dictate margins, spacing between paragraphs, etc. - the whole works. It's fantastic.
I suggest you watch the WWDC 2012 videos concerning attributed strings in iOS 6. Do not, however, believe their repeated mantra that UILabel is your locus of power for displaying attributed strings. I have found, for example, in rewriting my app, that multiparagraph attributed strings do not always play nicely with UILabel. So I have found it easiest to lay out the attributed string by drawing it directly in the drawRect: of a custom view, using the new NSAttributedString drawWithRect:options:context: method.
Why didn't labels work? I would recommend subclassing UIView to hold two labels (heading and paragraph) and style them appropriately. You'll need to specify what your issues with the labels were and what exactly you're trying to accomplish if you need further advice.

Resources