Display show more in uitableview - ios

By default each section should show maximum three cells. If any cell contains more than three cells, it should display 'show more' option.If show more is tapped I want to display the rest of the cells in that particular section. Two days I spent, nothing worked out.Segments at the top of the table. Depend on segment selected, tableview load the cells. This code for each segment each section varies, so the func cellForRowAtIndexPath: becomes big seriously very big. I roughly added code. This code is what i have tried.
if segmentName == .Feature || segmentName == .Services
{
if indexPath.section == 0
{
if boolShowFullFeature[indexPath.section] == false
{
if indexPath.row == showCells
{
return createShowMoreCell(indexPath.section)
}
else
{
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! SearchListViewCell
var firstTitle = "", secondTitle = "", thirdTitle = "", recomendValue = "", starValue = ""
(firstTitle, secondTitle, thirdTitle, recomendValue, starValue) = model.foodValue[indexPath.row]
cell.configureCell(firstTitle, secondTitle: secondTitle, thirdTitle: thirdTitle, recomendValue: recomendValue, starValue: starValue)
return cell

i had actually done this before. here is sample code:
var objects = [["1","2","3"],["q","w","e","r","t","y"],["z","x","c","v","b","n","m"]]
var sec = ["sec a","sec b","sec c"]
var showallSec = 0
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return sec.count
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let items = objects[section].count
if items > 3{
if section == showallSec-1{
return items
}
return 4
}
return items
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
let object = objects[indexPath.section][indexPath.row]
cell.textLabel!.text = object
if(indexPath.section != showallSec-1){
if(indexPath.row == 3){
cell.textLabel!.text = "show more"
}}
return cell
}
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sec[section]
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if(indexPath.row == 3){
showallSec = indexPath.section + 1
tableView.reloadData()
}
}

Related

Index out of range in tableView

I am trying to display 2 different types of data in table view. The videoNews Array only has one element that is to be displayed in indexPath.row == 1 and Suggested News array has many elements that are to be displayed in indexPath.row >= 4. Everything in between are just labels and go as it is. The problem comes when elements from SuggestedNews array are displayed the tableView gives index out of range error even though the array has elements and numberOfRowsInSection also gets the right number of elements.
Code of TableView
var SuggestedNews = [VideoNews]()
var videoNews = [VideoNews]()
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (5 + SuggestedNews.count)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0 {
if let cell = tableView.dequeueReusableCell(withIdentifier: "VideoArticleCell", for: indexPath) as? VideoArticleCell {
let video = self.videoNews[indexPath.row]
cell.updateUI(video: video)
return cell
}
} else if indexPath.row == 1 {
if let cell = tableView.dequeueReusableCell(withIdentifier: "VideoFirstLabelCell") {
return cell
}
} else if indexPath.row == 2 {
if let cell = tableView.dequeueReusableCell(withIdentifier: "VideoSubmissionCell", for: indexPath) as? VideoSubmissionCell {
return cell
}
} else if indexPath.row == 3 {
if let cell = tableView.dequeueReusableCell(withIdentifier: "VideoSecondLabelCell") {
return cell
}
} else if indexPath.row >= 4 {
if let cell = tableView.dequeueReusableCell(withIdentifier: "VideoSuggestionCell", for: indexPath) as? VideoSuggestionCell {
let latest = self.SuggestedNews[indexPath.row] //Index out of range
cell.updateUI(latest: latest)
return cell
}
}
return UITableViewCell()
}
If index.row == 4 your code in this line but you want to show first element of array; therefore, your first array index is equal to 0.
let latest = self.SuggestedNews[indexPath.row - 4]
If you have 4 cell different than SuggestedNews, your return don't be return (5 + SuggestedNews.count)
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (4 + SuggestedNews.count)
}

Xcode - TableView - Multiple sections

