[Ok I've had to ask this question again as the first time I was unregistered, and I can't seem to register and link my fb id to that account/or give feedback on my question otherwise! Any way here's the original question, and extra info - original url: Stop image expanding in multiline table row? ]
I'm having problems implementing a table row that allows text to wrap to multiple lines, and also has an image on the left, and a disclosure accessory on the right.
The multiline text is fine but the imageView expands to the right when there is more than one line of text. I want images in all rows to be the same size. I've tried setting the autoresizingMask to UIViewAutoresizingNone but this doesn't seem to work.. Do I need to use the contentView, or a nib file?
Any help/example code appreciated!
EXTRA: HaveYouMetPrabu's answer to my original question kinda worked - but so did my current code UNTIL I changed the row height in heightForRowAtIndex path for rows with more than one line of text (even using an autoresizingMask of UIViewAutoresizingNone) - then the image expands to the right. So I think the solution needs to include both the cellForRow.. & heightForRow.. methods. My current heightForRow.. implementation is probably too simple just switching between 2 fixed row heights depending on the text length..?
Related
I am trying to recreate a menu similar to the ones in the detail view of the iOS 13 Health app. Please refer to the marked up screenshot.
I know that this can be done with a table view. There's a section title and list items. But what I want to achieve is similar to the look shown in the screenshot whereby there's a background colour on the list items (not including the section title) and rounded corners at the top and bottom of the list.
Can anybody tell me how I can achieve this with the table view? Or point me towards the right direction? I already know how to setup table views and programmatically add the details. I just need help on how to achieve the styling as shown below.
Thanks!
So, I was able to figure it out. For the benefit of the devs who stumble in the same dilemma, I'm posting my solution here. But I will be tagging Glenn's answer above as the correct answer as it lead me to find the solution. Thanks again Glenn!
It appears that I didn't have to do anything special with my code. I just discovered that on XCode 11 and iOS 13, there's a new table view style called "Inset Grouped". You may set this property from IB or via code.
With a quick experimentation I was able to come up with the result as shown on the screenshot below.
It's not that complex to do. This one of the multiple ways that that style can be done.
a. You can use grouped tableView, as what you've indicated in the screenshot.
b. Provide section title, or better yet, a section view (for more customization!).
c. For each section, you have ONE tableViewCell.
d. For each cell of that c., you will have a tableView.
e. For each tableView of that d., you will have your a new cell of course (item cell).
f. How to compute for the height of the tableView of e.? There are multiple ways.
Provide static height (if your number of items are static).
If dynamic count, but you have constant height of each cell, then you can just compute it like so: itemsCount * heightConstantOfCell
If again you have dynamic count of rows/items, and you have iether constant height of each cell or dynamic height of each cell, then you can observe the frame key of the whole tableView.
g. Finally, just add some corner radius to each container view of your tableView in d..
Note, this screenshot ONLY shows the item g.. It's merely a corner radius of each container view of your tableView in a tableViewCell that is a cell of your main tableView.
Another way is to use UICollectionView, but kinda more complex than what I've discussed - at least for me.
I encountered this image on Apple's UI Design Do's and Don'ts:
Of course the UI on the left is the one I am shooting for, my question is what is the best way to go about getting this UI on the left? My initial thought was to use a static table view, with the top cell being the image and the cell below it but I came up with two problems with that approach:
How would I get that little water droplet image to span across both cells?
How do I make sure that the text field below the image is always the right length no matter how much text is put in (i.e. resizing the text field and the cell depending on the amount of text)?
My second thought was to use a UIScrollView and put the image at the top, constrain the water droplet in between them and then contain a text field below it, but then:
How would I make sure that the text field always the right length no matter the amount of text put in?
It is pretty impossible to constrain these items in a UIScrollView, how do I properly constrain this in a UIScrollView?
Why not use a UITableView, and make your cell in the interface builder that can be called through a reuse identifier. And each cell would have the image along with the relevant information that's required. This would fix your first option since you would be able to place the water droplet image over your image and your text.
For your second issue, making sure the cell is of correct height can be done by giving the UITableView dynamic height.
For example, you wouldn't need to insert a heightForRowAtIndexPath function on this tableview, and you can also define:
tableView.estimatedRowHeight = 100; //Can be any value really, but giving a reasonable estimate is helpful
tableView.rowHeight = UITableViewAutomaticDimension;
Also, your the textView you want to use shouldn't be set with any fixed width's or height in the interface builder.
TableView Image . Your imageView would be set up somewhat like the blue section in this picture (but fitting the entire width of the screen instead) and your textView would be like the red one. They would all fit in one cell and would make it much easier to organize than using 2 separate cells for one set of content, and you wouldn't have to get into the hassle of setting up the UIScrollView.
I am trying to achieve something like this for iOS in Objective C.
The fill in the blanks(UITextField) should be inline, and should be able to have its own inputType.
Also, each View is a type of cell.contentView of a UITableViewCell.
My current approach is to find the length of string and also calculate the wrapping content length to the next line. Calculate the x's and y's for UITextField and add another UILabel after the UTextField
Is there any other approach other than this?
As EmilioPelaez says, this is not exactly an answer to your question, but a suggestion:
You can use a collection view with an horizontal flow for each "sequence" (i.e. UILabel-UItextfield-etc...)
That collection view has 2 kind of cell:
One with a uilabel with the number of line set to "1"
and the correct layout to fit the cell.
Another with a uitextfield and the correct layout
Coupled with:
My current approach is to find the length of string and also calculate the wrapping content length to the next line.
You may be able to easily adjust the width of the different cells, hide a uitextfield (if needed) and display a more dynamic "sequence" (if needed)
This is not exactly an answer to your question, instead it's a suggestion for a different interaction.
I think that instead of using inline textFields, you could use a UILabel with an attributed string, and in where the textFields would be, you add a different character with a different color that you can tap (For example, this character ✚).
When tapped, you can show an overlay with a text input, and once that input is completed, you update the label with the text (still tappable, and with a different color).
I think this answer might also be relevant: Detecting taps on attributed text in a UITextView in iOS
I think your solution of separating the UILabels and calculating their required positions is a good one for versions lower than iOS9, but if you can count on iOS, UIStackView can dramatically simplify the process for you. You can read more about the process in this tutorial:
UIStackView Tutorial
Good luck!
I am trying to repduce a similar sort of layout as in the screenshot below from the Digg app..
Notice that each list entry has a title in bold followed by the source, posted time and finally if there is enough space the start of the description line.
The question is what is the best way to achieve this in iOS? With some posts having longer titles than others I cannot simply say that the title label is 40px high and then place the Source label at 45 as the title will sometimes be longer and sometimes shorter.
Do I have to calculate the height of the label based on its contents before arranging the layout or is there some better way of doing this in iOS so that the views 'below' are automatically moved down?
Another alternative would be some sort of rich text label that I could add all the text to and have it automatically wrap round moving the later text down but I cannot find any sort of control in standard iOS / Xamarin (MonoTouch).
Any pointers would be greatly appreciated?
If you are using a storyboard the simplest way to achieve this result is to define different prototype cells. For example, you could define four different prototype cells, each one with a different layout like those shown in the example picture you provided. You can dequeue the appropriate cell based on the content you want to display so there is no need to adjust the layout in the code.
If you are doing everything in code, it's a lot more complicated since you have to build your own "layout engine" to adjust size and position of the views in your cell. You can have a look at XibFree or use MonoTouch.Dialog as suggested in the comments.
I am using section headers to show a small image 'floating' next to cells from appropriate sections. The section header is transparent and contains only a imageview.
The initial problem with this solution was that the section header takes up height, which looked strange (there was unnecessary empty space in the beginning of each section + the image should be aligned with the top of the first cell when tableview is scrolled to the beginning of the section). The fix for this was to set section header height to 1px. The image was still in place, but the header didn't use any height and everything looked great.
However now I need to add a UIButton on top of that image, and unfortunately it doesn't work when the header has 1px of height. It is not hidden or covered by anything and it is drawn correctly, but the set selector doesn't get called. If I set some height, the button works.
In short - how to achieve either a working button in a section header that has virtually no height, or how to achieve a section header that has normal height but always overlaps cells (doesn't use any space when the tableview is scrolled to the top of the section)?
Any help will be greatly appreciated.
One way you may be able to get this to work is to add a transparent view over the table. You would intercept touchDown and touchUp. You could calculate whether they were over one of your buttons, and if so send them directly to the button, otherwise just forward them. the reason you don't get the touch events is probably since the touch does not fall into the header frame.
David H suggestion was my initial idea as well but I was hoping to find a more elegant solution. Anyway, that's how I ended up implementing this feature.
I kept the code as simple as possible (I'm sure it can be done in a more optimized fashion, works fast enough for my needs) - each image added to a section (no need for overlaying buttons anymore) was also added to a dictionary with section numbers as keys.
When my mask layer view (the transparent one added over my tableview) is being touched I simply check with CGRectContainsPoint if the touch corresponds to any of the views in my dictionary.