Multiple cell prototypes in Dynamic TableView - ios

I want to create a table like this in which on there will be two cells in one section. In first cell the profile image comes and description in the second cell. what I have tried so far is I have set Prototypes to 2 and give each prototype a unique identifier and also created two classes for two prototypes. But The problem is it is showing two rows but both rows have same data.
var profileImage = ["angelina","kevin"]
var userName = ["Angelina Jolie","Vasiliy Pupkin"]
var requestTitle = ["I have a Wordpress website and I am looking for someone to create a landing page with links and a cart to link up.","second description"]
var date = ["Feb 03, 16","Feb 03, 16"]
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return profileImage.count
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return profileImage.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if(indexPath.row==0){
let cell = tableView.dequeueReusableCellWithIdentifier("firstCustomCell", forIndexPath: indexPath) as! FirstProductRequestTableViewCell
cell.userNameLabel.text = userName[indexPath.row]
cell.profileImage.image = UIImage(named: profileImage[indexPath.row])
return cell
}else{
let cell = tableView.dequeueReusableCellWithIdentifier("secondCustomCell", forIndexPath: indexPath) as! SecondProductRequestTableViewCell
cell.requestTitleTxtView.text = requestTitle[indexPath.row]
return cell
}
}

Here is solution for your question.
You need to use UITableViewSecionHeaderView in this case because i think in your scenario you have multiple descriptions against a profile so put the SecionHeader which contain the information of profile and cells contain the description.
But if you want to Repeat the whole cell then you only need to make a CustomCell which contain profile information and description with a line separator. You can make a line separator with an Image or using UIView of height 1.0 and colour lightgray.

Based on your description, the number of sections returned is correct, but you should return 2 for the number of rows in each section and when configuring the cells you should be using indexPath.section where you're currently using the row to choose the data to add to the cell (but keep using the row to choose which type of cell to return).
So, the section is used to choose which person you're showing details about and the row is used to choose which piece of information to show:
var profileImage = ["angelina","kevin"]
var userName = ["Angelina Jolie","Vasiliy Pupkin"]
var requestTitle = ["I have a Wordpress website and I am looking for someone to create a landing page with links and a cart to link up.","second description"]
var date = ["Feb 03, 16","Feb 03, 16"]
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return profileImage.count
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if(indexPath.row == 0) {
let cell = tableView.dequeueReusableCellWithIdentifier("firstCustomCell", forIndexPath: indexPath) as! FirstProductRequestTableViewCell
cell.userNameLabel.text = userName[indexPath.row]
cell.profileImage.image = UIImage(named: profileImage[indexPath.section])
return cell
} else {
let cell = tableView.dequeueReusableCellWithIdentifier("secondCustomCell", forIndexPath: indexPath) as! SecondProductRequestTableViewCell
cell.requestTitleTxtView.text = requestTitle[indexPath.section]
return cell
}
}

Related

How to get total in footer cell of cells in sections?

