need help for creating submit screen new to swift - ios

I have a login screen - after login, I am displaying list in a table view with check boxes. After submitting button. all the selected check box labels should send to server. Login screen and displaying table working how to write action for submit import UIKit
class ViewController: UIViewController,UITableViewDataSource, UITableViewDelegate {
private let dwarves = [
"Sleepy", "Sneezy", "Bashful", "Happy",
"Doc", "Grumpy", "Dopey",
"Thorin", "Dorin", "Nori", "Ori",
"Balin", "Dwalin", "Fili", "Kili",
"Oin", "Gloin", "Bifur", "Bofur",
"Bombur"]
let simpleTableIdentifier = "SimpleTableIdentifier"
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return dwarves.count
}
func tableView(tableView: UITableView,
cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier(
simpleTableIdentifier) as? UITableViewCell
if (cell == nil) {
cell = UITableViewCell(
style: UITableViewCellStyle.Default, reuseIdentifier: simpleTableIdentifier)
}
let image = UIImage(named: "unchecked")
cell!.imageView.image = image
let highlightedImage = UIImage(named: "checked")
cell!.imageView.highlightedImage = highlightedImage
cell!.textLabel.text = dwarves[indexPath.row]
return cell!
}
/*func tableView(tableView: UITableView,
didSelectRowAtIndexPath indexPath: NSIndexPath) {
let rowValue = dwarves[indexPath.row]
for element in rowValue {
sel = [rowValue]
println(element)
}
}*/
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
let rowValue = dwarves[indexPath.row]; println("You selected cell \(indexPath.row)")
}
}

You can create an NSMutableArray instance variable to hold the selected values:
var selected = NSMutableArray()
Then, in your didSelectRowAtIndexPath method, add to the array if the object does not exist or remove the object if it does exist.
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let rowValue = dwarves[indexPath.row]; println("You selected cell \(indexPath.row)")
// if the item exsits then remove it
if selected.containsObject(rowValue) {
selected.removeObject(rowValue)
} else { // else the item doesn't exist so add it
selected.addObject(rowValue)
}
println(selected)
}

Related

How to make it such that there are two seperate groups of cells in the same tableview?

How do I make it such that when names2 is not equals to names, it will add the missing strings from names into the table view but with a different text style?
import UIKit
class TableViewController: UITableViewController {
var names = [String]()
var identities = [String]()
var names2 = [String]()
override func viewDidLoad() {
names = ["First", "Second", "Third", "Fourth"]
identities = ["A", "B", "C", "D"]
names2 = ["First", "Second"]
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return names.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell")
cell?.textLabel!.text = names[indexPath.row]
return cell!
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let vc = identities[indexPath.row]
let viewController = storyboard?.instantiateViewControllerWithIdentifier(vc)
self.navigationController?.pushViewController(viewController!, animated: true)
}
}
For images in collection view
import UIKit
class MedalViewController: UICollectionViewController {
var imagesArray = [String]()
var identities = [String]()
var identities2 = [String]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
imagesArray = ["1", "2", "3"]
identities = ["Shield", "Tie", "Star"]
identities2 = ["Shield", "Tie"]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath)
let imageView = cell.viewWithTag(1) as! UIImageView
imageView.image = UIImage(named: imagesArray[indexPath.row])
return cell
}
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return imagesArray.count
}
override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
let vc = identities[indexPath.row]
let viewController = storyboard?.instantiateViewControllerWithIdentifier(vc)
self.navigationController?.pushViewController(viewController!, animated: true)
viewController?.title = self.identities[indexPath.row]
}
}
How do I make it such that the missing identifier in this case "Star" in which its image is "3" is greyed out in the collectionsView?
You can check that names2 is contains names array object inside cellForRowAtIndexPath and then change the text style you want.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell")
cell?.textLabel!.text = names[indexPath.row]
if (names2.contains(names[indexPath.row])) {
cell.textLabel.textColor = UIColor.blackColor() //Set other style that you want
}
else {
cell.textLabel.textColor = UIColor.redColor() //Set other style that you want
}
return cell!
}
Edit: I doesn't get properly about image but you could try some thing like this.
if (identities2.contains(identities[indexPath.row])) {
cell.imageView = UIImage(named: identities[indexPath.row])
}
else {
cell.imageView = UIImage(named: "DefaultGrayImage") //Set default image not in identities2
}

TableView loop through all cell for deleting them, Swift

