I created a TableView directly in the storyboard; this tableView contains 8 static cells (style basic) in 4 section; now, how could I edit via code these cells? for example for to change textLabel, backgroundColor, separator ecc
I tried to set an identifier to each cel but didn't work...
For static cells created in the storyboard, you can simply set the IBOutlet for the elements you want to edit by ctrl-dragging from the storyboard to the corresponding view controller, to end up with something like this:
class MyViewController: UIViewController {
#IBOutlet weak var cell1: UITableViewCell!
#IBOutlet weak var cell2: UITableViewCell!
}
Then you can access the built-in elements in the Basic view with cell1.textLabel etc.
Check out the documentation about setting IBOutlets.
To change the background color, you can do it in the storyboard UI directly or access the backgroundColor property. You might want to read the UITableViewCell Class Reference.
Thanks p4sh4 for #IBOutlet suggestion.
But instead of multiple Outlets, you should try an "Outlet Collection".
#IBOutlet var tableLabelCollection: [UILabel]!
override func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath) {
print("accessory Button Tapped: \(indexPath.row) => \(tableLabelCollection[indexPath.row].text)")
}
Related
I have a TableViewController that uses a custom prototype cell. The outlets for the cell contents are defined in a swift file named BYMyCell.swift.
class BYMyCell: UITableViewCell {
#IBOutlet weak var yearLabel: UILabel!
#IBOutlet weak var descriptionLabel: UILabel!
#IBOutlet weak var startingDateLabel: UILabel!
#IBOutlet weak var commentsLabel: UILabel!
#IBOutlet weak var openStateImage: UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
In my BusinessYearViewController which is a TableViewController view I define the cell for the CellForRowAt func as the following:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellID", for: indexPath) as! BYMyCell
This casting "as! BYMyCell" works fine. I am able to put data in the outlets that are labels and an image into my custom cell.
Now I would like to make the cell or row swipeable. I have loaded the SwipeCellKit cocoaPod which I have used before when the cellForRowAt did not use the downcasting for the custom cell. The documentation suggest that I need to downcast the "let cell ..." definition to downcast to "as! SwipeCellKit" such as:
let cell = tableView.dequeueReusableCell(withIdentifier: "cellID", for: indexPath) as! SwipeTableViewCell
I'm not sure if this will disable my outlets from the BYMyCell.swift file on behalf of my ViewController. Can someone suggest how I would handle both a custom cell and making it a cocoapod swipeable cell at the same time.
My reason is to put Edit, Flag, and Delete functions in the swipeable cell UI.
Learning Swift and Storyboards, I'm attempting to create a View of repeating cells (UITableView).
So far I have created a view with a UIView, linked to a UITableView with a UITableViewCell inside. The issue I'm having is my cells are not displaying "woof" as per below.
My View Controller looks like this:
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var myTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellId") as! MyListViewCell
cell.myLabel.text = "woof"
return cell
}
}
After some research, I believe I don't need to register:
myTableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellId")
as it's already linked as an outlet successfully
but I thought I may need to do delegate and datasource like so:
myTableView.datasource = self
myTableView.delegate = self
but I received: Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
I am attempting to use MVVM which I think is meant to only use the one ViewController. Am I meant to be using a UITableViewController instead?
I have verified that my cell identifier is set correctly in the storyboard.
This error in your case can be related to the missing connection between UITableView in a storyboard and your IBOutlet myTableView.
Concerning the UITableView.register(_:forCellIdentifier:) method, when you are creating a cell in UITableView in a storyboard then this method is called by UIKit when loading the storyboard. You should call this method when you have created a custom UITableViewCell subclass in code or Xib file.
Setting delegate and dataSourceDelegate can be done in a storyboard file without creating an IBOutlet in a view controller. Just select Table View and go to the connections inspector and drag a delegate and a datasource delegate to the view controller.
Firstly, check if you have connected properly on storyboard(Outlets,identifier everything).
Secondly, if nothing works try disconnecting and connecting the Outlets again.
cell.textLabel?.text = "my string"
This above works fine but I would like to have two different textLabels like I do in my prototype cell.
Any help is much appreciated.
**Edit
cellForRowAt:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = holesTableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MyTableViewCell
cell.labelHole?.text = "Hole \(mainCurrentHoleNumber)"
cell.labelShots?.text = "\(mainShotsEachHole[indexPath.row])"
return cell
}
Hi if your are using storyboard to create your cell, just drag and drop another label and then make a custom UITableViewCell class for that prototype cell and click hold and drag while holding control to make outlets for the labels. After you make outlets you can use both textLabels in your code.
#IBOutlet weak var textLabel1: UILabel!
#IBOutlet weak var textLabel2: UILabel!
Either hold control and click and drag using the assistant editor to make the outlet or type the above line in your custom cell class and then right click on the left pane (storyboard scene) in the storyboard and connect the outlet you make to the label.
I hope this helps.
Register the nib, not the cell.
(void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier;
Issue
I have a single page app with a single view controller. On the screen there is a button that slides out/in a (smaller) UIView with a TableView (functions correctly). My goal is to simplify my view controller, hence my idea was to split off the UIView with the TableView into its own view controller. Therefore I've created a second view controller in the Storyboard and created a class HintsViewTableViewController, that contains the TableView datasource and delegate methods.
Main View controller
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
var HintsViewTableVC = HintsViewTableViewController()
HintsViewTableViewController
class HintsViewTableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var HintsViewTableView: UITableView!
#IBOutlet var hintsLabel: UILabel!
override func viewDidLoad() {
hintsLabel.text = "HINT" <---fatal error: unexpectedly found nil while unwrapping an Optional value
}
// MARK: - Table view data source
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 4
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return CGFloat (40)
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
// Configure the cell...
cell.textLabel!.text = "\(indexPath.row)"
return cell
}
}
Problem
If the storyboard entry point is the Main View Controller, the compiler gives an error stating that my property hintsLabel! is nil and crashes.
If I move the storyboard entry point directly to the HintsViewTableViewController, then the app runs and shows the correct view on screen.
Question
Apparently, the procedure to initialize a view controller directly (using the storyboard entry point) is different from assigning the view controller to a variable (as I do in the first case). I've searched high and low for init methods, but have come up blank.
Another solution I've tried: making a separate XIB file and linking this to my HintsViewTableViewController, however TableViews in XIB files can't have prototype cells.
What am I missing here, or stated differently: what's the correct procedure to separate a UIView into a separate view controller (in the same Storyboard)?
The problem is that when you instantiate your HintsViewTableViewController like this:
var HintsViewTableVC = HintsViewTableViewController()
you are creating an instance of the class, BUT that class knows nothing about your Storyboard, so all of the #IBOutlets will be nil because they aren't wired to anything.
Instead, you need to ask the Storyboard to create the ViewController:
self.storyboard?.instantiateViewControllerWithIdentifier("hintsController") as! HintsViewTableViewController
where hintsController is the Storyboard ID you have set for that ViewController in the Identity Inspector.
Note: You will need to make this call to the Storyboard in a method (such as viewDidLoad where self will refer to an instance of your ViewController class.
If you want to declare it as a property like you were doing before, making it a lazy property will allow it to be created when first accessed (and self will be available then):
lazy var hintsViewTableVC: HintsViewTableViewController = { self.storyboard?.instantiateViewControllerWithIdentifier("hintsController") as! HintsViewTableViewController }()
I am trying to create a custom cell for my tableView. I believe I followed all the correct steps but when I try to write code to access my custom properties from cellForRowAtIndexPath, I get the aforementioned error. It is as if it the custom properties cannot be seen.
Custom cell:
class MapViewTableViewCell: UITableViewCell {
#IBOutlet weak var nameLabel: UILabel!
#IBOutlet weak var distanceLabel: UILabel!
#IBOutlet weak var accessibleImage: UIImageView!
TableView:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("Cell") as MapViewTableViewCell
cell.nameLabel.text = items[indexPath.row]
I verified that the custom cell objects in the storyboard are connected to the MapViewTableViewCell outlets. I also verified that the custom cell in the storyboard has its class set as MapViewTableViewCell.
I am using XCode 6.1.1
I was wondering if anyone could shed some insight as to what might be going wrong?
Thanks in advance.
With this line
var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("Cell") as MapViewTableViewCell
you are forcing the cell to be of type UITableViewCell which indeed does not have a member nameLabel. Change this line to
var cell = self.tableView.dequeueReusableCellWithIdentifier("Cell") as MapViewTableViewCell