Custom UITableViewCell on Swift - ios

I need to create a custom UITableViewCell,
I have created a class inside of a ViewController class.
I have written the code below;
class FavoritesCell: UITableViewCell
{
var timeLabel:UILabel?
override init(style: UITableViewCellStyle, reuseIdentifier: String!) {
super.init(style: UITableViewCellStyle.Value1, reuseIdentifier: reuseIdentifier)
timeLabel = UILabel(frame: CGRectMake(250, 10, 70, 20))
//how to add this time label as a subview of FavoritesCell
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
As i mentioned in commented line, how to add timeLabel to UITableViewCell?
Thanks

After you've created your timeLabel, this should do it:
self.contentView.addSubview(timeLabel!)
This adds the timeLabel to the cell's contentView rather than the cell itself, but that's generally what you do in table view cells.
Other things to note:
It's fine to use self here - after your super.init call, the object is fully initialised.
You've just created the timeLabel, so it's safe to force-unwrap it in addSubview.

As UITableViewCell class is derived from the UIView, so you can use the same method - self.addSubview(timeLabel!).

Related

How to render #IBDesignable UITableViewCell in Storyboard?

I create a UITableViewCell subclass CustomTableViewCell and mark it as #IBDesignable. In CustomTableViewCell.xib file I drag a label to its center, then setup an #IBOutlet and name this label as contentLabel. Next, I drag a TableViewCell and put it on a ViewController's table view in the storyboard file, and change its class to CustomTableViewCell. My question is: how to render this contentLabel in the storyboard?
The following snippet doesn't work and I believe it's because contentLabel is not initialized yet in init(), but I want to give it an initial text and render it in the storyboard. How to achieve this?
#IBDesignable class CustomTableViewCell: UITableViewCell {
#IBOutlet weak var contentLabel: UILabel!
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentLabel.text = "Hello"
}
required init?(coder: NSCoder) {
super.init(coder: coder)
contentLabel.text = "Hello"
}
}
EDIT: This cell needs to reused in several different view controllers.

How to initialize a programmatic UITableViewCell with a property via dependency injection?

