Send different nibs in a function swift 3 - swift

I have a tableView who need to contain two different view, the name of the first one is CustomTableViewCell the second one is CustomDeliveryTableViewCell
I want my variable to take the two cell, I don't understand this error.
Here my function
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
var cell: UITableViewCell
cell = Bundle.main.loadNibNamed("CustomTableViewCell", owner: self, options: nil)?.first as! UITableViewCell
if (!self.appReady)
{
return cell
}
let arrayOfCard = self.selectedCard(section: indexPath.section, row: indexPath.row)
let json:JSON = JSON(arrayOfCard)
if (json[0]["cards"][indexPath.row]["category"] == "delivery")
{
cell = Bundle.main.loadNibNamed("CustomDeliveryTableViewCell", owner: self, options: nil)?.first as! CustomTableViewCell
}
cell = fillCell(cell: cell, json: json, index: indexPath.row)
return cell
}
My fonction fillCell is prototype like that
func fillCell(cell: CustomTableViewCell, json:JSON, index:Int) ->
CustomTableViewCell
Edit
Here the code of actual fillCell function
func fillCell(cell: UITableViewCell, json:JSON, index:Int) -> UITableViewCell {
if (json[0]["cards"][index]["category"] == "train")
{
if let type = json[0]["cards"][index]["category"] as JSON?
{
cell.labelType.text = type.string
}
if let departureStation = json[0]["cards"][index]["train"]["departure"]["station"] as JSON?
{
cell.labelDepartureStation.text = departureStation.string
}
// Do some code
}
else if (json[0]["cards"][index]["category"] == "delivery")
{
//Do some code
return cell
}
else{
//Do some code
return cell
}
}