Currently Im able to get cells to add up their total in the sections Footer Cell. But it calculates the total for every cell no matter what section its in, inside the all the sections footer.
I still can't get it to add up the different prices(Price1 - 3) for the cells that have a different prices selected passed into it the Section
code im using to add up total in the CartFooter for the Cells in the sections cartFooter.cartTotal.text = "\(String(cart.map{$0.cartItems.price1}.reduce(0.0, +)))"
PREVIOUSLY:
im trying to get the Cells in each section to add up their total in footer cell for each section that they're in.
The data in the CartVC is populated from another a VC(HomeVC). Which is why there is 3 different price options in the CartCell for when the data populates the cells.
Just kind of stuck on how I would be able to get the total in the footer for the cells in the section
Adding specific data for each section in UITableView - Swift
Thanks in advance, Your help is much appreciated
extension CartViewController: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return brands
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let brand = brands[section]
return groupedCartItems[brand]!.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cartCell = tableView.dequeueReusableCell(withIdentifier: "CartCell") as! CartCell
let brand = brands[indexPath.section]
let cartItemsToDisplay = groupedCartItems[brand]![indexPath.row]
cartCell.configure(withCartItems: cartItemsToDisplay.cartItems)
return cartCell
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let cartHeader = tableView.dequeueReusableCell(withIdentifier: "CartHeader") as! CartHeader
let headerTitle = brands[section]
cartHeader.brandName.text = "Brand: \(headerTitle)"
return cartHeader
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let cartFooter = tableView.dequeueReusableCell(withIdentifier: "FooterCell") as! FooterCell
let sectionTotal = cart[section].getSectionTotal()
let calculate = String(cart.map{$0.cartItems.price1}.reduce(0.0, +))
cartFooter.cartTotal.text = "$\(calculate)"
return cartFooter
}
}
Update: these are the results that I am getting using this in the CartFooter
let calculate = String(cart.map{$0.cart.price1}.reduce(0.0, +))
cartFooter.cartTotal.text = "$\(calculate)"
which calculates the overall total (OT) for all the sections and places the OT in all all Footer Cells(as seen below ▼) when im trying to get the total for each section in their footers (as seen in image above ▲ on the right side)
Update2:
this what ive added in my cellForRowAt to get the totals to add up in the section footer. it adds up the data for the cells but it doesn't give an accurate total in the footer
var totalSum: Float = 0
for eachProduct in cartItems{
productPricesArray.append(eachProduct.cartItem.price1)
productPricesArray.append(eachProduct.cartItem.price2)
productPricesArray.append(eachProduct.cartItem.price3)
totalSum = productPricesArray.reduce(0, +)
cartFooter.cartTotal.text = String(totalSum)
}
There's a lot of code, and I'm not too sure where your coding error lies. With that said:
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let cartFooter = tableView.dequeueReusableCell(withIdentifier: "FooterCell") as! FooterCell
let sectionTotal = cart[section].getSectionTotal()
let calculate = String(cart.map{$0.cart.price1}.reduce(0.0, +))
cartFooter.cartTotal.text = "$\(calculate)"
return cartFooter
}
Your code seems to say let sectionTotal = cart[section].getSectionTotal() is the total you are looking for (i.e. the total within a section), while you are displaying the OT in a section, by summing up String(cart.map{$0.cart.price1}.reduce(0.0, +)).
In other words, if cartFooter is the container that will display the total within a section, one should read cartFooter.cartTotal.text = "$\(sectionTotal)" instead, no?
If that's not the answer, I suggest that you set a breakpoint each time the footerView is instantiated, and figure out why it output what it outputs (i.e. the OT, instead of the section total).
#Evelyn Try calculation directly in footer. Try below code.
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let cartFooter = tableView.dequeueReusableCell(withIdentifier: "FooterCell") as! FooterCell
let brand = brands[indexPath.section]
let arrAllItems = groupedCartItems[brand]!
var total: Float = 0
for item in arrAllItems {
if item.selectedOption == 1 {
total = total + Float(item.price1)
} else item cartItems.selectedOption == 2 {
total = total + Float(item.price2)
} else if item.selectedOption == 3 {
total = total + Float(item.price3)
}
}
cartFooter.cartTotal.text = "$\(total)"
return cartFooter
}
If you want to correct calculate total price in each section you need filter items for every section. now i think you sum all of your section.
For correct section you need yous snipper from your cellForRow method:
let brand = brands[indexPath.section]
let cartItemsToDisplay = groupedCartItems[brand]![indexPath.row]
cartCell.configure(withCartItems: cartItemsToDisplay.cart)
inside this:
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let cartFooter = tableView.dequeueReusableCell(withIdentifier: "FooterCell") as! FooterCell
let sectionTotal = cart[section].getSectionTotal()
let brand = brands[section]
let catrItemsToDisplay = // now you need to get associated items with this brand (cart)
// I think it is can looks like this = cartItemsToDisplay[brand]
let calculate = String(cartItemsToDisplay.cart.reduce(0.0, +))
cartFooter.cartTotal.text = "$\(calculate)"
return cartFooter
}
Modify your Model structure and the way values set to through TableViewDelegate. Giving a short hint. Please see if it helps:
class Cart {
var brandWiseProducts: [BrandWiseProductDetails]!
init() {
brandWiseProducts = [BrandWiseProductDetails]()
}
initWIthProducts(productList : [BrandWiseProductDetails]) {
self.brandWiseProducts = productList
}
}
class BrandWiseProductDetails {
var brandName: String!
var selectedItems: [Items]
var totalAmount: Double or anything
}
class SelectedItem {
var image
var name
var price
}
Sections:
Cart.brandWiseProducts.count
SectionTitle:
Cart.brandWiseProducts[indexPath.section].brandName
Rows in section
Cart.brandWiseProduct[indexPath.section].selectedItem[IndexPath.row]
Footer:
Cart.brandWiseProduct.totalAmount