I've looked around and I can't find any examples of this. I simply want to create a custom initializer on a programmatic UITableViewCell subclass that includes one property.
class CustomCell: UITableViewCell {
var foo: Foo
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// custom init with a foo
}
What I want is:
let cell = CustomCell(foo: myFoo) // other default init params if needed
Not:
let cell = CustomCell()
cell.foo = myFoo
Pointing me to a resource (if I missed one) that shows an implementation like this would be great. I assume this is a common need, but a couple hours being yelled at by init compiler errors and a few Medium articles later and I can't find anything.
Instances of UITableViewCell are created by the system, using the classic init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) initializer.
Don't forget to add this magic line after initializing your UITableView:
myTableView.register(CustomCell.self, forCellReuseIdentifier: Constant.myCellReuseIdentifier)
Let's say you write this:
class CustomCell: UITableViewCell {
convenience init(reuseIdentifier: String, customObject: Any?) {
self.init(style: UITableViewCell.CellStyle.default, reuseIdentifier: reuseIdentifier)
}
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Then you can create a cell with this line of code:
let cell = CustomCell(reuseIdentifier: Constant.myReuseIdentifier, customObject: nil)
... but what will you do with this cell? How to plug it into your "tableview's cells management" logic.
To inject something to your cell, you may plug in:
tableView(_:cellForRowAt:) for a UITableView (in the object implementing UITableViewDataSource)
collectionView(_:cellForItemAt:) or collectionView:willDisplayCell:forItemAtIndexPath: for a UICollectionView.
Those 3 methods may be call very frequently by the system, avoid memory allocations or any memory / CPU intensive task when possible.

Adding UILabel to a custom tableViewCell programmatically

I'm trying to add a label programmatically to a custom table view cell. The app will still crash with an 'unexpectedly found nil'. I've looked into other posts here but I can't see what I'm doing wrong. Please see the code for details.
import UIKit
class MyTableViewCell: UITableViewCell {
var titleLabel: UILabel!
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
titleLabel = UILabel()
titleLabel.textColor = UIColor.blackColor()
titleLabel.font = UIFont.systemFontOfSize(17)
titleLabel.frame = CGRect(x: 40.0, y: 2, width: bounds.width, height: bounds.height)
addSubview(titleLabel)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
Inside the view controller:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("CustomCell", forIndexPath: indexPath) as! MyTableViewCell
// Crashes the app with: 'fatal error: unexpectedly found nil while unwrapping an Optional value'
cell.titleLabel.text = "Some text"
}
The custom table view class is properly assigned to the prototype cell in the storyboard.
If I change the declaration inside MyTableViewCell to var titleLabel = UILabel() and delete that line from inside the init() the table view will display but my label will not show up.
The code looks good to me though, any advice as to what I may be missing here?
You made custom cell in storyboard,so you don't need to register class for table view.And views from storyboard will call initWithCoder and awakeFromNib,please add label in these two functions.

iOS UITableViewCell with custom accessoryView in InterfaceBuilder

I'm creating a settings page for my Swift app and (following examples here on SO) I've subclassed a UITableViewCell and in the init() handlers I've set the accessoryView to be a UISwitch().
I also have a custom #IBInspectable property on the subclass which is also marked #IBDesignable:
#IBDesignable class TableViewSwitchCell: UITableViewCell {
#IBInspectable var settingsKey: String?
func build()
{
accessoryView = UISwitch()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
build()
}
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
build()
}
// code omitted that uses the settingsKey with NSUserDefaults
}
How can I arrange for the UISwitch to also be visible in InterfaceBuilder so that I can attach additional targets to it whilst still just subclassing from UITableViewCell
Ideally I don't want to create a whole new nib with its own layout, since I still want to retain most of the other features of a standard UITableViewCell.
Drop UISwitch in Interface Builder inside of cell. Then wire it with up accessoryView of your cell. On standard basic cells the control tends to be locked in the middle of cell in IB. However in runtime it will be properly positioned.

IBDesignable never finishes updating UITableViewCell in storyboard

This is a similar question to this but not quite the same.
I have created a subclass of UITableViewCell which references a custom nib and marked it as #IBDesignable. Changes that are made both in code and from the .xib file display correctly in the simulator and on a device but not in the storyboard.
import UIKit
#IBDesignable class TextFieldTableViewCell: UITableViewCell {
var view: UIView!
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setup()
}
func setup() {
view = loadViewFromNib()
view.frame = bounds
view.autoresizingMask = [UIViewAutoresizing.FlexibleWidth, UIViewAutoresizing.FlexibleHeight]
contentView.addSubview(view)
}
func loadViewFromNib() -> UIView {
let bundle = NSBundle(forClass: self.dynamicType)
let nib = UINib(nibName: "TextFieldTableView", bundle: bundle)
let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView
return view
}
}
The storyboard displays a permanent "Designables Updating".
Breaking the problem down into a less complex test of only subclassing a UITableViewCell and marking it as #IBDesignable results in the same permanent "Designables Updating".
import UIKit
#IBDesignable class TextFieldTableViewCell: UITableViewCell {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
}
Has anyone had success with creating a #IBDesignable UITableViewCell subclass? This is happening in Xcode 7 beta 6 and beta 5.
This issue has been resolved as of Xcode 9.
I had reported this issue to Apple and at least have the piece of mind knowing that this is a known bug. It is currently an open issue under the problem ID 17973876.
Edit: As of 12/7/2016 this bug is still marked as open.
I was having similar problems. This thread helped me understand the issue: Is there a way for Interface Builder to render IBDesignable views which don't override drawRect:
I got it to work by adding
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
layoutSubviews()
}
as far as i understand after reading the above stack link, IBDesignable loads the nib in storyboard not from nib or from coder but from the init with frame. Not too sure but I think init with style is doing a similar thing.
It seems that the "Updating" bug is happening only when the cell is inside a storyboard. Everything works OK when you create special .xib file just for the cell.
Hopefully, they will fix it soon.

Resources