Your initial assignment creates a cell of type CustomDeliveryTableViewCell.
Within the if block you're trying to assign a CustomTableViewCell to the same variable. This will only work if CustomTableViewCell is a subclass of CustomDeliveryTableViewCell
When you call fillCell( it's expecting CustomTableViewCell, but cell is a CustomDeliveryTableViewCell
If you declare var cell: UITableViewCell then you can assign either type to it.

Related

Custom cell did select not call delegate

I have a custom cell named PendingHistoryCell. When did select i get my stake and by indexpath.row value of the id
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let userStakes = self.userStakes
let better_bet_status = userStakes[indexPath.row].bet_status
let deletedOddId = userStakes[indexPath.row]._id
if better_bet_status == "PENDING" {
delegate?.deleteBet(oddId: deletedOddId!)
} else{
}
}
and the protocol is PendingHistoryCell
protocol PendingHistoryCellDelegate {
func deleteBet(oddId: String)
}
And in MyBetsViewContoller i configure the cell
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
if(indexPath.row == 0){
//do some
} else {
let cell: PendingHistoryCell = tableView.dequeueReusableCell(withIdentifier: CellId.MyBets.pendingHistoryCell, for: indexPath) as! PendingHistoryCell
let match = isOnPendingTab ? pendingMatches[indexPath.row-1] : claimedMatches[indexPath.row-1]
//let matchAllData = self.matchData
let userStake = (self.matchData?.bets[indexPath.row-1].stakes)!
//self.fixture = self.matchData?.bets[indexPath.row - 1].fixture
if(self.matchData?.bets[indexPath.row - 1].fixture != nil){
self.fixture = self.matchData?.bets[indexPath.row - 1].fixture!
}
//cell.configure(match: match, isPending: isOnPendingTab, betCount: self.betCount, matchData: matchAllData!, stakes: userStake, fixture:fixture! )
cell.configure(match: match,isPending: isOnPendingTab, betCount: self.betCount, stakes: userStake, fixture: fixture!)
// func configure( isPending: Bool, betCount: Int, stakes:[BT_Stake], fixture: BT_Fixture ) {
return cell
}
}
and in my BetsViewController i called
extension MyBetsViewController: PendingHistoryCellDelegate {
func deleteBet(oddId: String) {
//do some()
}
}
but delegates method does not call.
As others have commented, you need to add the delegate to your tableview cell. To do this, your cell needs the following (in your cell class) :
weak var delegate: PendingHistoryCellDelegate?
To be declared weak (and avoid potential memory leaks), your protocol needs to add : class to its declaration:
protocol PendingHistoryCellDelegate: class {
You can then assign the delegate to your tableview cell in the cellForRow method:
cell.delegate = self
Let me know how you get on!

TableView Data Not Reloading Swift

I am working on restaurant app where i need to get all restaurant type..i successfully get all data but tableview not reloading..
var arrSubMenu = [ResataurantType]()
//TableView Datasource And Delegate Method
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print(arrSubMenu.count)
return arrSubMenu.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: leftMenuTableViewCell =
tableView.dequeueReusableCell(withIdentifier: "tableCell") as!
leftMenuTableViewCell
cell.name.text = self.arrSubMenu[indexPath.row].type
return cell
}
func getRestaurantType() {
let manager = AFHTTPSessionManager()
manager.requestSerializer = AFJSONRequestSerializer()
manager.get(RESTAURANTTYPE, parameters: nil, progress: nil, success: {
(operation, responseObj) in
if let objDic = responseObj as? [String:Any] {
if let objArray = objDic["RESTAURANT_TYPE"] as? NSArray {
for objType in objArray {
let ObjRestaurant = ResataurantType()
if let objString = objType as? String {
ObjRestaurant.type = objString
}
self.arrSubMenu.append(ObjRestaurant)
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
}) { (operation, error) in
print(error)
}
}
I call this function in ViewDidLoad() but still i can't polulate tableview with record
-These can be possible reason from my person experience
TableView's dataSource don't set to self.
-Verification :- Break point on tableView Data Source & Delegate methods.
your arrSubMenu array don't contain the single value.
-Verification:- Break point & print the arrSubMenu before reloading the tableView.
You have just to enter:
First a IBOutlet:
#IBOutlet var tableView : UITableView
In viewDidLoad:
tableView.dataSource = self //OR connection between tableView in storyboard and tableView in swift class
When are you calling getRestaurantType() ? Could it be that it is called before the tableview's datasource is assigned ? That could make the tableview appear empty although the underlying data is present. And, unless you call reloadData() at some other point in the program, it will not refresh itself.
Replace below at cell for row at index method
let cell =
tableView.dequeueReusableCell(withIdentifier: "tableCell" ,for: indexPath)as!
leftMenuTableViewCellenter

Get indexPath in UITableViewCell subclass

I have a subclass of UITableViewCell that is shown in a TableView. Each cell has a text field. When the textFieldDidEndEditing func is called, I want to save the entered text as an attribute of an NSManagedObject in my Managed Object Context.
This function is implemented in my tableViewCell class:
func textFieldDidEndEditing(textField: UITextField) {
let viewController = ViewController()
let indexPath: NSIndexPath!
viewController.updateCommitsInMOC(self, atIndexPath: indexPath!)
}
And this is the function it calls. This function is implemented in my ViewController class, the one that controls the TableView which is made up of the tableViewCells:
func updateCommitsInMOC(cell: CommitTableViewCell, atIndexPath indexPath: NSIndexPath) {
// Fetch Commit
let commit = fetchedResultsController.objectAtIndexPath(indexPath) as! Commit
// Update Cell
commit.contents = cell.commitContents.text!
if cell.repeatStatus.selectedSegmentIndex == 1 { commit.repeatStatus = true }
saveManagedObjectContext()
}
I'm of course open to any suggestions as to other ways to implement the saving behavior every time the user is done editing the text field.
Is your question "How do I get the IndexPath"? Instead of the UITableviewCell trying to figure out what it's indexPath is in textFieldDidEndEditing, why don't you just figure it out within updateCommitsInMOC function?
Assuming you have a reference to your tableView you can just do this
func updateCommitsInMOC(cell: CommitTableViewCell) {
guard let indexPath = tableView.indexPathForCell(cell) else {
return
}
// Fetch Commit
let commit = fetchedResultsController.objectAtIndexPath(indexPath) as! Commit
// Update Cell
commit.contents = cell.commitContents.text!
if cell.repeatStatus.selectedSegmentIndex == 1 { commit.repeatStatus = true }
saveManagedObjectContext()
}
You can add a tag as row in cell textField.
like this:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("idCell")
cell.textField.tag = indexPath.row
return cell
}
and the textField delegate:
func textFieldDidEndEditing(textField: UITextField) {
let viewController = ViewController()
let indexPath = NSIndexPath(forRow: textField.tag, section: 0)
viewController.updateCommitsInMOC(self, atIndexPath: indexPath!)
}
or you can use the superview:
func textFieldDidEndEditing(textField: UITextField) {
let view = textField.superview!
let cell = view.superview as! UITableViewCell
let viewController = ViewController()
let indexPath = itemTable.indexPathForCell(cell)
viewController.updateCommitsInMOC(self, atIndexPath: indexPath!)
}
I suggest you to use in your tableview the
setEditing(editing, animated: animated) method.
Then inside of it you can manage the single object retrieving it from the fetchResultController.indexPathForObject(inputObject) or as you used fetchedResultsController.objectAtIndexPath(indexPath).
Finally you can use self.managedObjectContext.saveToPersistentStore() or self.managedObjectContext.save().

Reload UITableView has UITableViewCell visibility issue

I have a UITableView with two row. First row have the UITextField and second row have the UICollectionView. On reloading the UITableView, cell of UICollectionViewCell does not appear.But on scrolling the UITableView all cell of UICollectionView becomes visible. What wrong I might be doing.
if indexPath.row == 0 {
let cellIdentifier = "NewPostCell"
var cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as? NewPostCell
if (cell == nil) {
cell = Utils.getCellForGivenIdentifier(cellIdentifier, cellIdentifier: cellIdentifier, ownerT: self) as? NewPostCell
}
cell?.txtPost.delegate = self
cell?.txtPost.text = userThoughts
newPostCell = cell
return cell!
} else {
let cellIdentifier = "ASAttachmentCell"
var cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as? ASAttachmentCell
if (cell == nil) {
cell = Utils.getCellForGivenIdentifier(cellIdentifier, cellIdentifier: cellIdentifier, ownerT: self) as? ASAttachmentCell
}
if let height = cell?.collectionAttachment?.contentSize.height
{
cell?.cntCollectionHeight.constant = height
}
attachmentCell = cell
return cell!
}
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if indexPath.row == 1 {
attachmentCell = cell as? ASAttachmentCell
attachmentCell?.attachmentCollection(self)
}
}
Try to put in your code, exactly to the part where you set the collection view datasource also a :
collectionView.reloadData()
This is most likely because you are calling tableView.reloadData() on a background thread. Therefore, when you actually begin to scroll, the UI will get updated on the main thread and everything will look normal. Try calling the reloading on the main thread.
dispatch_async(dispatch_get_main_queue()){
self.tableView.reloadData()
}

Error: Variable with getter/setter cannot have an initial value

How do I fix this error?
Variable with getter/setter cannot have an initial value
Here's my code:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell: UITableViewCell = tableview.dequeueReusableCellWithIdentifier("cell") as UITableViewCell { //Error
cell.textLabel?.text = self.items[indexPath.row] //Error
return cell; //Error
}
}
I think you have an extra set of {} As it is, you're defining a block and assigning it to the cell variable:
var cell: UITableViewCell = tableview.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
cell.textLabel?.text = self.items[indexPath.row] //Error
return cell; //Error
And, since dequeueReusableCell... returns a UITableViewCell already, all you really need is:
var cell = tableview.dequeueReusableCellWithIdentifier("cell")
My guess is you cut/copied code that started out looking like:
if let cell = tableview.dequeueReusableCellWithIdentifier("cell") as? MyCellClass {
// some setup code here
return cell
}