Delegate didSet property of UIView not being called inside custom UITableViewCell - ios

I've been banging my head on the desk for the past 2 hours trying to figure this out so any help will be greatly appreciated.
I'm using CVCalendar (the develop branch) and I'm trying to place the CalendarView inside a custom UITableViewCell so I can make it look something like this:
The problem I'm facing is that it doesn't set the delegate property when I call self.calendarView.calendarDelegate = self inside the custom UITableViewCell
I know it's not being set because I've placed a println inside the delegate didSet property that's not being outputted.
Here is the CalendarViewDelegate outlet inside the CalendarView
// MARK: - Calendar View Delegate
#IBOutlet weak var calendarDelegate: AnyObject? {
set {
if let calendarDelegate = newValue as? Delegate {
delegate = calendarDelegate
println("delegate did set property called")
}
}
get {
return delegate
}
}
Here is my code for the custom UITableViewCell I'm working with.
import UIKit
class CalendarCell: UITableViewCell {
var calendarView: CVCalendarView!
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
}
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
backgroundColor = UIColor.redColor()
selectionStyle = .None
self.calendarView = CVCalendarView(frame: self.frame)
self.calendarView.calendarDelegate = self
self.calendarView.calendarAppearanceDelegate = self
self.calendarView.animatorDelegate = self
contentView.addSubview(calendarView)
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
self.calendarView.commitCalendarViewUpdate()
}
}
Here is my UITableViewController code:
import UIKit
class CalendarTableViewController: UITableViewController {
#IBOutlet var myTableView: UITableView!
var items = ["Apple", "Banana"];
override func viewDidLoad() {
super.viewDidLoad()
self.myTableView.registerClass(CalendarCell.self, forCellReuseIdentifier: NSStringFromClass(CalendarCell))
self.myTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")
self.myTableView.dataSource = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func creatHeaderCell() -> UITableViewCell {
var headerCell = self.myTableView.dequeueReusableCellWithIdentifier(NSStringFromClass(CalendarCell)) as! CalendarCell
return headerCell
}
// MARK: - Table view data source
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if (indexPath.section == 0) {
return 300
}
return 44
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 2
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch (section) {
case 0:
return 1
default:
return items.count
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if (indexPath.section == 0) {
return self.creatHeaderCell()
}
let cell = self.myTableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell
cell.textLabel!.text = "Thomas"
// Configure the cell...
return cell
}
}

Your println statement is probably not reached because your if condition if let calendarDelegate = newValue as? Delegate is not true because what you pass in as calenderDelegate is a CalenderCell, not a Delegate or CVCalendarViewDelegate (typealias).
Additionally your CalendarCell does not conform to CVCalendarViewAppearanceDelegate and CVCalendarViewAnimatorDelegate.
You have to make your cell conform to those protocols to be able to set them as delegates.

Related

Using custom XIB in table view cell

I have followed this tutorial to create a custom .xib, which I plan to use in a table view's cell:
https://medium.com/#brianclouser/swift-3-creating-a-custom-view-from-a-xib-ecdfe5b3a960
Here is the .xib's class I created:
class UserView: UIView {
#IBOutlet var view: UIView!
#IBOutlet weak var username: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
initialize()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
initialize()
}
private func initialize() {
Bundle.main.loadNibNamed("UserView", owner: self, options: nil)
addSubview(view)
view.frame = self.bounds
view.autoresizingMask = [.flexibleHeight, .flexibleWidth]
}
}
Previously, I was creating my table view cell within the storyboard, but I've come to realize that I want a more flexible view so that I can use it in different parts of my app, so I created the above custom .xib, UserView.
I have updated the table view cell in the storyboard to use the custom .xib:
https://i.stack.imgur.com/t7Tr7.png
Here is what my table view controller class looked like prior to creating the custom .xib (i.e. making the layout in the storyboard):
class UserTableViewController: UITableViewController {
// MARK: Properties
let provider = MoyaProvider<ApiService>()
var users = [User]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.estimatedRowHeight = 100
tableView.rowHeight = UITableViewAutomaticDimension
// Fetch the user by their username
provider.request(.getUsers()) { result in
switch result {
case let .success(response):
do {
let results = try JSONDecoder().decode(Pagination<[User]>.self, from: response.data)
self.users.append(contentsOf: results.data)
self.tableView.reloadData()
} catch {
print(error)
}
case let .failure(error):
print(error)
break
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return users.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "UserTableViewCell"
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? UserTableViewCell else {
fatalError("The dequeued cell is not an instance of UserTableViewCell.")
}
let user = users[indexPath.row]
cell.username.text = user.username
return cell
}
}
Here is the table view cell class:
class UserTableViewCell: UITableViewCell {
//MARK: Properties
#IBOutlet weak var userView: UserView!
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
}
}
My question is, how do I update the above table view controller class to use my custom .xib, instead of using the storyboard layout?
You can use 2 ways:
Create UITableViewCell (better)
1) Change UIView to UITableViewCell
class CustomTableViewCell: UITableViewCell {
...
class var identifier: String {
return String(describing: self)
}
}
2) Register your cell
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.registerNib(UINib(nibName: CustomTableViewCell.identifier, bundle: nil), forCellReuseIdentifier: CustomTableViewCell.identifier)
...
}
3) Use cellForRow(at:)
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: CustomTableViewCell.identifier) as! CustomTableViewCell
cell.username.text = user.username
return cell
}
OR Add view as subview to cell (only in rare cases)
1) Add this to UserView
class UserView: UIView {
...
class func fromNib() -> UserView {
return UINib(nibName: String(describing: self), bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! UserView
}
}
2) Use cellForRow(at:)
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "UserTableViewCell"
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? UserTableViewCell else {
fatalError("The dequeued cell is not an instance of UserTableViewCell.")
}
let userView = UserView.fromNib()
let user = users[indexPath.row]
userView.username.text = user.username
//Use frame size, but for me better to add 4 constraints
userView.frame = CGRect(x: 0, y: 0, width: cellWidth, height: cellHeight)
cell.contentView.addSubview(UserView)
return cell
}

