I am trying to code images to UIImage but I am having trouble. I am not sure how code it for each different image per list item. The app I am building is a List with pictures attached to each list item.
Below is the MyWhatsit class:
class MyWhatsit {
var name: String {
didSet {
postDidChangeNotification()
}
}
var location: String {
didSet {
postDidChangeNotification()
}
}
var image: UIImage? {
didSet {
postDidChangeNotification()
}
}
var viewImage: UIImage {
return image ?? UIImage(named: "camera")!
}
init( name: String, position: String = "" ) {
self.name = name
self.location = location
}
func postDidChangeNotification() {
let center = NSNotificationCenter.defaultCenter()
center.postNotificationName(WhatsitDidChangeNotification, object: self)
}
}
Below is the Table View:
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return things.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
let thing = things[indexPath.row] as MyWhatsit
cell.textLabel?.text = thing.name
cell.detailTextLabel?.text = thing.location
cell.imageView?.image = thing.viewImage
return cell
}
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
things.removeAtIndex(indexPath.row)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
} else if editingStyle == .Insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
}
}
I believe all you need to do is create an array of images like you are with the title and subtitle. When you add another picture, add the image name to the array and append the tableView.
What I see in your code is a name and position. It looks like you need to add "image" and set it to the name of the image. For example, MyWhatsit(name: "Bob Smith", position: "midfielder", image: "bobSmithImage")... and then you set the cell's image view equal to the image name.
Hope this gets you moving!
You need to create your own personal category. For example sorting your players based on positions they play. Using a class that stores your images into an array. For example:
let goalkeeper = [UIImage(named:"ivanlucic"), UIImage(named:"manuelneuer")]
let rightBack = [UIImage(named:"danialves"), UIImage(named:"sergioramos")]
After you have a list of images, inside your cellForRowAtIndexPath you can do a checking, and reference it to the array your created.
Didn't get how you are setting the code in the tableview but you can add image name with names like
Where image key contains the image name you have stored in the XCAssets
var things: [MyWhatsit] = [
MyWhatsit(name: "Ivan Lucic", position: "Goalkeeper","image":"ivan"),
MyWhatsit(name: "Manuel Neuer", position: "Goalkeeper","image":"manuel")...]
And you can init the image at the same time you init the name
init( name: String, position: String = "", imagename:string ) {
self.name = name
self.position = position
self.imgview = UIImage(named:imagename)
}
Related
I have a fairly standard UITableView that populates via custom cell. That cell is simply an image and a label at the moment. I cannot, for the life of me, get it to resize on it's own.
When I include UITableViewAutomaticDimension, I lose the ability to populate my data in addition to incorrect layouts.
Without UITableViewAutomaticDimension, the data is displayed properly.
I am using SnapKit to handle constraints and Meteor/SwiftDDP to handle the data, but there is another UITableView in the project that seems to be working properly
ViewController
class CommentViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var commentTable:UITableView!
var comments:MeteorCollection<Comment>!
init() {
super.init(nibName: nil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
comments = MeteorCollection<Comment>(name: "comments")
createView()
Meteor.subscribe("postsComments", params: [["postId": self.source!.id!]]) {}
}
func createView() {
let contentTableView = UITableView(frame: content.frame)
content.addSubview(contentTableView)
contentTableView.backgroundColor = UIColor.clearColor()
self.commentTable = contentTableView
contentTableView.delegate = self
contentTableView.dataSource = self
contentTableView.snp_makeConstraints { (make) -> Void in
make.top.equalTo(content)
make.left.equalTo(content)
make.right.equalTo(content)
make.height.equalTo(content).inset(65)
}
contentTableView.rowHeight = UITableViewAutomaticDimension
contentTableView.estimatedRowHeight = 350
}
}
CommentTableViewDelegate.swift
import UIKit
extension CommentViewController {
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.comments.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(CommentTableViewCell.reuseIdentifier, forIndexPath: indexPath) as UITableViewCell
cell.setNeedsUpdateConstraints()
cell.updateConstraintsIfNeeded()
if let card = cell as? CommentTableViewCell {
let item = self.comments.sorted[indexPath.row]
card.populate(item)
}
return CommentTableViewCell()
}
func reloadTableView() {
self.commentTable.reloadData()
}
}
An example of my garbled mess when not using UITableViewAutomaticDimension
An example of my garbled mess when using UITableViewAutomaticDimension
It might be due to improper constraint within cell. Please add constraint properly in table view cell and set these two properties of UILable from Attributes inspector section of storyboard:
lines to 0
Line break to word wrap
or you can also set these properties from code:
self.lblxyz.numberOfLines = 0
self.lblxyz.lineBreakMode = .byWordWrapping
Note - Do not fix the height of UILable.
Hope it will help you... :)
I'm not sure if it works but, I've been through the same problem recently, and i fixed it by changing the estimatedRowHeight .
Can you please try once with:-
contentTableView.estimatedRowHeight = 350
to, contentTableView.estimatedRowHeight = 160
I'm a high school student working on an app in Xcode 8 using Swift 3. I am trying to create a way to create a table view with collapsible sections. I am trying to create a way to have my code create a view that pushes all of the data into organized sections. Im trying to have my data displayed through using an extension. Even when I have a breakpoint after the extension it never reaches that point.
Edit: The rest of the app is built within the Main.storyboard, however (as you can see), this tableViewController is built entirely within code.
I can create a segue to the WeaponSelectVC however, none of the information and sections are displayed. Breakpoints inside the datasource/delegate methods do not 'break' the program and no information is displayed.
Edit #2: From the storyboard, I segue to this TableViewController (WeaponSelectVC) using the following code after a button is pressed:
let window = UIWindow(frame:UIScreen.main.bounds)
window.makeKeyAndVisible()
window.rootViewController = UINavigationController(rootViewController: WeaponSelectVC())
I can see the table loaded for an instant before the Main.Storyboard ViewController (with the button) gets loaded on top of this.
The Table does not contain any of the information or sections when we see it for an instant (it also isn't loaded when I open this separately).
Below is the code from the WeaponSelect class:
struct section {
var name: String!
var items: [String]!
var collapsed: Bool
init(name: String, items: [String], collapsed: Bool = false) {
self.name = name
self.items = items
self.collapsed = collapsed
}
}
class WeaponSelectVC: UITableViewController {
var sections = [section]()
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Weapons"
// Initialize the sections array
// Here we have three sections: Mac, iPad, iPhone
sections = [
section(name: "Canadian Weapons", items: ["Colt-browning machine gun M1895/14 (Canadian)","Lee Enfield (Canadian)", "Ross Rifle MK III(Canada)", "Webley revolver (Canadian)", "Lewis (Canadian)", "Mills bomb (Canadian)"]),
section(name: "German Weapons", items: ["KAR-98K (German)", "Mauser Gewehr 98 (German)", "Luger (German), Stick grenade (German)"]), ]
// self.tableView.reloadData()
self.tableView.dataSource = self
// self.tableView.delegate = self
// self.tableView.reloadData()
}
}
extension WeaponSelectVC {
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return sections.count
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sections[section].items.count
}
// Cell
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as UITableViewCell? ?? UITableViewCell(style: .default, reuseIdentifier: "cell")
cell.textLabel?.text = sections[indexPath.section].items[indexPath.row]
return cell
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return sections[indexPath.section].collapsed ? 0 : 44.0
}
// Header
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "header") as? CollapsibleTableViewHeader ?? CollapsibleTableViewHeader(reuseIdentifier: "header")
header.titleLabel.text = sections[section].name
header.arrowLabel.text = ">"
header.setCollapsed(sections[section].collapsed)
header.section = section
header.delegate = self
return header
}
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 44.0
}
func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 1.0
}
}
//
// MARK: - Section Header Delegate
//
extension WeaponSelectVC: CollapsibleTableViewHeaderDelegate {
func toggleSection(_ header: CollapsibleTableViewHeader, section: Int) {
let collapsed = !sections[section].collapsed
// Toggle collapse
sections[section].collapsed = collapsed
header.setCollapsed(collapsed)
// Adjust the height of the rows inside the section
tableView.beginUpdates()
for i in 0 ..< sections[section].items.count {
tableView.reloadRows(at: [IndexPath(row: i, section: section)], with: .automatic)
}
tableView.endUpdates()
}
}
From which class is the WeaponSelectVC inherited? Your extension should be inheriting from UITableView .
Your extension class should look like
extension UITableView {
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?
I have data saved like this:
var mineSpillere = ["erik", "tom", "phil"]
How can i add that data to a UITableView by pressing a UIButton like this?:
#IBAction func backButtonAction(sender: AnyObject) {
// Press this button here to add the "mineSpillere" data to myTableView
}
Set the data source of the table view inside the IBAction. so like this:
#IBAction func backButtonAction(sender: AnyObject) {
myTableView.dataSource = self
// Loading from NSUserDefaults:
// Please name it something better than array I couldn't come up with any names.
if let array = NSUserDefaults.standardUserDefaults().arrayForKey("key") as? [String]
{
// The key exists in user defaults
}
else
{
// The key doesn't exist in the user defaults, do some error handling here.
}
}
And then implement the data source:
extension MyVC : UITableViewDataSource
{
func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return mineSpillere.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = UITableViewCell(style: .Default, reuseIdentifier: "cell")
cell.textLabel!.text = mineSpillere[indexPath.row]
return cell
}
}