How to set enabled checkimage in tableview based on the selected cells

I am fetching previously selected categorylist from the server. say for an example.cateogrylist i fetched from the server was in following formate
categoryid : 2,6,12,17
now what i need to do is want to enable checkmark in my tableview based on this categorylist,for that purpose i converted this list into an [Int] array like this :
func get_numbers(stringtext:String) -> [Int] {
let StringRecordedArr = stringtext.components(separatedBy: ",")
return StringRecordedArr.map { Int($0)!}
}
in viewDidLoad() :
selectedCells = self.get_numbers(stringtext: UpdateMedicalReportDetailsViewController.catId)
print(myselection)
while printing it's giving me results like this : [12,17,6,8,10]
i want to enable checkimage based on this array.I tried some code while printing its giving me the right result like whatever the categories i selected at the time of posting ,i am able to fetch it but failed to place back this selection in tableview.Requirement : while i open this page it should show me the selection based on the categorylist i fetched from the server.
var selectedCells : [Int] = []
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell1 = table.dequeueReusableCell(withIdentifier: "mycell") as! catcell
cell1.mytext.text = categoriesName[indexPath.row]
if UpdateMedicalReportDetailsViewController.flag == 1
{
selectedCells = self.get_numbers(stringtext: UpdateMedicalReportDetailsViewController.catId)
cell1.checkimage.image = another
print(selectedCells)
}
else
{
selectedCells = []
cell1.checkimage.image = myimage
}
return cell1
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = table.cellForRow(at: indexPath) as! catcell
cell.checkimage.image = myimage
if cell.isSelected == true
{
self.selectedCells.append(indexPath.row)
cell.checkimage.image = another
}
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let cell = table.cellForRow(at: indexPath) as! catcell
if cell.isSelected == false
{
self.selectedCells.remove(at: self.selectedCells.index(of: indexPath.row)!)
cell.checkimage.image = myimage
}
}
output :
This is a very common use case in most apps. I'm assuming you have an array of all categories, and then an array of selected categories. What you need to do is in cellForRowAtIndexPath, check to see if the current index path row's corresponding category in the "all categories" array is also present in the "selected categories" array. You can do this by comparing id's etc.
If you have a match, then you know that the cell needs to be selected/checked. A clean way to do this is give your cell subclass a custom load method and you can pass a flag for selected/checked.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = table.dequeueReusableCell(withIdentifier: "mycell") as! catcell
let category = self.categories[indexPath.row] // Let's say category is a string "hello"
Bool selected = self.selectedCategories.contains(category)
cell.load(category, selected)
return cell
}
So with the code above, let's say that categories is just an array of category strings like hello, world, and stackoverflow. We check to see if the selectedCategories array contains the current cell/row's category word.
Let's say that the cell we're setting up has a category of hello, and selectedCategories does contain it. That means the selected bool gets set to true.
We then pass the category and selected values into the cell subclass' load method, and inside that load method you can set the cell's title text to the category and you can check if selected is true or false and if it's true you can display the checked box UI.