Designing a UITableView/Cell - iOS

I'm designing a UITableView using subviews to populate the reusable cell of it, and I wish some opinion about that.
As I had tested, it works well. But, I don't know if it is a good solution.
The scenario is: I have a tableview with different kind of cells (layouts). When I was designing, it grows fast (my controller code), as I had to register a lot of cell and handle cellForRow. Then I come with that idea, to instantiate different subviews for one unique reusable cell and use a 'Presenter' to handle delegate/datasource. You think is that a problem? And is that a good approach?
Thanks in advance!
Ps.: sorry for any english error!
EDITED:
Here is the session in project followed by de codes:
Codes at:
OrderDetailCell
class OrderDetailCell: UITableViewCell {
//MARK: Outlets
#IBOutlet weak var cellHeight: NSLayoutConstraint!
#IBOutlet weak var viewContent: UIView!
//Variables
var didUpdateLayout = false
internal func setupLayoutWith(view: UIView){
cellHeight.constant = view.frame.height
viewContent.frame = view.frame
viewContent.addSubview(view)
updateConstraints()
layoutIfNeeded()
didUpdateLayout = true
}
}
OrderDetailSubview
class OrderDetailSubview: UIView {
var type: OrderDetailsSubViewType?
var height: CGFloat = 1
class func instanceFromNib(withType type: OrderDetailsSubViewType) -> OrderDetailSubview {
let view = UINib(nibName: type.rawValue, bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! OrderDetailSubview
switch type {
case .OrderDetailSubviewStatus:
view.height = 258
case .OrderDetailSubViewItem:
view.height = 129
case .OrderDetailSubViewStoreInformation:
view.height = 317
case .OrderDetailSubViewEvaluation:
view.height = 150
}
view.updateConstraints()
view.layoutIfNeeded()
return view
}
}
OrderDetailPresenter
enum OrderDetailsSubViewType: String {
case OrderDetailSubviewStatus = "OrderDetailSubviewStatus",
OrderDetailSubViewItem = "OrderDetailSubViewItem",
OrderDetailSubViewStoreInformation = "OrderDetailSubViewStoreInformation",
OrderDetailSubViewEvaluation = "OrderDetailSubViewEvaluation"
static let types = [OrderDetailSubviewStatus, OrderDetailSubViewItem, OrderDetailSubViewStoreInformation, OrderDetailSubViewEvaluation]
}
class OrderDetailPresenter {
//Constants
let numberOfSections = 4
//Variables
// var order: Order?
func setup(reusableCell: UITableViewCell, forRowInSection section: Int) -> OrderDetailCell {
let cell = reusableCell as! OrderDetailCell
for sub in cell.viewContent.subviews {
sub.removeFromSuperview()
}
let subView = OrderDetailSubview.instanceFromNib(withType: OrderDetailsSubViewType.types[section])
cell.setupLayoutWith(view: subView)
return cell
}
func numberOfRowsForSection(_ section: Int) -> Int {
switch section {
case 1:
//TODO: count de offerList
return 4
default:
return 1
}
}
}
OrderDetailViewController
class OrderDetailViewController: BaseViewController {
//MARK: Outlets
#IBOutlet weak var tableView: UITableView!
var presenter = OrderDetailPresenter()
override func setupView() {
setupTableView()
}
}
extension OrderDetailViewController: UITableViewDataSource, UITableViewDelegate {
internal func setupTableView() {
tableView.delegate = self
tableView.dataSource = self
tableView.estimatedRowHeight = 600
tableView.rowHeight = UITableViewAutomaticDimension
tableView.register(UINib(nibName: "OrderDetailCell", bundle: nil), forCellReuseIdentifier: "OrderDetailCell")
}
func numberOfSections(in tableView: UITableView) -> Int {
return presenter.numberOfSections
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return presenter.numberOfRowsForSection(section)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let reusableCell = tableView.dequeueReusableCell(withIdentifier: "OrderDetailCell") as! OrderDetailCell
let cell = presenter.setup(reusableCell: reusableCell, forRowInSection: indexPath.section)
return cell
}
}
*Sorry for indentation here...
Thats it! What you think?
Here you want to have multiple UITableViewCell subclasses that implement the different layouts that you want, and then select the relevant one in you table view data source.
class Cell1: UITableViewCell {
let label = UILabel()
override init(style: UITableViewCellStyle, reuseIdentifier: String) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.contentView.addSubview(label)
}
... whatever other setup/layout you need to do in the class ...
}
class Cell2: UITableViewCell {
let imageView = UIImageView()
override init(style: UITableViewCellStyle, reuseIdentifier: String) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.contentView.addSubview(imageView)
}
... whatever other setup/layout you need to do in the class ...
}
Then in your view controller
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(Cell1.self, forCellReuseIdentifier: "cell1Identifier")
tableView.register(Cell2.self, forCellReuseIdentifier: "cell2Identifier")
}
...
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row % 2 == 0 { // just alternating rows for example
let cell = tableView.dequeueReusableCell(withIdentifier: "cell1Identifier", for: indexPath) as! Cell1
// set data on cell
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell2Identifier", for: indexPath) as! Cell2
// set data on cell
return cell
}
}
So this is just an example, but is using two different cell subclasses for alternating rows in the table view.
let dynamicCellID: String = "dynamicCellID" //One Cell ID for resuse
class dynamicCell: UITableViewCell {
var sub: UIView // you just need to specify the subview
init(sub: UIView) {
self.sub = sub
super.init(style: .default, reuseIdentifier: dynamicCellID)
self.addSubview(sub)
self.sub.frame = CGRect(x: 0, y: 0, width: sub.frame.width, height: sub.frame.height)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
And you need to create a views array the give that view to every cell in delegate
let views: [UIView] = []
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return views.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let v = views[indexPath.row]
return dynamicCell(sub: v)
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let v = views[indexPath.row]
return v.frame.height + 10 //offset is 10 point
}

UICollectionView in UItableView Getting only empty tableview , what i have missed?

I have a requirement to use collection view in table view cell but , i am getting a bank table view cell can anybody please tell me what i am missing
![My storyboard]
contains
View,
Tableview,
TableViewCell,
Contentview,
collectionview,
collectionviewcell.
inside that
imageview and label to display the data
i have three class
1st one customcollectionview
class CustomCollectionViewCell: UICollectionViewCell {
#IBOutlet var AssetImage: UIImageView!
#IBOutlet var assetLabeldesc: UILabel!
override init(frame: CGRect)
{
super.init(frame: frame)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func awakeFromNib() {
super.awakeFromNib()
}
}
2)
class CustomTableViewCell: UITableViewCell,UICollectionViewDataSource,UICollectionViewDelegate {
#IBOutlet var AssetCollectionView: UICollectionView!
override init(frame: CGRect) {
super.init(frame: frame)
}
required init(coder aDecoder: NSCoder) {
// fatalError("init(coder:) has not been implemented")
super.init(coder: aDecoder)
}
var folderCount:Int?
{
didSet(value)
{
}
}
override func awakeFromNib() {
super.awakeFromNib()
var aFlowLayout : UICollectionViewFlowLayout = UICollectionViewFlowLayout()
aFlowLayout.scrollDirection = UICollectionViewScrollDirection.Horizontal
aFlowLayout.itemSize = CGSizeMake(60.0, 90.0)
aFlowLayout.minimumLineSpacing = 10.0
aFlowLayout.minimumInteritemSpacing = 0.0
aFlowLayout.sectionInset = UIEdgeInsetsMake(2, 9, 0, 10)
AssetCollectionView.collectionViewLayout = aFlowLayout
AssetCollectionView.registerClass(CustomCollectionViewCell.self, forCellWithReuseIdentifier: "CollectionViewCell")
var cNib:UINib? = UINib(nibName: "CustomCollectionViewCell", bundle: nil)
AssetCollectionView.registerNib(cNib, forCellWithReuseIdentifier: "CollectionViewCell")
AssetCollectionView.frame = self.bounds
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
class func CreateCustomCell() -> CustomTableViewCell
{
var nibElements: Array = NSBundle.mainBundle().loadNibNamed("CustomTableViewCell", owner: self, options: nil)
var item: AnyObject?
for item in nibElements
{
if item is UITableViewCell
{
return item as CustomTableViewCell
}
}
return item as CustomTableViewCell
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
{
var cell :CustomCollectionViewCell? = collectionView.dequeueReusableCellWithReuseIdentifier("CollectionViewCell", forIndexPath: indexPath) as? CustomCollectionViewCell
//hear u can modify which image to be displayed in the collection view cell
let imageNameString = "Logo.png"
let front = UIImage(named: imageNameString)
cell?.AssetImage.backgroundColor = UIColor.orangeColor()
cell?.AssetImage.image = front
cell?.assetLabeldesc.text = "Card:\(indexPath.row)"
return cell!
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return folderCount!
}
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
3)
class AssetViewController: UIViewController,UITableViewDataSource,UITableViewDelegate
{
var cardCountArray:[Int] = []
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
cardCountArray = [5,15,6,12,7,10]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
return cardCountArray.count
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return 1
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
var cell:CustomTableViewCell? = tableView.dequeueReusableCellWithIdentifier("CELL") as? CustomTableViewCell;
if(cell == nil)
{
cell = CustomTableViewCell.CreateCustomCell()
}
cell?.folderCount = cardCountArray[indexPath.section]
cell?.AssetCollectionView.reloadData()
cell?.clipsToBounds = true
return cell!;
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{
return 100.0
}
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
var headerView:UIView = UIView(frame: CGRectMake(0, 0, tableView.bounds.size.width, 70.0))
var labelTitle:UILabel = UILabel(frame: CGRectMake(0, 0, tableView.bounds.size.width, 35))
var descriptionTitle:UILabel = UILabel(frame: CGRectMake(0, 20,tableView.bounds.size.width , 30))
headerView.addSubview(labelTitle)
headerView.addSubview(descriptionTitle)
labelTitle.text = "GroupName:\(section)"
descriptionTitle.text = "Description \(cardCountArray[section])"
return headerView
}
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50.0
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}``
*/
}
Can anybody tell me what am missing?
It appears you are adding the subview for some elements but not for your collectionView:
I see the views added for the labels:
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
headerView.addSubview(labelTitle)
headerView.addSubview(descriptionTitle)
You will need to add the collection view as well. You can do it here so it is added to every cell:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:CustomTableViewCell? = tableView.dequeueReusableCellWithIdentifier("CELL") as? CustomTableViewCell;
I approached this without using addSubview on another project. In my case I initiated the
collectionView.datasource = self
collectionView.delegate = self
I posted a similar question recently and someone responded with an approach that may help you. UICollectionView cells with Images inside UITableView prototype

Swift Custom UITableViewCell Programmatically works and shows in cell but Storyboard IBOutlet is nil and does not show in cell

In my custom cell swift file CustomTableView.swift, I can create programmatically the labels for my TableView but when I use IBOutlet in Storyboard the label becomes always nil
I am very sure that my cell is not nil
import UIKit
class CustomTableViewCell: UITableViewCell {
#IBOutlet weak var lblPostDate: UILabel!
var message: UILabel = UILabel()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.message.frame = CGRectMake(0, 0, 100, 40);
self.message.backgroundColor = UIColor.brownColor()
self.message.text = "bla bla bla bla bla"
self.addSubview(self.message)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
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
}
func setCell(postDate: String)
{
self.lblPostDate?.text = postDate
}
}
In the above code, the message can be seen in the cells but lblPostDate which is the IBOutlet can not be seen
I am sure about the delegate and datasource and custom cell identifier what so ever but it seems that the IBOutlets don't get initialized correctly. I can see that lblPostDate becomes nil when I debug
Is this a bug of XCode 6?
Here is how I call from my Controller
import UIKit
class HomeViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
var items = ["one","two","three","four"]
let kCellIdentifier: String = "CustomCell"
#IBOutlet weak var mTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.mTableView.registerClass(CustomTableViewCell.classForCoder(), forCellReuseIdentifier:kCellIdentifier)
//self.mTableView.registerClass(CustomTableViewCell.self, forCellReuseIdentifier: kCellIdentifier)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:CustomTableViewCell! = tableView.dequeueReusableCellWithIdentifier(kCellIdentifier, forIndexPath: indexPath) as? CustomTableViewCell
if (cell == nil) {
self.mTableView.registerClass(CustomTableViewCell.classForCoder(), forCellReuseIdentifier: kCellIdentifier)
cell = CustomTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: kCellIdentifier)
}
if var label = cell.lblPostDate{
label.text = items[indexPath.row]
}
else{
cell.setCell(items[indexPath.row])
}
return cell
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 44
}
}
You have to link the lblPostDate with one label in your cell xib file.
That is insane, I deleted the register class code and it worked, I can't believe it
//self.mTableView.registerClass(CustomTableViewCell.classForCoder(), forCellReuseIdentifier:kCellIdentifier)
After commenting out the registerClass in my Controller, it doesn't call anymore the init function but creates the lblPostDate correctly indeed
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.message.frame = CGRectMake(0, 0, 100, 40);
self.message.backgroundColor = UIColor.brownColor()
self.message.text = "bla bla bla bla bla"
self.addSubview(self.message)
}
So I don't need anymore to create hard-code input objects.
It is interesting that all the tutorials, everywhere they suggest to register the class. Anyway,it worked!