I was trying iterating through all cell in TableView and delete them. I call function DeleteAll:
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var myTableView: UITableView!
#IBAction func DeleteAll(sender: UIButton) {
//myTableView.reloadData()
for j in 0..<myTableView.numberOfSections {
for i in (myTableView.numberOfRowsInSection(j) - 1).stride(through: 0, by: -1) {
let myIndexPath = NSIndexPath(forRow: i, inSection: j)
print("I=" + String(i) + "section " + String(j))
self.tableView( myTableView, commitEditingStyle: UITableViewCellEditingStyle.Delete, forRowAtIndexPath: myIndexPath)
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
var indexPathForSelectedRows = [NSIndexPath]()
lazy var productLines: [ProductLine] = {
return ProductLine.productLines()
}()
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
let selctedRow = tableView.cellForRowAtIndexPath(indexPath)!
if editingStyle == UITableViewCellEditingStyle.Delete {
productLines[indexPath.section].products.removeAtIndex(indexPath.row)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
selctedRow.accessoryType = UITableViewCellAccessoryType.None
}
}
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: .Destructive, title: "Delete") { (action, indexPath) in
self.tableView( tableView, commitEditingStyle: UITableViewCellEditingStyle.Delete, forRowAtIndexPath: indexPath)
}
let share = UITableViewRowAction(style: .Normal, title: "Disable") { (action, indexPath) in
}
delete.backgroundColor = UIColor.blackColor()
share.backgroundColor = UIColor.blueColor()
return [delete, share]
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
//self.tableView( tableView, commitEditingStyle: UITableViewCellEditingStyle.Delete, forRowAtIndexPath: indexPath)
let row = tableView.cellForRowAtIndexPath(indexPath)!
if row.accessoryType == UITableViewCellAccessoryType.None {
row.accessoryType = UITableViewCellAccessoryType.Checkmark
}
else {
row.accessoryType = UITableViewCellAccessoryType.None
}
}
// MARK: - Table view data source
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
let productLine = productLines[section]
return productLine.name
}
//override func tableV
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return productLines.count
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
let productLine = productLines[section]
return productLine.products.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("uppercaseString", forIndexPath: indexPath)
let productLine = productLines[indexPath.section]
let product = productLine.products[indexPath.row]
cell.textLabel?.text = product.title
cell.detailTextLabel?.text = product.description
cell.imageView?.image = product.image
// Configure the cell...
return cell
}
}
But I have had this error, and I don't find out what wrong. This is console log:
I=3section 0
I=2section 0
I=1section 0
I=0section 0
I=8section 1
fatal error: unexpectedly found nil while unwrapping an Optional
value (lldb)
Yes, that will return nil if the row isn't on screen, so force
unwrapping is a bad idea. In fact calling the delegate methods
yourself is a bad idea. If you want to reuse code then you should have
your delegate method calla delete method. You can't retrieve all
cells; you can only retrieve cells that are onscreen. You shouldn't
need to retrieve all cells; you simply update your data model and have
the table reflect those changes by reloading the table, reloading
specific rows or inserting/deleting specific rows
– Paulw11

Image added to UITableViewCell appears in wrong rows when scrolling

I'm adding an image to a table view row (actually, I seem to be adding it to the row's cell) when selecting it (and removing when selecting it again). The table view consists of prototype cells.
This works but when I scroll around and get back to the row I had previously selected, the image would be in another row. Also, the image appears in other rows as well.
My guess is this happens because the cells are re-used when scrolling.
Here's the code of a little sample project:
import UIKit
class MyTableViewController: UITableViewController {
// Using integers for simplicity, should work with strings, too.
var numbers = [Int]()
override func viewDidLoad() {
super.viewDidLoad()
for i in 0..<50 {
numbers.append(i)
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("TestCell", forIndexPath: indexPath)
cell.textLabel?.text = "\(numbers[indexPath.row] + 1)"
return cell
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return numbers.count
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath)!
if let myImage = curCell.viewWithTag(10) as? MyImage {
myImage.removeFromSuperview()
} else {
let myImage = myImage()
myImage.tag = 10
cell.addSubview(myImage)
}
}
I need to have the image stay in the correct row, also when coming back to this view controller. What's the correct way to tackle this?
Any advice much appreciated!
EDIT: I've tried to implement matt's answer but I seem to be missing something, as the problem is still the same.
EDIT 2: Updated, working as intended now.
import UIKit
class ListItem {
var name: String!
var showsImage = false
init(name: String) {
self.name = name
}
}
class MyTableViewController: UITableViewController {
var listItems = [ListItem]()
override func viewDidLoad() {
super.viewDidLoad()
for i in 0..<50 {
let listItem = ListItem(name: "row \(i)")
listItems.append(listItem)
}
}
// MARK: - Table view data source
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("TestCell", forIndexPath: indexPath)
cell.textLabel?.text = "\(listItems[indexPath.row].name)"
if listItems[indexPath.row].showsImage {
let myImage = myImage
myImage.tag = 10
cell.addSubview(myImage)
} else {
if let myImage = cell.viewWithTag(10) as? myImage {
myImage.removeFromSuperview()
listItems[indexPath.row].showsImage = false
}
return cell
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return listItems.count
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath)!
if let myImage = cell.viewWithTag(10) as? myImage {
myImage.removeFromSuperview()
listItems[indexPath.row].showsImage = false
} else {
listItems[indexPath.row].showsImage = true
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None)
}
}
}
EDIT 3: As matt suggested, here's an alternative solution to the code above which subclasses UITableViewCell instead of using a tag for the image.
import UIKit
class MyTableViewCell: UITableViewCell {
var myImage = MyImage()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
myImage.hidden = true
addSubview(myImage)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class ListItem {
var name: String!
var showsImage = false
init(name: String) {
self.name = name
}
}
class MyTableViewController: UITableViewController {
var listItems = [ListItem]()
override func viewDidLoad() {
super.viewDidLoad()
for i in 0..<50 {
let listItem = ListItem(name: "row \(i)")
listItems.append(listItem)
}
}
// MARK: - Table view data source
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return listItems.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = MyTableViewCell(style: .Default, reuseIdentifier: "TestCell")
cell.textLabel?.text = "\(listItems[indexPath.row].name)"
cell.myImage.hidden = !(listItems[indexPath.row].showsImage)
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath) as! MyTableViewCell
listItems[indexPath.row].showsImage = cell.myImage.hidden
cell.myImage.hidden = !cell.myImage.hidden
}
}
The problem is that cells are reused in other rows. When they are, cellForRowAtIndexPath is called again. But when it is, you are supplying no information about the image for that row.
The solution: fix your model (i.e. the info you consult in cellForRowAtIndexPath) so that it knows about the image. In didSelect, do not modify the cell directly. Instead, modify the model and reload the cell.