Two custom tableViewCells in UITableView

I am trying to create a contacts page where you can see all your contacts with a friend request cell showing up when you receive a friend request, but not there when you do not have any. At the moment, both custom cells work fine. The issue I have is that the contactRequestTableViewCell overlaps the first cell of the contactListTableViewCell.
I have researched other questions about two custom tableviewcells and none are quite having the same issues that I am facing.
Here is my executing code at the moment, I am returning 2 sections in the table view.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! ContactListTableViewCell
let requestCell = tableView.dequeueReusableCellWithIdentifier("requestCell", forIndexPath: indexPath) as! ContactRequestsTableViewCell
let user = OneRoster.userFromRosterAtIndexPath(indexPath: indexPath)
if (amountOfBuddyRequests > 0) {
if (indexPath.section == 0) {
requestCell.hidden = false
cell.hidden = false
requestCell.friendRequestLabel.text = "test"
} else if (indexPath.section >= 1) {
cell.contactNameLabel!.text = user.displayName;
cell.contactHandleLabel!.text = "# " + beautifyJID(user.jidStr)
cell.contactHandleLabel!.textColor = UIColor.grayColor()
OneChat.sharedInstance.configurePhotoForImageView(cell.imageView!, user: user)
}
return cell;
}
else { // if buddy requests == 0
requestCell.hidden = true
cell.contactNameLabel!.text = user.displayName;
cell.contactHandleLabel!.text = "# " + beautifyJID(user.jidStr)
cell.contactHandleLabel!.textColor = UIColor.grayColor()
print ("This is how many unreadMessages it has \(user.unreadMessages)")
// If there is unread messages for a person highlight it blue
// However this feature isn't working right now due to unreadMessages bug
if user.unreadMessages.intValue > 0 {
cell.backgroundColor = .blueColor()
} else {
cell.backgroundColor = .whiteColor()
}
OneChat.sharedInstance.configurePhotoForCell(cell, user: user)
return cell;
}
}
This is the current output that I have right now, my cells that have "test" are covering up other contactListTableViewCells.
The function tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell should always return one and the only one TableViewCell you want at indexPath, so you don't want to always return cell of type ContactListTableViewCell.
According to documentation, the cellForRowAtIndexPath tableView method asks for the cell at the indexPath, which means literally there can only be one cell at certain row of a certain section, so returning two cells is not an option.
I suggest you use two arrays to store the requests and contacts information. For example, you have arrays requests and contacts. Then you can tell the tableView how many rows you want:
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of rows in the section.
return requests.count + contacts.count
}
and then in cellForRowAtIndexpath you do something like:
override func tableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath.row < requests.count {
// return a request cell
}
else {
// return a contact cell
}
}
I'm only using one tableView section here. If you still want two sections you can simply return 2 in numberOfSections function and add if statements in cellForRowAtIndexPath for indexPath.section.
Hope this helps.
It turns out that the issue was dealing with the data sources. My data sources were not pointing to the correct tableviewcell. This resulted in them pointing to an incorrect cell. This issue was fixed by remaking the data sources system that was in place. This issue will not affect most as the data sources will point to the correct tableviewcell by default.
Contrary to what another poster said, you can in fact display two or more custom cells in a single table. This is how I fixed the tableView display issues:
var friendRequests = ["FriendRequest1", "FriendRequest2"]
var contacts = ["User1","User2","User3","User4"]
var amountOfBuddyRequests = 1
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
if (amountOfBuddyRequests > 0) {
return 2
}
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if (amountOfBuddyRequests > 0) {
if (section == 0) {
return friendRequests.count
}
}
return contacts.count
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if (amountOfBuddyRequests > 0) {
if (indexPath.section == 0) {
let requestCell = tableView.dequeueReusableCellWithIdentifier("requestCell") as! ContactRequestsTableViewCell
requestCell.friendRequestLabel.text = friendRequests[indexPath.row]
requestCell.onButtonTapped = {
self.friendRequests.removeAtIndex(indexPath.row)
self.tableView.reloadData()
}
requestCell.addButtonTapped = {
self.addUser(self.friendRequests[indexPath.row])
self.friendRequests.removeAtIndex(indexPath.row)
self.tableView.reloadData()
}
return requestCell
}
}
let friendCell = tableView.dequeueReusableCellWithIdentifier("FriendCell") as! ContactListTableViewCell
friendCell.contactNameLabel.text = contacts[indexPath.row]
return friendCell
}