swift custom uitextviewcell label always nil

i'm stuck here since two days ago, and cant find how to manage this..
I have an uitableview, with an array of custom cells and sections, here's what i want to do:
Section 1: just a row with a label inside
Section 2: a datepicker (i used DVDatePickerTableViewCell class for this)
here's the code for the table view
import UIKit
class DettagliRichiestaTVC: UITableViewController {
//sections contiene le sezioni
let sections: NSArray = ["Stato", "Data", "Priorità", "Richiesta", "Risposta"]
//cells contiene tutte le righe della tabella, un 2D array
var cells:NSArray = []
var stato:String = "Completato"
#IBOutlet weak var statoLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// statoLabel.text = stato
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 44
// Cells is a 2D array containing sections and rows.
var cellStato = cellDettagli(style: UITableViewCellStyle.Default, reuseIdentifier: "cellStato")
cellStato.label?.text = "Ciao"
cells = [
[cellStato],
[DVDatePickerTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: nil)]
]
// 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()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func selectedStato(segue:UIStoryboardSegue) {
let statoRichiesteTVC = segue.sourceViewController as StatoRichiesteTVC
if let selectedStato = statoRichiesteTVC.selectedStato {
statoLabel.text = selectedStato
stato = selectedStato
}
self.navigationController?.popViewControllerAnimated(true)
}
// MARK: - Table view data source
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
var headerFrame:CGRect = tableView.frame
var title = UILabel(frame: CGRectMake(10, 10, 100, 20))
title.font = UIFont.boldSystemFontOfSize(12.0)
title.text = self.sections.objectAtIndex(section) as? String
title.textColor = UIColor(red: 0.6, green: 0.6, blue: 0.6, alpha: 1)
var headerView:UIView = UIView(frame: CGRectMake(0, 0, headerFrame.size.width, headerFrame.size.height))
headerView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0.8)
headerView.addSubview(title)
return headerView
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
var cell = self.tableView(tableView, cellForRowAtIndexPath: indexPath)
if (cell.isKindOfClass(DVDatePickerTableViewCell)) {
return (cell as DVDatePickerTableViewCell).datePickerHeight()
}
return super.tableView(tableView, heightForRowAtIndexPath: indexPath)
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return cells.count
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cells[section].count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
return cells[indexPath.section][indexPath.row] as UITableViewCell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var cell = self.tableView(tableView, cellForRowAtIndexPath: indexPath)
if (cell.isKindOfClass(DVDatePickerTableViewCell)) {
var datePickerTableViewCell = cell as DVDatePickerTableViewCell
datePickerTableViewCell.selectedInTableView(tableView)
}
self.tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
//println(segue.identifier)
if segue.identifier == "SavePlayerDetail" {
}
if segue.identifier == "SelezionaStatoRichiesta" {
let statoRichiesteTVC = segue.destinationViewController as StatoRichiesteTVC
statoRichiesteTVC.selectedStato = stato
}
}
}
and here's the custom cell class
import UIKit
class cellDettagli: UITableViewCell {
#IBOutlet weak var label: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
func loadItem(#Label: String) {
label.text = Label
}
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init(coder aDecoder: NSCoder) {
//fatalError("init(coder:) has not been implemented")
super.init(coder: aDecoder)
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
if i set cellStato.label?.text = "Ciao" , it crashes saying "fatal error: unexpectedly found nil while unwrapping an Optional value" .
I created also the .xib file and assigned that to cellDettagli class.
I always get that error.
How can i set the values of this label, and the date of the datepicker row?
Thank you
I made it work using this:
var cell:cellDettagli? = tableView.dequeueReusableCellWithIdentifier("cellDettagli") as? cellDettagli
if (cell==nil){
var nib:NSArray=NSBundle.mainBundle().loadNibNamed("cellDettagli", owner: self, options: nil)
cell = nib.objectAtIndex(0) as? cellDettagli
}
inside my cellForRowAtIndexPath.
Thank you Alexander for your help! I already use static cells and storyboards...!
You're creating cells using the designated initialiser, which means the views that you've added in the nib won't be there at runtime. You will need to register your nib with the tableview first using registerNib:forCellReuseIdentifier:, then dequeue cells accordingly using dequeueReusableCellWithIdentifier:forIndexPath:.
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableView_Class/index.html
Since it looks like you're using static cells, you might be better off using a storyboard with "Static Cells" content type on your table view instead of "Dynamic Prototypes".
For more information on static cells, see the docs https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TableView_iPhone/CreateConfigureTableView/CreateConfigureTableView.html

Resources