How can I use a custom initializer on a UITableViewCell?
If you use dequeueReusableCell
you cannot change which initializer method that is called. But you can write your own method to update the IBOutlets which you then call after you successfully dequeue a cell.
class ReflectionCell: UITableViewCell {
@IBOutlet weak var header: UILabel!
@IBOutlet weak var content: UILabel!
@IBOutlet weak var author: UILabel!
func update(for reflection: Reflection) {
header.text = reflection.title
content.text = reflection.content
author.text = reflection.author.name
}
}
And
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "identifier", for: indexPath) as! ReflectionCell
cell.update(for: reflections[indexPath.row])
return cell
}
Working around not having a custom init method when using a custom UITableViewCell
The behavior you're trying to achieve is not actually a good design because UITableViewCell
s are reused. So you shouldn't rely on configuring they appearance in the init
method. For instance, you can instantiate a cell passing Integer
style and later, if you set the cell to have a different style, you will have an inconsistent state (since what you will be seeing won't reflect what you set). That being said, you should consider using a more reactive approach, where your cell behaves according to what is set, whenever is set. In your case, you might want to take a look in didSet
property observer. You'd have something like bellow:
public var textFieldStyle = eTextfieldStyle.Integer {
didSet {
updateAppearance()
}
}
func updateAppearance() {
switch textFieldStyle {
case .Integer:
// ...
}
}
EDIT
And in your tableView(_:cellForRowAt:)
you just need to set the proper style, as follows:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "your cell identifier goes here", for: indexPath)
// Here you obtain the proper style depending on the index path, for instance:
if indexPath.row == 0 {
cell.textFieldStyle = .Integer
} else {
cell.textFieldStyle = . MediumText
}
return cell
}
How do I set an initializer for a custom UITableViewCell class?
When you call this line:
super.init(style: UITableViewCellStyle, reuseIdentifier: String?)
you need to supply an actual cell style and an actual reuse identifier. You code at the moment is written as if this line is a function definition, not a function invocation.
Change it to something like:
super.init(style: .Default, reuseIdentifier: "SettingCell")
(though preferably at least the reuse identifier should be provided by the caller, not statically)
UITableViewCell dequeueReusableCellWithIdentifier with custom initializer
While you follow the usual pattern for cell re-usage (as you do with register class & dequeue), I do not see an easy to implement way of doing that.
If I were you I would create an additional initialization method (not following the usual init
pattern of obj-c) or simply setters and call that following the dequeueReusableCellWithIdentifier
call.
StoreLineGraphCell *cell = (StoreLineGraphCell*)[self.storeTableView dequeueReusableCellWithIdentifier:@"StoreLineGraphCellIdentifier"];
[cell furtherInitWithLocked:YES andUpcoming:NO]; // ... or so
Swift - initialize UITableViewCell
You are doing one thing very wrong there. You are setting your data directly on the cell (that var called whishText
). Think about it, the name of a wish belongs to a wish, not to a cell. A name of a person belongs to a person, not to a cell. The cell just presents/shows the name of whatever object it is given. With that in mind. You need to have a class called Wish, and implement the UITableView Data source methods. Here is the code:
Wish Cell:
class WhishCell: UITableViewCell {
public static let reuseID = "WhishCell"
required init?(coder: NSCoder) {fatalError("init(coder:) has not been implemented")}
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
backgroundColor = .systemTeal
//other common things,
}
}
WishTableViewController:
class WishTableViewController: UITableViewController {
public var wishList : [Wish]?
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.register(WhishCell.self, forCellReuseIdentifier: WhishCell.reuseID)
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return wishList?.count ?? 0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: WhishCell.reuseID, for: indexPath)
let currentWish = self.wishList![indexPath.row]
cell.textLabel?.text = currentWish.wishName
return cell
}
}
Wish Model:
class Wish: NSObject {
public var wishName : String?
init(withWishName name: String) {
super.init()
wishName = name
}
}
Usage Example:
@IBAction func showExampleWishTable(_ sender: Any) {
let wishTableView = WishTableViewController()
let wish1 = Wish(withWishName: "Bicycle")
let wish2 = Wish(withWishName: "Macbook")
let wish3 = Wish(withWishName: "Printer")
wishTableView.wishList = [wish1, wish2, wish3]
self.navigationController?.pushViewController(wishTableView, animated: true)
}
Result:
How to properly Init a custom UITableviewCell?
You can do your changes inside the DoneButtonCell
's class, either in the
- (void)awakeFromNib
{
.. essential to call super ..
super.awakeFromNib()
//Changes done directly here, we have an object
}
Or the initWithCoder:
method:
-(id)initWithCoder:(NSCoder*)aDecoder
{
self = [super initWithCoder:aDecoder];
if(self)
{
//Changes here after init'ing self
}
return self;
}
Custom UITableVIewCell initialization not called
If the cells come from a storyboard or nib file, then initWithStyle:reuseIdentifier
is not called, initWithCoder:
is called instead.
Here's a typical implementation of an overwritten initWithCoder:
:
-(id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
// Do your custom initialization here
}
return self;
}
Will not work if you need to access IBOutlet during custom initialization.
Related Topics
Apple Watch Table - First 4 Rows Not Appearing
User Notification Request Always Come with Default Action Identifier
How to Set Uitextview's Height Dynamically in Uitableviewcell Based on String Size
Embedding a Uitableview as a Container View Within a Uiviewcontroller
Uidropinteractiondelegate Performdrop Not Called
Swift Sending Data from Child View to Parent View Controller
Skspritenode Does Not Let Touches Pass Through When Isuserinteractionenabled False
How to Detect Which Annotation Was Selected in Mapview
Swift Scenekit - Centering Scntext - the Getboundingboxmin:Max Issue
How to Check If a Nstimer Is Running or Not in Swift
How to Get All Keys and Values into Separate String Arrays from Nsdictionary in Swift
How to Access Index of Tabbar Item Using Swift