TableViews inside ScrollView Autolayout - ios

I am trying to create a View that contains many subviews and can contain many tableviews.
Need is to enable scroll of all the subviews.
Actually I created scroll view and put it into superView. Then i put all the views inside that scroll but i have a lot of problems with putting tableviews inside that scroll using AutoLayout. I dont want a scroll inside tableViews, all i need is to enable clicks each tableView i create. I would like to listen to all of your suggestions how can I easily create this View.

A scrollview inside of a scrollview is hard to handle. Maybe it's worth to redesign your data model by combine the contents?
e.g. (assuming that each table contains 2 Labels)
image -> Row cell 0 of type A OR TableHeader
Label -> Row cell 1 of type B
Label -> Row cell 2 of type B
Label -> Row cell 3 of type B
Label -> Row cell 4 of type B
Table 1 Label 1 -> Row cell 5 of type C
Table 1 Label 2 -> Row cell 6 of type C
Label -> Row cell 7 of type B
Table 2 Label 1 -> Row cell 8 of type C
Table 2 Label 2 -> Row cell 9 of type C
Label -> Row cell 10 of type B
Table 3 Label 1 -> Row cell 11 of type C
Table 3 Label 2 -> Row cell 12 of type C
...
Button -> Row cell n of type D OR TableFooter
Now you can fill your table like a normal table without special solution.

Related

Expand and collapse cells in tableview

I have a tableview. Some cells contain images, other text.
I want to be able to collapse and expand the cells. In order to be able to do so I did the following:
I created a variable isExpanded = true
In cellForRowAt I check if the cell contains text and then...
if textIsExpanded {
cell.textLabel?.sizeToFit()
cell.textLabel?.numberOfLines = 0
}
so that the cell can be as tall as the text inside of it.
In the action I toggle textIsExpanded and reload the table:
textIsExpanded.toggle()
table.reloadData()
This procedure perfectly works with tableviews only containing text.
Something that would work was expanding the if statement and in the false branch calling:
cell.textLabel?.invalidateIntrinsicContentSize()
cell.textLabel?.layoutIfNeeded()
BUT this doesn't work when I toggle the variable, this only works on launch.
How can I collapse and expand back the cells in my tableview?
Create your cell with a stack of two views, Upper view and lower View, Add a Bool key to your Model isExpandable that is triggered and changed on didSelect and check on this to hide or show your view, EIther keep the text as text or TextView up to you.

Check which column a UICollectionView Cell is in?

I have a UICollection View and am creating a custom animation when a user taps on a cell.
There are three columns in the collection view. Is there a quick way to figure out, given a index path, the column that was tapped?
If you have a single section, you can just use modulo arithmetic on the item of the index path.
let column = indexPath.item % 3 // gives a value from 0 to 2
Yes. Assuming you setup the columns as sections in the collection view, you should just be able to check the section of the indexpath.
An IndexPath is primarily made of two parts, a row, and a section. If you have 3 sections than indexPath.section == 0 is the first column, indexPath.section == 1 is the second, and indexPath.section == 2 is the third

Swift Dynamically growing a cell depending on the text length

I have a TableViewController which contains 2 sections:
Section 1 - is a cell which is loaded from a xib file. This cell just contains a TextView.
Section 2 - Contains multiple cells populated from an Array.
The section 1 only exists if the master (previous) UITableView cell you select contains a certain piece of data.
All of the above works as expected, below is the parent view. The list of items come from a database, some items have a description, and some do not. For example below this image, you'll see the view is 'Classic Starters' is selected. Then below that, you'll see the view if 'Stir Frys' is selected. Stri Frys contains a description:
Now, what I want is, the description cell which is shows on the Stir Frys page, to automatically grow depending on the length of the text inside it. So if a description is 10 lines long, it will grow to show all 10 lines.
Does this have to be done programmatically, or is their a feature in XCode I'm missing ?
You can use UITableViewAutomaticDimension.
1)
Set properties estimatedRowHeight and rowHeight of your tableview, in viewDidLoad for example. Like this :
self.tableView.estimatedRowHeight = 50
self.tableView.rowHeight = UITableViewAutomaticDimension
2) Return UITableViewAutomaticDimension in your heightForRowAt delegate method :
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
First you need to do is to set estimatedRowSize to a value that best estimates most common size, and rowSize to UITableViewAutomaticDimension:
self.tableView.estimatedRowHeight = 44
self.tableView.rowHeight = UITableViewAutomaticDimension
In your case, since except the first one all the other cells are supposed to be the same, you can use the height of the rest of the cells as the estimatedRowHeight.
You don't have to implement heightForRowAt at all.
The second step you need to do is to setup proper constraints on the cells. That means you have to constrain the contents of the cell to the left, right, top and bottom of the cell, so that when contents grow, the cell will need to grow, too. Common mistake is to forget to constrain bottom, so then the cell does not grow and the contents leak through the bottom of the cell.
Third, since your dynamic cell contains UITextView, you need to make sure that it will grow with its text. That is not automatic. To achieve that, based on this answer, this should suffice (in the cell):
textView.isScrollEnabled = false
If you are using storyboard, just uncheck scroll enabled.

XCTest: Can not get the last collection cell element after swipeLeft()

I have one collection View inside my table view cell. And I want to tap on the last cell after swipe left to see the last collection cell.
For example here are my list collection view cells:
|A B C D| E F
Note: '|' is the bounds of screen and collection cell E, F are not visible yet
let tableCell = app.tables["TableView"].cells.element(boundBy: 1)
// Test to get the label of collection cell inside tableCell
let collectionCell_A = tableCell.staticTexts["A"]
XCTAssert(collectionCell_A.exists) // Okay
// Swipe left to see the collection cell E
tableCell.swipeLeft()
// Test to get collection cell D success
let sevenElevenCell = tableCell.staticTexts["D"]
// But with the collection cell E always failed.
let collectionCell_E = tableCell.staticTexts["E"]
waitUntilElementExists(collectionCell_E) // My helper func to wait element exits for 10 seconds
collectionCell_E.tap() // Failed here
After debugging, I found that list staticTexts didn't update after collection has swiped to left.
I think this guy has the same problem like me. https://forums.developer.apple.com/thread/82366
This issue has been resolved. My co-worker has a great solution to fix it.
let cell = XCUIApplication().cells.containing(NSPredicate(format: "label CONTAINS %#", "E")).element
cell.tap() // Success.
Hope this will help someone else.

Section within a section for UITableView

I have to create a UITableView that has sections within sections however I have never done this before and am not even sure if this is possible.
This is what it needs to look like
Header 1
Sub Header 1
cell 1
cell 2
cell 3
Sub Header 2
cell 1
cell 2
Header 2
Sub Header 1
cell 1
Sub Header 2
cell 1
cell 2
All fields are dynamic, so there could be 0 or more Header sections; would a UITableView be the best way to go about this? if so how would I approach this?
There is no easy way to do it, you have to plan cleverly.
From numberOfSectionsInTableView return the number of "Header".
For each section in numberOfRowsInSection return Sub Header + Cell in each sub header.
From cellForRowAtIndexPath just chek if it is a sub header or a cell. If its is a sub header the return a cell which has a Label near to left side, if it is a cell then return a cell that has the label in more far away from left border.
You can use same cell just changing the frame of the cell's label.

Resources