n view controllers or n cells - ios

I have a scenario where the user is transformed to a new view controller vc2 when he presses add button.
depending on where he came from, required fields will change. For instance, if he choose to add a task he should enter title, due date and time, but when he choose to add a person he should enter contact info.
Is it better to have two separate view controllers (vc2a,vc2b) or one table view controller vc2 that contains prototype of all cells for the two case, but every time I call cellForRowAtIndexPath, I have to check from where I come.
for me as a developer it is easier to have different view controller in storyboard especially when n>2, but if that can make a difference in performance things will change.
Thanks in advance.

As per my opinion it is better to do this task in a single view controller, provided you are performing similar next action after adding a task of adding a person.
And instead of putting up the checks in cellForRowAtIndexPath because it is called multiple times do place a check in numberOfRowsInSection.
In numberOfRowsInSection do
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
OMGOrderDetailsSectionType sectionType = [[self.tableViewLayoutArray objectAtIndex:section] integerValue];
if (sectionType == 0) {
if(self.isContactsType) {
return 1;
}
}
else if (sectionType == 1) {
if(self.isTaskType) {
return 1;
}
}
return 0;
}
Rest remains same for cellForRow, do configure both type of cells.

Related

Switch calls multiple cases one after another when checking table view tag

I have a collection view with three different cells. Each of the cells contains a table view. So, there are three table views. I've set tags for each of them (from 1 to 3).
Now, on my view controller (I set it as the table view's data source when I dequeue collection view's cells) I call table view's data source method for the number of rows. To distinguish table views I check each one's tag. Here is the code for that:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch tableView.tag {
case 1:
if unitItems1 != nil {
return unitItems1!.count
} else {
return 0
}
case 2:
if unitItems2 != nil {
return unitItems2!.count
} else {
return 4
}
case 3:
if unitItems3 != nil {
return unitItems3!.count
} else {
return 4
}
default:
return 0
}
}
The problem is, when the first cell of the collection view is shown (with the first table view) it works fine. But when I scroll to the second cell, BOTH case 2 and case 3 get executed. After that, the second table view shows data as expected, but when I scroll to the third one, the method doesn't get called.
I can't figure out why two case statements get called one after another, while everything works fine for the first cell. If you have any ideas why this happens (or maybe, you could suggested a better way of checking table view's), I would appreciate your help.
Actually, the solution is quite simple. The reason of the problem was that collectionView's data source method was dequeueing all the cells one after another, even when they weren't on the screen. Consequently, tableView's inside of each cell were getting set, too. So, their data source method was getting called, hence the problem.
UICollectionView has a property called isPrefetchingEnabled. According to the documentation it denotes whether cells and data prefetching is enabled.
The documentation says:
When true, the collection view requests cells in advance of when they will be displayed, spreading the rendering over multiple layout passes. When false, the cells are requested as they are needed for display, often with multiple cells being requested in the same render loop. Setting this property to false also disables data prefetching. The default value of this property is true.
So, to solve the problem, described in the question, I set it to false as soon as my collectionView gets set.

Simultaneously change display parameters on all table view cells

I am trying to implement a table view design where a user can click a button outside of a table view cell and the display mode of all the buttons should change. However this is not the 'selected' mode for a given cell (that will be yet a third state that becomes accessible via switching to this second state). What's the proper way to accomplish this?
I am using dequeueReusableCellWith so I don't want to simply cycle through every cell because some that are out of sight probably shouldn't be modified. I simply want any cell that is visible, or becomes visible, while the table view cell is in this second display mode to follow a second design rather than the first design.
The second design, for now, is being modified via a method I added to a subclass of UITableViewCell like so:
- (void) p_refreshDisplay {
if (self.editing) {
self.buttonToClearWidth.constant = 20;
self.buttonToClearLeadingWidth.constant = 20;
} else {
self.buttonToClearWidth.constant = 0;
self.buttonToClearLeadingWidth.constant = 0;
}
}
However, I'm not sure how to trigger this p_refreshDisplay for every visible (and to become visible) cell. It seems unwise to call this many times and refresh the table view. What would be the proper way to accomplish what I want to do?
You do what should be done for any table view change:
Update your data model or some flag as needed.
Either call reloadData on the table view or call reloadRowsAtIndexPaths:withRowAnimation: passing in indexPathsForVisibleRows as the list of rows to reload.
Implement cellForRowAtIndexPath to provide appropriate cells for the given data/flags.
It sounds like you should have a custom cell class that has one or more properties that can be set on the cell in cellForRowAtIndexPath so the cell can render itself properly based on the specified state.
You can achieve this by doing three things:
Establish some property that indicates the "mode" of the table, either a boolean or perhaps an enum if there are more than three states
Ensure that cellForRowAtIndexPath configures the cell appropriately based on the value of this property. This will ensure that newly displayed cells are configured correctly.
When the "mode" changes you can use the tableview's visibleCells property to update any currently visible cells:
for cell in tableview.visibleCells {
if let myCell = cell as? MyCustomCellClass {
myCell.setButtonStyle()
}
}

Hide a static cell of Tableview in swift

I've an application that works with a static cells table view. In some cases in need to hide a few cells and when needed show them again. How can i do this ?
To do what you wanna do I work with numberOfRowsInSection tableview's method using a bool variabile
if section == 3 {
if !hideTableSection! { return 1 } else { return 2 }
}
Every time I need to hide some cell I change the bool variable then I reload my table.
It can manage only the latest rows of every section but I didn't find nothing better...

Your Second iOS app Tutorial: How Many Sections Do They Want?

In Your Second iOS app, there is a portion that says the following:
After you finish laying out the cells in the table, the detail scene should look similar to this:
However, mine has Section-1, Section-2, Section-3 right above each section. I get the feeling that they want 1 section with three cells.
Can you tell which?
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 3;
}
This should be your code to have 3 rows and only 1 section like that of image
You incremented the number of sections by mistake instead of incrementing the number of rows. Which you should have done.
Edited to add
You get to this by highlighting the Table View Section in the controller scene and editing the number of rows in the right hand panel.
I picture makes this clearer:
Yes, according to the image its 1 section with 3 rows. In numberOfSections method return 1 and in numberOfRowsInSection method return 3.
They are looking for one section with three cells.

Showing/Hiding Rows in Sections of UITableView

I am trying to create a UITableView that is set up so that when I click on a section, it hides the rows from the previous section and shows the rows of the newly selected section. The tableView is set up with data from an array of arrays called menuItems. menuItems contains several other arrays including contactInfoArray, clientInfoArray, jacketArray, and shirtArray. In each of these arrays, the objectAtIndex:0 is the Section Title and effectively acts as the header.
So, for example when the app loads, it should first show all rows of the contactInfoArray, but then show the ObjectAtIndex:0 (the title) for each of the other arrays. When I then tap one of those section titles, for example: "Jacket", I need the table to hide the contactInfoArray objectsAtIndexes:1+, but not object 0, while at the same time (or with an acceptable delay) showing jacketArray objectsAtIndexes:1+.
I have achieved the desired result by calling reload data, but I want animation of the change and reloadData does not allow that. I can't find any tutorials or sample code that does this.
Can anybody help me?
Thanks to my good friend Darren for helping me solve this issue!
- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section{
return (indexPath.section == currentSection) ? [[menuItems objectAtIndex: indexPath.section ] count] : 1;
}
All that I needed to do was set an immediate variable (in my case "currentSection" which is an int) and set its value in the didSelectRowAtIndexPath: method. Then I set up my table so that row 0 of the section acted as the section title.
Doing this made it so that when I clicked on the section header it would "collapse" the open section and "expand" the newly selected section.

Resources