How to use multiple custom cells (>1) in UITableView

I've searched for an answer to this question all over Stack Overflow and have found some useful answers but my situation is different as the number of rows in the section are to be determined from the number of items listed in an array. I'm trying to create a table that uses two custom cells. The first cell displays profile information while the second displays the news feed.
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myProfileDM.profileArray.count
//return myProfileFeedDM.profileFeedArray.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) ->
UITableViewCell {
if indexPath.row == 0 {
let cell = tableView.dequeueReusableCellWithIdentifier("bio", forIndexPath:indexPath) as! ProfileTableViewCell
cell.followerNumber!.text = myProfileDM.profileArray[indexPath.row].followerNumberInterface
cell.followers!.text = myProfileDM.profileArray[indexPath.row].followersInterface
cell.following!.text = myProfileDM.profileArray[indexPath.row].followingInterface
cell.followingNumber!.text = myProfileDM.profileArray[indexPath.row].followingNumberInterface
return cell
}
else{
let cell = tableView.dequeueReusableCellWithIdentifier("feed", forIndexPath:indexPath) as! FeedTableViewCell
//let cell: FeedTableViewCell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "feed")
cell.profileFeedLabel!.text = myProfileFeedDM.profileFeedArray[indexPath.row].profileFeed
cell.profileDateLabel!.text = myProfileFeedDM.profileFeedArray[indexPath.row].profileDate
return cell
}
}
}
when I run the program, the first cell (with identifier-bio) is the only one that loads/shows up.
I suppose the number of rows in the section is wrong. From your variable names I suspect it should be
myProfileFeedDM.profileFeedArray.count + 1
Note that in the feed array you would have to use indexPath.row - 1 to get to the right index of your array because the first row is for the profile.
I don't see any reason from the code why it doesn't work.
Try to debug cellForRowAtIndexPath method to see what is the value of the indexPath on each call
(or just put println ("IndexPath: \(indexPath)") to your cellForIndexPath method)
PS: But as long as you need your profile cell only once - I would suggest to move ProfileCell into table's or Section's header
it would be a bit more logical I think.

Swift - How to use dequeueReusableCellWithIdentifier with two cell types? (identifiers)

