I had an error with Xcode where I needed to fix the size class. After I did that, I went back to one of my table views, and it added white space above the first prototype cells in the tableview. How can I get rid of that space? I added this picture below to better describe what I mean.
https://www.dropbox.com/s/7ebxipb0r2jakav/TableViewProblem.png?dl=0
#IBOutlet var schoolTable: UITableView!
var namesArray = [String]()
var locationsArray = [String]()
var currentUser = PFUser.currentUser()
var theSchoolName: String = "None Selected"
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(animated: Bool) {
namesArray.removeAll(keepCapacity: false)
locationsArray.removeAll(keepCapacity: false)
var query = PFQuery(className: "Schools")
query.findObjectsInBackgroundWithBlock { (objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil {
if let objects = query.findObjects() as? [PFObject] {
for object in objects {
self.namesArray.append(object.valueForKey("schoolName") as! String)
self.locationsArray.append(object.valueForKey("schoolLocation") as! String)
self.schoolTable.reloadData()
}
}
} else {
println("Oops, it didn't work...")
}
}
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.namesArray.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:ChangeSchoolListTableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell") as! ChangeSchoolListTableViewCell
if namesArray.count > 0 {
cell.nameLabel.text = namesArray[indexPath.row]
cell.locationLabel.text = locationsArray[indexPath.row]
}
return cell
}
I've seen this a lot with Xcode storyboards.
The solution is to move the UITableView so its not the first view on the screen.
Space at the top of UITableViews
Related
I am trying to populate my feed of images and text users post. The code compiles and runs but I get empty cells.
var titles = [String]()
var locations = [String]()
var dates = [String]()
var imageFiles = [PFFile]()
override func viewDidLoad() {
super.viewDidLoad()
var privacySettingQuery = PFQuery(className: "Posts")
privacySettingQuery.whereKey("privacy", equalTo: true)
privacySettingQuery.findObjectsInBackgroundWithBlock { (objects, error) -> Void in
if let objects = objects {
for object in objects {
self.titles.append(object["name"] as! String)
self.dates.append(object["dateTime"] as! String)
self.locations.append(object["location"] as! String)
self.imageFiles.append(object["imageFile"] as! PFFile)
}
}
}
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return titles.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath(indexPath: NSIndexPath) -> UITableViewCell {
let postsCell = tableView.dequeueReusableCellWithIdentifier("PostsCell", forIndexPath: indexPath) as! PostsCell
postsCell.postImage.image = UIImage(named: "Post-Image- Placeholder-1.png")
postsCell.postTitle.text = titles[indexPath.row]
postsCell.postLocation.text = locations[indexPath.row]
postsCell.postDate.text = dates[indexPath.row]
return postsCell
}
Any help would be appreciated. Also is there a better way to do this other than using arrays?
To solve the empty issue.You need call tableView.reloadData() after you got the objects.
Model class like
class Post: NSObject {
var title: String
var location: String
var date: NSDate
var imageFile: PFFile
}
And in viewController use
var posts: [Post]?
instead of the 4 arrays
When this code is being called
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return titles.count
}
The value for titles.count is still 0. After you finish fetching the info from parse and you have values for the arrays you must reload the UITableView. To do this make an outlet for the UITableView and call it tableView. Then call this code tableView.reloadData()
Hope this helps!!
I am attempting to display data from Parse onto the following tableView controller. For some reason, the data is not displaying on the tableView (i.e. the rows are blank). I do not think that the data queried from Parse is being appended to the arrays. I am wondering what I'm doing wrong here.
Here's the current output:
I am using a custom prototype cell with identifier "CellTrack" class "TrackTableViewCell" and as shown below:
Here is my code in the TableViewController file:
import UIKit
import Parse
class MusicPlaylistTableViewController: UITableViewController {
var usernames = [String]()
var songs = [String]()
var dates = [String]()
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(animated: Bool) {
var query = PFQuery(className:"PlaylistData")
query.findObjectsInBackgroundWithBlock { (objects: [PFObject]?, error: NSError?) -> Void in
if error == nil {
if let objects = objects! as? [PFObject] {
self.usernames.removeAll()
self.songs.removeAll()
self.dates.removeAll()
for object in objects {
let username = object["username"] as? String
self.usernames.append(username!)
print("added username")
let track = object["song"] as? String
self.songs.append(track!)
let date = object["createdAt"] as? String
self.dates.append(date!)
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 usernames.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("CellTrack", forIndexPath: indexPath) as! TrackTableViewCell
cell.username.text = usernames[indexPath.row]
cell.songTitle.text = songs[indexPath.row]
cell.CreatedOn.text = dates[indexPath.row]
return cell
}
}
And here is my code in the "TrackTableViewCell.swift" class:
import UIKit
class TrackTableViewCell: UITableViewCell {
#IBOutlet weak var songTitle: UILabel!
#IBOutlet weak var username: UILabel!
#IBOutlet weak var CreatedOn: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
Execute your tableView.reloadData() in main thread.
dispatch_async(dispatch_get_main_queue(), {
self.tableViewCell.reloadData()
})
Try doing a guard let to see if those values are actually coming back as string or not. My guess would be that the value for created at never came back. Try it out and let me know.
guard let username = object["username"] as? String else {
print ("could not get username")
}
self.usernames.append(username)
print("added username")
guard let track = object["song"] as? String else {
print ("could not get song")
return
}
self.songs.append(track)
guard let date = object["createdAt"] as? String else {
print ("could not get createdAt")
return}
self.dates.append(date!)
func dequeueReusableCellWithIdentifier(_ identifier: String) -> UITableViewCell?
Return Value
A UITableViewCell object with the associated identifier or nil if no such object exists in the reusable-cell queue.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("CellTrack", forIndexPath: indexPath) as! TrackTableViewCell
if cell == nil {
// create a new cell here
cell = TrackTableViewCell(...)
}
cell.username.text = usernames[indexPath.row]
cell.songTitle.text = songs[indexPath.row]
cell.CreatedOn.text = dates[indexPath.row]
return cell
}
I'm doing Rob's UDEMY iOS8 Swift course and so far so good.
I use a Tab Bar Controller to separate tabs: Profile, Ask, Browse etc...
In the 'Ask' tab, I input a text and it is successfully uploaded to Parse and I want that text to be displayed in the 'Browse' tab. The Browse tab is a Table View with prototype cell, I added labels there to display username and the text.
My problem is that it doesn't display the text nor the username from Parse. Here is the code:
import UIKit
import Parse
class browseViewController: UITableViewController{
var postedQuestion = [String]()
var usernames = [String]()
override func viewDidLoad() {
super.viewDidLoad()
var query = PFQuery(className:"Post")
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]?, error: NSError?) -> Void in
if error != nil {
if let objects = objects as? [PFObject] {
for object in objects {
self.postedQuestion.append(object["postedQuestion"] as! String)
self.usernames.append(object["username"] as! String)
self.tableView.reloadData()
}
}
} else {
println(error)
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return usernames.count
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 227
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var myCell:cell = self.tableView.dequeueReusableCellWithIdentifier("myCell") as! cell
myCell.postedQuestion.text = postedQuestion[indexPath.row]
myCell.username.text = usernames[indexPath.row]
myCell.sizeToFit()
return myCell
}
}
Error message:
nil
I can see it is loading the data (from Parse) but then it just gives me that error message. It doesn't crash tho.
Thanks!
I am running into difficulty displaying the data from the query I made in the individual cells of my tableview. I believe that my logic is correct, but I'm not seeing the console.log's that I am calling within my function that contains the Parse queried data. This might be a simple fix, but it isn't coming to me at the moment. The console log I should be seeing to validate that my query is coming through correctly is the println("\(objects.count) users are listed"), it should then be displayed within the usernameLabel.text property.
import UIKit
class SearchUsersRegistrationViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var userArray : NSMutableArray = []
#IBOutlet var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
loadParseData()
}
func loadParseData() {
var query : PFQuery = PFUser.query()
query.findObjectsInBackgroundWithBlock {
(objects:[AnyObject]!, error:NSError!) -> Void in
if error == nil {
if let objects = objects {
println("\(objects.count) users are listed")
for object in objects {
self.userArray.addObject(object)
}
self.tableView.reloadData()
}
} else {
println("There is an error")
}
}
}
let textCellIdentifier = "Cell"
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.userArray.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(textCellIdentifier, forIndexPath: indexPath) as! SearchUsersRegistrationTableViewCell
let row = indexPath.row
let cellDataParse : PFObject = self.userArray.objectAtIndex(row) as! PFObject
//cell.userImage.image = UIImage(named: usersArr[row])
cell.usernameLabel.text = cellDataParse.objectForKey("_User") as! String
return cell
}
}
I fixed the issue. I needed to cast the index path row in the users array as a PFUser and then cast the user's username property as a String and then set that as the label text.
let row = indexPath.row
var user = userArray[row] as! PFUser
var username = user.username as String
cell.usernameLabel.text = username
My code has an issue when I run the iOS simulator. It breaks and brings me to the line of code:let targetUser = users[indexPath.row] and says 'EXC_BAD_INSTRUCTION (CODE=EXC_1386_INVOP,snbcode = 0x0)' would anyone be able to help me figure out why?
class OverviewTableViewController: UITableViewController {
#IBOutlet weak var LogoutButton: UIBarButtonItem!
#IBOutlet weak var ChoosePartnerButton: UIBarButtonItem!
var rooms = [PFObject]()
var users = [PFUser]()
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.setLeftBarButtonItem(LogoutButton, animated: false)
self.navigationItem.setRightBarButtonItem(ChoosePartnerButton, animated: false)
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
if PFUser.currentUser() != nil {
loadData()
}
}
func loadData() {
rooms = [PFObject]()
users = [PFUser]()
self.tableView.reloadData()
let pred = NSPredicate(format: "user1 = %# OR user2 = %#", PFUser.currentUser()!, PFUser.currentUser()!)
let roomQuery = PFQuery(className: "Room", predicate: pred)
roomQuery.includeKey("user1")
roomQuery.includeKey("user2")
roomQuery.findObjectsInBackgroundWithBlock { (results:[AnyObject]?, error:NSError?) -> Void in
if error == nil {
self.rooms = results as! [PFObject]
for room in self.rooms {
let user1 = room.objectForKey("user1") as! PFUser
let user2 = room["user2"] as! PFUser
if user1.objectId != PFUser.currentUser()?.objectId {
self.users.append(user1)
}
if user2.objectId != PFUser.currentUser()?.objectId {
self.users.append(user2)
}
}
self.tableView.reloadData()
}
}
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// Return the number of sections.
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of rows in the section.
return rooms.count
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 80
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! OverviewTableViewCell
let targetUser = users[indexPath.row]
cell.nameLabel.text = targetUser.username
return cell
}
Sounds like #MartinR had nailed it. You're reading rooms.count in numberOfRowsInSection, but then looking up data from the users array in cellForRowAtIndexPath.
You could figure this out in the debugger by examining indexPath.row when you crash, and examining the size of rooms.count as well.