I have a tableView (not static cells) with two sections
A bar section and a club section( and each has several cells). I want that every cell from the same section goes to the same viewcontroller.
I can only acces the first one, never the last one. Even de cells from the second section go to the first viewcontroller.
Can someone see my mistake?
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("mainIdentifier", forIndexPath: indexPath)
if indexPath.section == 0 {
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
return cell
}
}
the segue:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "barsandclubsIdentifier"{
let selectedIndex = self.tableView.indexPathForSelectedRow!
let selectedBar = self.areas.bars[selectedIndex.row]
let detailBarsAndClubsViewController = segue.destinationViewController as! DetailBarOrClubViewController
detailBarsAndClubsViewController.bars = selectedBar
}
else {
let selectedIndex = self.tableView.indexPathForSelectedRow!
let selectedClub = self.areas.clubs[selectedIndex.row]
let detailBarsAndClubsTwoViewController = segue.destinationViewController as! DetailBarOrClubTwoViewController
detailBarsAndClubsTwoViewController.clubs = selectedClub
}
Each prototype cell can only segue to a single viewController. If you have 2 different destination viewControllers, you need 2 prototype cells: 1 for bars and 1 for clubs. Give them each a unique identifier such as "barCell" and "clubCell".
Then in cellForRowAtIndexPath, dequeue the proper cell:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellID = ["barCell", "clubCell"][indexPath.section]
let cell = tableView.dequeueReusableCellWithIdentifier(cellID, forIndexPath: indexPath)
Then you can wire each prototype cell to go to the appropriate viewController. Give each of these two segues a unique identifier such as "barSegue" and "clubSegue" and then you can use those in prepareForSegue to configure the destination viewController.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "barSegue"{
let selectedIndex = self.tableView.indexPathForSelectedRow!
let selectedBar = self.areas.bars[selectedIndex.row]
let detailBarViewController = segue.destinationViewController as! DetailBarViewController
detailBarsViewController.bars = selectedBar
}
else if segue.identifier = "clubSegue" {
let selectedIndex = self.tableView.indexPathForSelectedRow!
let selectedClub = self.areas.clubs[selectedIndex.row]
let detailClubViewController = segue.destinationViewController as! DetailClubViewController
detailClubsViewController.clubs = selectedClub
}
}
Related
I have embed a UISwitch on a UITableView cell.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
if self.users.count > 0 {
let eachPost = self.users[indexPath.row]
let postDate = (eachPost.date as? String) ?? ""
let postTitle = (eachPost.title as? String) ?? ""
cell.detailTextLabel?.text = postDate
cell.textLabel?.text = postTitle
}
if cell.accessoryView == nil{
let switchView : UISwitch = UISwitch(frame: .zero)
switchView.setOn(false, animated: true)
cell.accessoryView = switchView
}
return cell
}
My table has 30 rows. When I select a switch on the visible cells and then scroll down, on the cells from the bottom of the list the switch is selected by default. What can I do to have correct selections for my list?
My solution without creating a custom class:
class MyTableViewController: UITableViewController {
var users: [[String: Any]] = [[String: Any]]()
// This array is used for storring the state for switch from each cell. Otherwise when the cell is reused the state is displayed incorrectly
var switchArray = [Bool]()
override func viewDidLoad() {
super.viewDidLoad()
self.users = result
for _ in 0 ..< self.users.count {
self.switchArray.append(false)
}
self.tableView?.reloadData()
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let eachPost = self.users[indexPath.row]
let postTitle = (eachPost.title as? String) ?? ""
cell.textLabel?.text = postTitle
let switchView : UISwitch = UISwitch(frame: .zero)
switchView.isOn = self.switchArray[indexPath.row]
cell.accessoryView = switchView
return cell}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
self.switchArray[indexPath.row] = true
let switchView : UISwitch = (tableView.cellForRow(at: indexPath)?.accessoryView) as! UISwitch;
switchView.isOn = true
}
override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
self.switchArray[indexPath.row] = false
let switchView : UISwitch = (tableView.cellForRow(at: indexPath)?.accessoryView) as! UISwitch;
switchView.isOn = false
}
Note: Multiple selection has to be enabled
I'm using two table view in one view controller to populate my different data. All the other delegates methods are working fine but didselect method is not performing an action neither its printing any value in console. I hae checked through story board also all the things looks fine and i have set its delegate and datasources methods also but still it isn't working. Searched a lot from net but still unsuccessful in it. My code is this,
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.isNavigationBarHidden = true
self.searchBar.delegate = self
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(LoginViewController.dismissKeyboard))
view.addGestureRecognizer(tap)
dishDetailTableView.delegate = self
dishDetailTableView.dataSource = self
self.addOnTableView.allowsMultipleSelection = true
addOnTableView.delegate = self
addOnTableView.dataSource = self
dishDetailTableView.reloadData()
sectionArray = [String(MenuService.instance.subCategoryModelInstance[0].sub_categoryName)]
print(sectionArray)
cancelBtn.cornerButton()
cancelBtn.layer.borderColor = #colorLiteral(red: 1, green: 0, blue: 0.03742904276, alpha: 1)
cancelBtn.layer.borderWidth = 1.5
nextBtn.layer.borderColor = #colorLiteral(red: 0.09759091236, green: 0.5779017098, blue: 1, alpha: 1)
nextBtn.layer.borderWidth = 1.5
nextBtn.cornerButton()
menuTypeLbl.layer.cornerRadius = 5
addOnView.borderView(view: addOnView)
addOnView.isHidden = true
shadowView.isHidden = true
}
extension DishDetailViewController : UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
var count:Int?
if tableView == dishDetailTableView {
count = MenuService.instance.subCategoryItemModelInstance.count
}
if (tableView == addOnTableView) {
count = AddOnService.instance.AddOnModelInstance.count
}
return count!
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
var cell:UITableViewCell?
if tableView == dishDetailTableView{
let cell = tableView.dequeueReusableCell(withIdentifier: "menuCell", for: indexPath) as! MenuDetailTableViewCell
cell.titleLbl?.text = MenuService.instance.subCategoryItemModelInstance[indexPath.row].itemName
cell.descriptionLbl?.text = MenuService.instance.subCategoryItemModelInstance[indexPath.row].itemdescription
cell.priceLbl?.text = MenuService.instance.subCategoryItemModelInstance[indexPath.row].itemprice
cell.backgroundColor = UIColor.clear
cell.delegate = self
cell.selectionStyle = .none
return cell
}
if tableView == addOnTableView{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! AddOnTableViewCell
cell.addOnLbl.text = AddOnService.instance.AddOnModelInstance[indexPath.row].itemName
print(cell.addOnLbl?.text! as Any)
return cell
}
return cell!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if tableView == dishDetailTableView{
print("Hi")
dishDetailTableView.reloadData()
}
if tableView == addOnTableView {
print("Hello")
addOnTableView.reloadData()
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
var count : Int?
if tableView == dishDetailTableView{
count = 120
}
if tableView == addOnTableView{
count = 60
}
return CGFloat(count!)
}
}
How can i perform any action on cell?
well i create tableview and inside of it tableview cell with xib file
now i want create tableview inside xib file , the main problem is that u can't create cell inside of it to define the identifier for this cell
i keep get this error
'unable to dequeue a cell with identifier AutoCompleteRowIdentifier -
must register a nib or a class for the identifier or connect a
prototype cell in a storyboard'
this is my code
import UIKit
class TableViewCell2: UITableViewCell, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {
#IBOutlet weak var textField: UITextField!
#IBOutlet weak var autocompleteTableView: UITableView!
var pastUrls = ["Men", "Women", "Cats", "Dogs", "Children"]
var autocompleteUrls = [String]()
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
{
autocompleteTableView.hidden = false
let substring = (textField.text! as NSString).stringByReplacingCharactersInRange(range, withString: string)
searchAutocompleteEntriesWithSubstring(substring)
return true // not sure about this - could be false
}
func searchAutocompleteEntriesWithSubstring(substring: String)
{
autocompleteUrls.removeAll(keepCapacity: false)
for curString in pastUrls
{
var myString:NSString! = curString as NSString
var substringRange :NSRange! = myString.rangeOfString(substring)
if (substringRange.location == 0)
{
autocompleteUrls.append(curString)
}
}
autocompleteTableView.reloadData()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return autocompleteUrls.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let autoCompleteRowIdentifier = "AutoCompleteRowIdentifier"
let cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier(autoCompleteRowIdentifier, forIndexPath: indexPath) as UITableViewCell
let index = indexPath.row as Int
cell.textLabel!.text = autocompleteUrls[index]
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let selectedCell : UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
textField.text = selectedCell.textLabel!.text
}
override func awakeFromNib() {
super.awakeFromNib()
textField.delegate = self
autocompleteTableView.delegate = self
autocompleteTableView.dataSource = self
autocompleteTableView.scrollEnabled = true
autocompleteTableView.hidden = true
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}}
as you know you can't define identifier inside xib file
thanks
You need to register a cell with autocompleteTableView before you can dequeue it. Modify your code like this:
override func awakeFromNib() {
super.awakeFromNib()
textField.delegate = self
autocompleteTableView.delegate = self
autocompleteTableView.dataSource = self
autocompleteTableView.scrollEnabled = true
autocompleteTableView.hidden = true
// Register cell
autocompleteTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "AutoCompleteRowIdentifier")
}
I have an issue when I'm trying to pass the information from the database from Parse to my TableViewController. I think that is the way I'm calling to the name and password.
When I push the View Users button the app crash.
I put my git if you need more information. https://github.com/emmanuelcu/ParseProject.git
class TableViewController: UITableViewController{
var dataParse:NSMutableArray = NSMutableArray()
var count:Int = 0
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
//PFQuery
let query = PFQuery(className: "LoginCredentials")
query.findObjectsInBackgroundWithBlock {
(objects: [PFObject]? , error: NSError?) -> Void in
if(error == nil){
print("The current number of users is \(objects!.count)")
self.count = objects!.count
self.tableView.reloadData()
} else {
print("Error")
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
//return self.dataParse.count
return self.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "CellData"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! TableViewCell
// Configure the cell...
cell.password.text = dataParse[indexPath.row]["name"] as? String
cell.name.text = dataParse[indexPath.row]["user"] as? String
print("Error")
return cell
}
When you run your query you never assign your objects to your data source, only the number of objects that you receive. Also you're force unwrapping that count without checking if objects has a count, which is possible even without an error.
It works like this dataParse array is empty you should populate it, or should disable view users button when it is empty etc.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "CellData"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! TableViewCell
// Configure the cell...
if dataParse.count > indexPath.row {
cell.password.text = dataParse[indexPath.row]["name"] as? String
cell.name.text = dataParse[indexPath.row]["user"] as? String
}
print("Error")
return cell
}
I have followed a tutorial of Vea software (https://www.veasoftware.com/tutorials/2015/6/27/uisearchcontroller-in-swift-xcode-7-ios-9-tutorial) to create a table view with search bar on xcode 7, ios 9. Now I need to select multiple rows from the table view by adding a checkmark on each row when selected, the problem is that when I use the search bar the checkmarks don't match the rows anymore..
Here's my code:
class SportSearchTableViewController: UITableViewController, UISearchResultsUpdating {
let appleProducts = ["Mac","iPhone","Apple Watch","iPad"]
var filteredAppleProducts = [String]()
var resultSearchController = UISearchController()
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath,animated: true)
let selectedRow = tableView.cellForRowAtIndexPath(indexPath)!
if selectedRow.accessoryType == UITableViewCellAccessoryType.None {
selectedRow.accessoryType = UITableViewCellAccessoryType.Checkmark
selectedRow.tintColor = UIColor.blueColor()
} else {
selectedRow.accessoryType = UITableViewCellAccessoryType.None
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.resultSearchController = UISearchController(searchResultsController: nil)
self.resultSearchController.searchResultsUpdater = self
self.resultSearchController.dimsBackgroundDuringPresentation = false
self.resultSearchController.searchBar.sizeToFit()
self.tableView.tableHeaderView = self.resultSearchController.searchBar
self.tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if (self.resultSearchController.active)
{
return self.filteredAppleProducts.count
}
else
{
return self.appleProducts.count
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell?
if (self.resultSearchController.active)
{
cell!.textLabel?.text = self.filteredAppleProducts[indexPath.row]
return cell!
}
else
{
cell!.textLabel?.text = self.appleProducts[indexPath.row]
return cell!
}
}
func updateSearchResultsForSearchController(searchController: UISearchController)
{
self.filteredAppleProducts.removeAll(keepCapacity: false)
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %#", searchController.searchBar.text!)
let array = (self.sportsList as NSArray).filteredArrayUsingPredicate(searchPredicate)
self.filteredAppleProducts = array as! [String]
self.tableView.reloadData()
}
Does anyone know how to fix that?