I am trying to build a table view for events, like so:
I have two cell prototypes:
An event cell with identifier "event"
A separator cell with identifier "seperator"
Also, I have this class to represent a date:
class Event{
var name:String = ""
var date:NSDate? = nil
}
And this is the table controller:
class EventsController: UITableViewController {
//...
var eventsToday = [Event]()
var eventsTomorrow = [Event]()
var eventsNextWeek = [Event]()
override func viewDidLoad() {
super.viewDidLoad()
//...
self.fetchEvents()//Fetch events from server and put each event in the right property (today, tomorrow, next week)
//...
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let event = tableView.dequeueReusableCellWithIdentifier("event", forIndexPath: indexPath) as EventTableViewCell
let seperator = tableView.dequeueReusableCellWithIdentifier("seperator", forIndexPath: indexPath) as SeperatorTableViewCell
//...
return cell
}
}
I have all the information I need at hand, but I can't figure out the right way to put it all together. The mechanics behind the dequeue func are unclear to me regrading multiple cell types.
I know the question's scope might seem a little too broad, but some lines of code to point out the right direction will be much appreciated. Also I think it will benefit a lot of users since I didn't found any Swift examples of this.
Thanks in advance!
The basic approach is that you must implement numberOfRowsInSection and cellForRowAtIndexPath (and if your table has multiple sections, numberOfSectionsInTableView, too). But each call to the cellForRowAtIndexPath will create only one cell, so you have to do this programmatically, looking at the indexPath to determine what type of cell it is. For example, to implement it like you suggested, it might look like:
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return eventsToday.count + eventsTomorrow.count + eventsNextWeek.count + 3 // sum of the three array counts, plus 3 (one for each header)
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var index = indexPath.row
// see if we're the "today" header
if index == 0 {
let separator = tableView.dequeueReusableCellWithIdentifier("separator", forIndexPath: indexPath) as SeparatorTableViewCell
// configure "today" header cell
return separator
}
// if not, adjust index and now see if we're one of the `eventsToday` items
index--
if index < eventsToday.count {
let eventCell = tableView.dequeueReusableCellWithIdentifier("event", forIndexPath: indexPath) as EventTableViewCell
let event = eventsToday[index]
// configure "today" `eventCell` cell using `event`
return eventCell
}
// if not, adjust index and see if we're the "tomorrow" header
index -= eventsToday.count
if index == 0 {
let separator = tableView.dequeueReusableCellWithIdentifier("separator", forIndexPath: indexPath) as SeparatorTableViewCell
// configure "tomorrow" header cell
return separator
}
// if not, adjust index and now see if we're one of the `eventsTomorrow` items
index--
if index < eventsTomorrow.count {
let eventCell = tableView.dequeueReusableCellWithIdentifier("event", forIndexPath: indexPath) as EventTableViewCell
let event = eventsTomorrow[index]
// configure "tomorrow" `eventCell` cell using `event`
return eventCell
}
// if not, adjust index and see if we're the "next week" header
index -= eventsTomorrow.count
if index == 0 {
let separator = tableView.dequeueReusableCellWithIdentifier("separator", forIndexPath: indexPath) as SeparatorTableViewCell
// configure "next week" header cell
return separator
}
// if not, adjust index and now see if we're one of the `eventsToday` items
index--
assert (index < eventsNextWeek.count, "Whoops; something wrong; `indexPath.row` is too large")
let eventCell = tableView.dequeueReusableCellWithIdentifier("event", forIndexPath: indexPath) as EventTableViewCell
let event = eventsNextWeek[index]
// configure "next week" `eventCell` cell using `event`
return eventCell
}
Having said that, I really don't like that logic. I'd rather represent the "today", "tomorrow" and "next week" separator cells as headers, and use the section logic that table views have.
For example, rather than representing your table as a single table with 8 rows in it, you could implement that as a table with three sections, with 2, 1, and 2 items in each, respectively. That would look like:
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 3
}
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
switch section {
case 0:
return "Today"
case 1:
return "Tomorrow"
case 2:
return "Next week"
default:
return nil
}
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch section {
case 0:
return eventsToday.count
case 1:
return eventsTomorrow.count
case 2:
return eventsNextWeek.count
default:
return 0
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let eventCell = tableView.dequeueReusableCellWithIdentifier("event", forIndexPath: indexPath) as EventTableViewCell
var event: Event!
switch indexPath.section {
case 0:
event = eventsToday[indexPath.row]
case 1:
event = eventsTomorrow[indexPath.row]
case 2:
event = eventsNextWeek[indexPath.row]
default:
event = nil
}
// populate eventCell on the basis of `event` here
return eventCell
}
The multiple section approach maps more logically from the table view to your underlying model, so I'd to adopt that pattern, but you have both approaches and you can decide.

Resources