I have multiple sections in my TableView and I'm a bit stuck to display there names in the correct section. I'm new to xcode, so this an easy one for most but not for me :s
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 2
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
if section == 0 {
return areas.bars.count
} else {
return areas.clubs.count
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("barsandclubsIdentifier", forIndexPath: indexPath)
if section == 0 { // **This is where I'm stuck I can't put section -> UITableViewCell**
let bars = areas.bars
let bar = bars[indexPath.row]
cell.textLabel?.text = bar.name
return cell
} else {
let clubs = areas.clubs
let club = clubs[indexPath.row]
cell.textLabel?.text = club.name
}
}
Try this may help you :
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("barsandclubsIdentifier", forIndexPath: indexPath)
if indexPath.section == 0 { // **This is where I'm stuck I can't put section -> UITableViewCell**
let bars = areas.bars
let bar = bars[indexPath.row]
cell.textLabel?.text = bar.name
}else {
let clubs = areas.clubs
let club = clubs[indexPath.row]
cell.textLabel?.text = club.name
}
return cell
}

How to change section location of a UITableViewCell on tap

I'm trying to add a UITableViewCell to another UITableView section whenever a button on the cell is tapped. However, I'm quite confused about the process of how to change a cell's section location after it has already been loaded into the table view. Currently I have two sections and am adding 5 custom UITableViewCells into the first section.
Any ideas on how to move the cells to the second section on tap?
Here are cell and section methods in my view controller class:
var tableData = ["One","Two","Three","Four","Five"]
// Content within each cell and reusablity on scroll
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var tableCell : Task = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! Task
tableCell.selectionStyle = .None
tableView.separatorStyle = UITableViewCellSeparatorStyle.None
var titleString = "Section \(indexPath.section) Row \(indexPath.row)"
tableCell.title.text = titleString
println(indexPath.row)
return tableCell
}
// Number of sections in table
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 2
}
// Section titles
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if section == 0 {
return "First Section"
} else {
return "Second Section"
}
}
// Number of rows in each section
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return tableData.count
} else if section == 1 {
return 0
} else {
return 0
}
}
You need to have a separate datasource for first and second sections. When button is tapped, modify datasource and move cell to new section with moveRowAtIndexPath(indexPath: NSIndexPath, toIndexPath newIndexPath: NSIndexPath) UITableView method.
For example:
var firstDataSource = ["One","Two","Three","Four","Five"]
var secondDataSource = [ ]
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return section == 0 ? firstDataSource.count : secondDataSource.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell
cell.textLabel?.text = indexPath.section == 0 ? firstDataSource[indexPath.row] : secondDataSource[indexPath.row]
return cell
}
// For example, changing section of cell when click on it.
// In your case, similar code should be in the button's tap event handler
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
if indexPath.section == 0
{
let data = firstDataSource[indexPath.row]
tableView.beginUpdates()
secondDataSource.append(data)
firstDataSource.removeAtIndex(indexPath.row)
let newIndexPath = NSIndexPath(forRow: find(secondDataSource, data)!, inSection: 1)
tableView.moveRowAtIndexPath(indexPath, toIndexPath: newIndexPath)
tableView.endUpdates()
}
}

How to add an image when a row is selected and then remove it when it is deselected in UITableView in SWIFT

