Swift UITableView not showing all result - ios

I have UITableView hook up to an array.
var shoppingList: [String] = ["Eggs", "Milk","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O"]
However, when I run the app in the simulator, it doesn't allow me to scroll to the end. Why is that? I can only scroll to the letter "I" and see half of the "J", but I can't scroll down further. In the func tableView, it shows the correct array size, so I know the items are all there, but can't scroll to the the end. Below is the screen shot. thank you.
screen shot
screen shot 2
here's the code
import UIKit
class TestTableViewController: UITableViewController {
var shoppingList: [String] = ["Eggs", "Milk","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O"]
override func viewDidLoad() {
super.viewDidLoad()
print("test")
// 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()
}
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
print(shoppingList.count)
return shoppingList.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("TestCell", forIndexPath: indexPath)
// Configure the cell...
cell.textLabel!.text = shoppingList[indexPath.row]
// Configure the cell...
print("here")
return cell
}

Julia, It seems that the table view is longer than the screen itself. If you go into your story board and shorten the length of your tableview, you will be able to see the rest as along as it's the same or shorter size of the screen.
You can add constraints that will automatically snap to the fit what ever size of screen.
If you want to do it by code, try this in your viewDidLoad()
tableView.frame.size = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)

Related

Creating a 'Favourites' section in an app