How to overcome of tapping a row in a table

When I am tapping a row in a table it doesn't show the next screen, but when i tapped for another row it show the previous tapped row's details.
How to solve this problem?
class AllListsViewController: UITableViewController {
var lists: [Checklist]
required init(coder aDecoder: NSCoder)
{
lists = [Checklist]()
super.init(coder: aDecoder)
var list = Checklist(name: " Birthdays")
lists.append(list)
list = Checklist( name: "Groceries")
lists.append(list)
list = Checklist(name: "Cool Apps")
lists.append(list)
list = Checklist(name: "To Do")
lists.append(list)
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
let checklist = lists[indexPath.row]
performSegueWithIdentifier("ShowChecklist", sender: checklist)
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return lists.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cellIdentifier = "cell"
var cell: UITableViewCell! = tableView.dequeueReusableCellWithIdentifier(cellIdentifier)
if cell == nil
{
cell = UITableViewCell(style: .Default, reuseIdentifier: cellIdentifier)
}
let checklist = lists[indexPath.row]
cell.textLabel!.text = checklist.name
cell.accessoryType = .DetailDisclosureButton
return cell
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "ShowChecklist"
{
let controller = segue.destinationViewController as! ChecklistViewController
controller.checklist = sender as! Checklist
}
}
}
And this is my didSelectRowAtIndex.
override func tableView (tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
if let cell = tableView.cellForRowAtIndexPath(indexPath)
{
let item = items[indexPath.row]
item.toggleChecked()
configureCheckmarkForCell(cell, withChecklistItem: item)
}
tableView.deselectRowAtIndexPath(indexPath, animated: true)
saveChecklistItems()
}
You are messing up the usage of the delegate.
You are calling performSegueWithIdentifier in the wrong delegate method, where the row get's deselected.
If you want to perform the segue you should do it in the tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) method.
Currently you are doing it in the tableView (tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) method.
Here is how it should look like, after you swapped your code:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
let checklist = lists[indexPath.row]
performSegueWithIdentifier("ShowChecklist", sender: checklist)
}

How to make a click on cell of a Table View in Swift

This is my first day in the awesome SWIFT language, I'm trying to populate a Table view with some data, everything seems to work fine, but I want to make my Table view clickable and print the id of the item clicked but it doesn't seem to be working I'm not getting any Error.
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
var categories = [Category]()
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return categories.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell
cell.textLabel?.text = categories[indexPath.row].Label
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
println("You selected cell #\(indexPath.row)!")
}
override func viewDidLoad() {
super.viewDidLoad()
let reposURL = NSURL(string: "http://myserver.com/file.json")
// 2
if let JSONData = NSData(contentsOfURL: reposURL!) {
// 3
if let json = NSJSONSerialization.JSONObjectWithData(JSONData, options: nil, error: nil) as? NSDictionary {
// 4
if let reposArray = json["List"] as? [NSDictionary] {
// 5
for item in reposArray {
categories.append(Category(json: item))
}
}
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
It seems like you have forgotten to set your UITableViewDelegate:
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self
}
If you haven't defined your tableView as a variable in your code. You can define your delegate and datasource using storyboard.

Resources