I'm having an issue with making an image appear when a row is selected and then making the image disappear when another row is selected. If I touch a selected row it does not get deselected – this is OK as that is the behaviour that I want. I only want the currently selected row to be deselected when I touch another row.
I am writing in Swift.
I am using Kai Engelhardt's solution to expand the selected row, as answered here.
This UIImage should appear/disappear: cellContent.ringImage.image = UIImage(named: "ring.png")
I'm guessing that my logic is wrong in the selectedCellIndexPath part below.
This is my code:
In my TVC:
class MenuViewController: UIViewController{
var selectedCellIndexPath: NSIndexPath?
let SelectedCellHeight: CGFloat = 222.0
let UnselectedCellHeight: CGFloat = 64.0
let menuItems = [
("1","test 1"),
("2","test 2"),
("3","test 3"),
("4","test 4"),
("5","test 5")]
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView == menuTable {
return menuItems.count
} else {
return 0}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! MenuTableViewCell
if tableView == menuTable {
let (my, section) = menuItems[indexPath.row]
cell.myLabel.text = my
cell.sectionLabel.text = section
cell.selected = true
}
}
func tableView(tableView: UITableView!, heightForRowAtIndexPath indexPath: NSIndexPath!) -> CGFloat {
if let selectedCellIndexPath = selectedCellIndexPath {
if selectedCellIndexPath == indexPath {
return SelectedCellHeight
}
}
return UnselectedCellHeight
}
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
var cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! MenuTableViewCell
var cellContent = tableView.cellForRowAtIndexPath(indexPath) as! MenuTableViewCell
let cellLabel = cellContent.sectionLabel.text
if let selectedCellIndexPath = selectedCellIndexPath {
if selectedCellIndexPath != indexPath {
self.selectedCellIndexPath = indexPath
cellContent.ringImage.image = UIImage(named: "ring.png")
} else {
self.selectedCellIndexPath != indexPath
cellContent.ringImage.hidden = true
tableView.deselectRowAtIndexPath(indexPath, animated: true)
// cellContent.testbutton.removeFromSuperView
}
} else {
selectedCellIndexPath = indexPath
cellContent.ringImage.hidden = true
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
tableView.beginUpdates()
tableView.endUpdates()
}
Your help is greatly appreciated!
Thanks
Mikee
It seems that self.selectedCellIndexPath != indexPath does not do the deselect mark effect you want. You may try to use tableView.indexPathsForSelectedRows() to get the currently selected indexPath, compare it with the indexPath in the argument, and then complete your logic without assigning self.selectedCellIndexPath.
(Edited)
As I find that you also need the varialbe self.selectedCellIndexPath to identify the height, you could try to convert it to a counter variable which counts the selected time of currently selected row. If it is odd, it is selected, while when it's even that you know you would deselect it and reset the counter varialbe to zero.
func tableView(tableView: UITableView!, heightForRowAtIndexPath indexPath: NSIndexPath!) -> CGFloat {
if (indexPath == tableView.indexPathsForSelectedRows()[0] && self.counter % 2 == 1) {
return SelectedCellHeight
}
return UnselectedCellHeight
}

Dynamic UITableView controlled by second UITableView in same ViewController - Swift

This is a followup to a question I asked yesterday, I thought I had a solution based upon the answer received, but I'm having a new difficulty.
I have a single ViewController with two UITableViews (PropertyTypeListand PropertyDetailList)
I essentially want to treat this like a Master Detail View, When a row in PropertyTypeList is selected PropertyDetailList updates to an array based upon that selection. (I need it to be in one ViewController)
The problem was that I couldn't get the row selected from didSelectRowAtIndexPath into cellForRowAtIndexPath where I populate the tables through an If Statement to determine which tableview is in play.
I am now getting the currently selected row through a variable (currentRowInTypeList) and using that value to switch which array is loaded into PropertyDetailList.
Even though currentRowInTypeList is updating with each click the table isn't. What am I missing?
my code follows:
#IBOutlet weak var propertyTypeList: UITableView!
#IBOutlet weak var propertyDetailList: UITableView!
var testarray = ["test1", "test2"]
var testarray2 = ["test3", "test4"]
var currentRowInTypeList: Int = 0
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int
{
if tableView == propertyTypeList {
return projectSources.count;
}
else {
if currentRowInTypeList == 0 {
return testarray.count
} else {
return testarray2.count
}
}
}
func tableView(tableView: UITableView!,
cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!
{
let cell:UITableViewCell = UITableViewCell(style:UITableViewCellStyle.Default, reuseIdentifier:"Cell")
if tableView == propertyTypeList {
cell.textLabel?.text = projectSources[indexPath.row]
return cell
}
else
{
if currentRowInTypeList == 0 {
cell.textLabel?.text = testarray[indexPath.row]
return cell
} else {
cell.textLabel?.text = testarray2[indexPath.row]
return cell
}
}
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
let cell:UITableViewCell = UITableViewCell(style:UITableViewCellStyle.Default, reuseIdentifier:"Cell")
if tableView == propertyTypeList {
currentRowInTypeList = indexPath.row
println(currentRowInTypeList)
} else {
}
}
Just call propertyDetailList.reloadData()
In your code:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
let cell:UITableViewCell = UITableViewCell(style:UITableViewCellStyle.Default, reuseIdentifier:"Cell")
if tableView == propertyTypeList {
currentRowInTypeList = indexPath.row
propertyDetailList.reloadData()
println(currentRowInTypeList)
} else {
}
}

Resources