I'm currently working on an app in which I would like the users to be able to favourite a button and that button then gets added to the 'Favourites' section for that particular ViewController.
The app is a soundboard so it is split into (currently) 2 characters, within those characters I have categories of sound files for the users to choose from, once the user selects a category it will load up the ViewController with a set of sounds which can be played by pressing the button (very simple I know).
I'm trying to implement a 'Favourite' function in order to allow the user to favourite the buttons of their choice and in doing so, the new 'favourited' button will be displayed in a new ViewController.
I've browsed through here and found some stuff in regards to NSUserDefaults
I'm new to Swift and iOS development as a whole so if someone could be kind enough to guide me in the right direction I would be very grateful.
I know how to set the Image of the favourite button to change whether it has been set as a favourite or not, I also noticed that it suggests I place the favourites in a UITableViewController. My app is currently using a UITabBarController with 4 different ViewControllers off them.
If you would like screenshots of my Storyboard to get a better understanding please let me know and I shall update the post, also if any code is required please let me know and once again, I shall update the post!
EDIT: I will happily add a button which when pressed loads a table view if someone knows how to add a normal button into a table view so when pressed it shows the favourites
EDIT 2: Image
try to do as follows-
Take a UITabBarController having one viewController as soundsViewController and another tableViewController as favouritesTableViewController shown as below image-
Now add these sample code to soundsViewController-
var favListArray:NSMutableArray = []
#IBOutlet weak var tableView: UITableView!
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
if NSUserDefaults.standardUserDefaults().objectForKey("favList") != nil {
favListArray = NSMutableArray.init(array: NSUserDefaults.standardUserDefaults().objectForKey("favList") as! NSMutableArray)
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return 10
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("soundCell", forIndexPath: indexPath) as! TableViewCell
cell.titleLbl.text = NSString.localizedStringWithFormat("Sound %d", indexPath.row) as String
if favListArray.containsObject(cell.titleLbl.text!) {
cell.addTOFVrtBtn.setTitle("-", forState: UIControlState.Normal)
}else{
cell.addTOFVrtBtn.setTitle("+", forState: UIControlState.Normal)
}
cell.addTOFVrtBtn.tag = indexPath.row
cell.addTOFVrtBtn.addTarget(self, action:#selector(addToFav) , forControlEvents: UIControlEvents.TouchUpInside)
return cell
}
func addToFav(sender:UIButton) {
let cell = self.tableView.cellForRowAtIndexPath(NSIndexPath.init(forRow: sender.tag, inSection: 0)) as! TableViewCell
if favListArray.containsObject(cell.titleLbl.text!) {
favListArray.removeObject(cell.titleLbl.text!)
}else{
favListArray.addObject(cell.titleLbl.text!)
}
tableView.reloadData()
NSUserDefaults.standardUserDefaults().setObject(favListArray, forKey: "favList")
}
these is a sample code, here TableViewCell is subclass of UITableViewCell having titleLbl and addTOFvrtBtn.
Add below sample code to favouritesTableViewController -
varfavSoundList:NSMutableArray = []
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
if NSUserDefaults.standardUserDefaults().objectForKey("favList") != nil {
favSoundList = NSMutableArray.init(array: NSUserDefaults.standardUserDefaults().objectForKey("favList") as! NSMutableArray)
print(favSoundList)
self.tableView.reloadData()
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
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 favSoundList.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
cell.textLabel?.text = favSoundList.objectAtIndex(indexPath.row) as? String
return cell
}
Here is the o/p screen demo-
I hope this will help you or you can get an idea how to make Favourites list and Favourites section..Thanks
Don't think of it as favouriting a button, a button is just how you're displaying the data in your app - what you're really favouriting is the data itself, so in this case a particular sound file.
So, your current data is a list of sound files, or the path to those files. Your favourites list can be exactly the same. I imagine you might be simply getting a list of files from disk to display so your list of favourites will need to be stored differently. That could be in user defaults, or in a plist file, either way it's an array of strings and both are simple options to store the array.
When storing you just set the array into defaults with a key, or write it to a file. When you read back you should either read from user defaults and then make a mutableCopy or use NSMutableArray to read the file in so you have an editable instance afterwards and you can add and remove favourites from the list.
Your approach of using buttons to represent the sound files is probably a lot more code and effort than you require. Table views are specifically designed to show a list of things, and there's no reason that a table view can't look like a list of buttons (while being much more flexible and much less code to create).

Trying to populate a tableview however label content does not show up in simulator

I am currently working on an app that needs to load label content into a table view controller. I have created an array of string values that I want to populate the table view but for some reason the content is not showing up in the simulator. I am not getting any errors but the data does not seem to register. Any thoughts on how I can resolve this?
Below is my table view controller file:
categoryTableViewController.swift
// Style Guide
//
// Created by Claudia Laurie on 5/30/16.
// Copyright © 2016 Claudia Laurie. All rights reserved.
//
import UIKit
//struct Color {
// let red, green, blue: Double
// init(red: Double, green: Double, blue: Double) {
// self.red = red
// self.green = green
// self.blue = blue
// }
// init(white: Double) {
// red = white
// green = white
// blue = white
// }
//}
I
class clothing_category: NSObject {
let name: String!
init (name: String) {
self.name = name
}
}
class categoryTableViewController: UITableViewController {
// MARK: Properties
// Create an array to hold the clothing.
var clothing_categories = [clothing_category]()
override func viewDidLoad() {
super.viewDidLoad()
// Register cells? let me google...is this why nothing was showing up in the cells themselves despite loading the data? maybe
self.tableView.registerClass(catgeoriesTableViewCell.self, forCellReuseIdentifier: "categoriesTableViewCell")
// Load sample data
loadSampleClothing_categories()
}
func loadSampleClothing_categories() {
clothing_categories.append(clothing_category(name:"Jackets"))
clothing_categories.append(clothing_category(name: "Accessories"))
clothing_categories.append(clothing_category(name: "Pants"))
clothing_categories.append(clothing_category(name: "Color"))
clothing_categories.append(clothing_category(name: "Tops"))
clothing_categories.append(clothing_category(name: "Dressing for an Occaision"))
// Load up the array when the view is loaded.
clothing_categories.append(clothing_category(name:"Jackets"))
clothing_categories.append(clothing_category(name: "Accessories"))
clothing_categories.append(clothing_category(name: "Pants"))
clothing_categories.append(clothing_category(name: "Color"))
clothing_categories.append(clothing_category(name: "Tops"))
clothing_categories.append(clothing_category(name: "Dressing for an Occaision"))
// 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()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return clothing_categories.count
}
// Table view cells are reused and should be dequeued using a cell identifier.
let cellIdentifier = "categoriesTableViewCell"
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// This is the line that is failing, lets find out why
let cell = tableView.dequeueReusableCellWithIdentifier("categoriesTableViewCell", forIndexPath: indexPath) as! catgeoriesTableViewCell
//Fetches the appropriate clothing_catgeory for the data source layout.
let category = clothing_categories[indexPath.row]
cell.nameclothing_category.text = category.name
return cell
}
I believe I have also properly created an outlet connection to the datasource and delegate.
self.tableView.registerClass(catgeoriesTableViewCell.self, forCellReuseIdentifier: "categoriesTableViewCell")
This line is causing problem for you.
If you are loading the cell from a nib or xib then you first need to load the nib and then register it. The nibname has to match the file name and restoration id.
let cellNib = UINib(nibName: "LanguagePickerCellView", bundle: nil)
tableView.registerNib(cellNib, forCellReuseIdentifier: "reuseIdentifier")
If you are using prototype cells directly in interface builder then you just have to put the reuseIdentifier in storyboard.
If you are using a UITableViewController directly then you don't need to link dataSource and delegate, it's done automatically. If you are using plain TableView then you have to link dataSource and delegate.

How to restrict the size of table view which is on left side of the split view controller?

I have a UISplitViewController. So I want to see my master view(i.e table view) upto the size of its content (consider it have only 3 element's).
I tried With self.tableview.contentsize but did not succeeded. Please help me finding solution.
Each cell's Height is 44 .
This is the Code That I wrote.
class AccountTableViewController: UITableViewController {
var filterList = [String]()
var selectedIndex = -1
override func viewDidLoad() {
super.viewDidLoad()
filterList = ["All Accounts","Business Accounts","Person Accounts"]
self.tableView.contentSize = CGSize(width: 600, height: 44*3);
}
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 3
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("accountCell", forIndexPath: indexPath)
cell.textLabel?.text = filterList[indexPath.row]
return cell
}}
I grabbed Ray Wenderlich's example project (https://www.raywenderlich.com/94443/uisplitviewcontroller-tutorial-getting-started) as a starting point. That's what you see modified in the pictures below.
In Interface Builder, first make sure your set to use AutoLayout:
Then drag a UIView under the prototype cell (I set the background to orange so you can see where it is), and make the size whatever you like:
I added some fields to the to the new UIView that we just created, and I added constraints so you could see them move based on the content at runtime. (You'll notice the storyboard view controller as a much larger width in IB than at runtime.) Here's the constraints I added:
Finally, run the app--no need to do anything in code:
Once you get this basic part working, then you can configure the size of the view in code. You can design the view in IB if you want, or do it in code--whatever you prefer.
Here's an example with just one row in the table:
And here's an example with no rows in the table:

Nothing appearing in UITableView cell

I am working on an app that needs to display five different images inside of five different tableview cells. This is the storyboard that I have for the cell.
This is the code I have inside of the tableviewcontroller.
class MasterViewController: UITableViewController, UITableViewDelegate, UITableViewDataSource {
var returnTable = 1
var icons: [String] = ["settings", "calendar", "classes", "envelope", "grades"]
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()
}
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 Potentially incomplete method implementation.
// Return the number of sections.
return 0
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete method implementation.
// Return the number of rows in the section.
return icons.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! HomeScreenCells
var image : UIImage = UIImage(named: icons[indexPath.row])!
cell.icon.image = image
return cell
}
I also have a custom class for the tableviewcells. Also, I have the correct reuse identifier for the cell. Still, the image does not appear. Not only does the image not appear, nothing appears. When I change the background, the background does not change in the simulator. This is all I get in the simulator.
I have the classes linked up correctly for the split view controller. I have no idea why nothing is appearing in the table. Any help would be appreciated.
I think your problem may be that you have the number of sections set to 0. Either set it to 1, or leave out the block of code completely.
As stated above, return 1 in number of sections (or the number of cells you need). And if your custom cell class has a .xib, you also need to register it, sometimes after you init the tableview
tableView.registerNib( UINib(nibName: "HomeScreenCells", bundle: nil), forCellReuseIdentifier: "Cell")

add identifier to segue

I have created a segue from a button, but it has given me the following error. I am using Swift and Xcode 6.
/Users/dave_cooljamdesign/Desktop/XcodeDev/findaphysio2/FindaPhysio/FindaPhysio/Base.lproj/Main.storyboard: Segues initiated directly from view controllers must have an identifier
How do I give them an identifier when I'm draging from table view to the detail view?
Below is some code to show what I am doing in the view controller
import UIKit
import MapKit
class ClinicsTableViewController:
UITableViewController {
var clinic = [Clinics]()
#IBOutlet var mapView: MKMapView!
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()
self.clinic = [Clinics(name:"Chocolate")]
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 Potentially incomplete method implementation.
// Return the number of sections.
return 0
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete method implementation.
// Return the number of rows in the section.
return self.clinic.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//ask for a reusable cell from the tableview, the tableview will create a new one if it doesn't have any
let cell = self.tableView.dequeueReusableCellWithIdentifier("findaphysioCell", forIndexPath: indexPath) as UITableViewCell
// Get the corresponding candy from our candies array
let _clinic = self.clinic[indexPath.row]
// Configure the cell
cell.textLabel!.text = _clinic.name
cell.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
return cell
}
}
Find the segue on the storyboard (the line between view controllers with a circle in the middle) and click it.
Then open the attributes inspector in the utilities pane and give it an identifier.
As gabbler mentioned, the shortcut command + option + 4 will immediately open the attributes inspector.
In your storyboard, select the segue between the two view controllers. Go to the attributes inspector on the right and add an identifier name.
In your code do something like this:
self.performSegueWithIdentifier("setupView", sender: self)
Obviously change 'setupView' with whatever you set for the segue identifier.

Resources