Setting delegate for UITextField produces error - ios

I have a table view with prototype cells and a custom table view cell class. In one of the prototype cells I have a UITextField. I'm trying to dismiss the keyboard when the return key is pressed, to do that I'm using the function textFieldShouldReturn and am trying to set the delegate of my UITextView to self(inputText.delegate = self). Unfortunately, without setting the delegate to self results in nothing happening when return is pressed, and with the inputText.delegate = self line the app crashes with the error fatal error: unexpectedly found nil while unwrapping an Optional value.
Here is my custom table view cell file.
import UIKit
class CustomTableViewCell: UITableViewCell, UITextFieldDelegate {
#IBOutlet weak var inputLabel: UILabel!
#IBOutlet weak var inputText: UITextField!
#IBOutlet weak var labelLabel: UILabel!
#IBOutlet weak var labelDetail: UILabel!
#IBOutlet weak var picker: UIPickerView!
#IBOutlet weak var largeInputText: UITextField!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
inputText.delegate = self
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
print("return button in CustomTableViewCell")
inputText.resignFirstResponder()
return true
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
Any help would be greatly appreciated.

There could one of these reasons because of which you are getting this error.
You might not have specified the class of your prototype cell in interface builder. See below
You might not have correctly set the IBOutlet property. Check this in last tab on the side bar shown above after clicking on the label in your prototype cell.
NOTE: Make sure that you have set the custom class for your table view controller or view controller as well.

tryn to call awakeFromNib() from viewDidLoad() ; and then you can select what type of keyboard need for edit : inputTextFile.keyboardType = UIKeyboardType.ASCIICapable/EmailAddress/etc

Related

Swift how to update a subview's label and imageview using a button in a tableview cell

I want to update a subview's label text and image view photo in my storyboard when I click on a button in my TableCell. I have tried using tableView didSelectRowAt but it only works when I highlight the cell not when I use a the tableviewcell's button.
Here you can see a video of my issue.
https://www.loom.com/share/1f147a67bea548b192b654ceb78722c9
Below here you can see my code used to update the subview using didSelectRowAt
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
EditViewDescriptionLabel.text = userPostDescription[indexPath.row]
EditPostImageView.sd_setImage(with: URL(string: userPostImageArray[indexPath.row]))
}
Is there a way to update my subview by clicking on the gear icon instead?
Below is my FeedViewCell Code
//
// FeedCell.swift
// VidaClock
//
// Created by Irving Gonzalez on 5/30/20.
// Copyright © 2020 Viva La App. All rights reserved.
//
import UIKit
protocol EditPostDelegate {
func gearButtonPressed(_ sender: Any)
}
class FeedCell: UITableViewCell {
#IBOutlet weak var FeedCellUserNameLabel: UILabel!
#IBOutlet weak var userProfilePhotoFeedCellLabel: UIImageView!
#IBOutlet weak var dateFeedCellLabel: UILabel!
#IBOutlet weak var postImageFeedCellLabel: UIImageView!
#IBOutlet weak var likeCountFeedCellLabel: UILabel!
#IBOutlet weak var postDescriptionLabel: UILabel!
#IBOutlet weak var documentIDLabel: UILabel!
#IBOutlet weak var FeedViewGearButtonOutlet: UIButton!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func layoutSubviews() {
super.layoutSubviews()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
#IBAction func likeButtonClicked(_ sender: Any) {
}
var delegate1: EditPostDelegate?
#IBAction func postGearButtonPressed(_ sender: Any) {
print("postGearButtonPressed")
delegate1?.gearButtonPressed(AnyObject.self)
}
}
You need to set the text for your EditViewDescriptionLabel label once the gear icon is pressed as well. You have a delegate to pass the message over to your viewcontroller. Within the gearButtonPressed call, set the text for your label similar to how you do in didSelectRowAt indexPath.
You need to set the text for your EditViewDescriptionLabel label once the gear icon is pressed as well. You have a delegate to pass the message over to your viewcontroller. Within the gearButtonPressed call, set the text for your label similar to how you do in didSelectRowAt indexPath.
Make your protocol like the below
(Pass data that best fits your needs. Here I am passing the description alone)
protocol EditPostDelegate: class {
func gearButtonPressed(description: String)
}
Then on button action,
if let descriptionContent = postDescriptionLabel.text{
delegate1?.gearButtonPressed(description: descriptionContent)
}
Then set the text for editViewDescriptionLabel in the gearButtonPressed method implementation and then show your view controller.
Pass the data you need to use to your view controller like so.
Also, consider naming your variables in camelCase.

How To Transfer Data from a Table View Cell to a View Controller

In my app I have a row of table view cells, each with a stepper and three labels. The stepper changes the value of a label in a table view cell. The problem I am facing is that when I try to transfer this data to the view controller the table view is on it does not transfer the data. I need each cell in the table view to give me a specific value so I have the code for the table view cell set up like this set up like this.
import UIKit
class ItemSearchCell: UITableViewCell {
#IBAction func itemAmountChanger(_ sender: UIStepper) {
itemQuantyWanted.text = "\(Int(sender.value))"
SearchResults().itemResultsAmountWanted.insert(Int(sender.value), at: position)
}
#IBOutlet weak var amountChangerValue: UIStepper!
#IBOutlet weak var areaView: UIView!
#IBOutlet weak var itemName: UILabel!
#IBOutlet weak var itemPrice: UILabel!
#IBOutlet weak var itemQuantyWanted: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
I then take this data and transfer it to a new viewcontroller when a button on the viewcontroller with the tableview is pressed. However the data is not sent by the stepper. The code used for sending the data is this.
var itemResultsName:[String]=[]
var itemResultsAmountWanted:[Int]=[]
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let nextView = segue.destination as! CategorsSearch
if segue.identifier == "Return"{
if itemResults.count != 0{
for i in 0 ... (itemResults.count-1){
nextView.returningItemsName.append(itemResultsName[i])
nextView.returningItemsAmountWanted.append(itemResultsAmountWanted[i])
}
}
}
}
My question is how do I transfer data from a table view cell to a view controller that the table view is on without the use a seugeway.
I am using the latest version of xcode 8.
I think the problem is how you modeled your project.
Let's describe the problem.
You need a list and the list is a representation from a some data source, like Array. If you have an array you can match the selectedIndex from list and get the value from array.
In the TableView you have delegates, and this delegate return how cell was selected with id, so get this id and get the data from your array.
I hope to help you to find the solution

Delegates with Swift

Currently I have a ViewController with a TableView and a custom Header containing a back button. What I want is to say from the header class that the ViewController has to go back to the previous ViewController. The problem I'm facing is that I'm conforming the protocol and the action of the button is received but the debugger doesn't go to the dismiss function. Here's the code:
protocol StoresFilterHeaderViewDelegate: class {
func onBackButtonTap();
}
class StoresFilterHeaderView: UICollectionReusableView {
weak var delegate: StoresFilterHeaderViewDelegate?;
#IBOutlet weak var lbSubcategory: UILabel!
#IBOutlet weak var ivSubcategory: UIImageView!
// MARK: Actions
#IBAction func onBackToMomentDetailButtonTap(_ sender: AnyObject) {
self.delegate?.onBackButtonTap();
print("button pressed");
}
}
"button pressed" is printed well
class StoresFilterViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, StoresFilterHeaderViewDelegate {
func onBackButtonTap() {
print("segueback")
}
"segueback" is not being printed
when creating the headerview, set it's delegate to self.
headerView.delegate = self
You should add this after you initialized headerView in StoresFilterViewController

make UITableView updates from class of the cells populating it

I have used the same nib file to populated a UITableView. There are 2 different functionalities I have built out for these cells. If you anywhere on the cell other than a small button it runs a function and segues to another page. However if you click the small button, I want to update the UITableView and input a cell below the clicked cell, as a sort of dropdown. I have the below to successfully run a separate functionality:
import UIKit
class ContactCell: UITableViewCell {
//below are the outlets for the conact cells
#IBOutlet weak var msgStatus: UIView!
#IBOutlet weak var contactName: UILabel!
#IBOutlet weak var dropDown: UIButton!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
msgStatus.layer.cornerRadius = msgStatus.frame.size.width/2
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
#IBAction func dropDown(_ sender: Any) {
print("selected drop down")
}
}
Moving forward I need to be able to get the index of the current cell and perform a UITableView update from the UITableViewCell's class. How would I be able to do this?
You could do this with delegation. Create a delegate protocol for your ContactCell:
protocol ContactCellDelegate {
func pleaseAddDropdown(to: ContactCell)
}
Then set up a delegate parameter for the cell:
var delegate: ContactCellDelegate?
Then subscribe your table view to the ContactCellDelegate protocol (you will have to subclass if you are using a standard UITableView). This means you will need to write an implementation of pleaseAddDropdown() for your table view class. When you dequeue a cell make sure the delegate parameter is assigned to your table view.
Now in your implementation of dropdown() you just need to do something like:
guard let _ = delegate else { return }
delegate!.pleaseAddDropdown(to: self)
Which will send that message up to the table view which can take the appropriate action.
Hope that helps.

Hiding buttons in cells

I am developing app which users will choose one of the two pictures in one cell. My prototype cell looks like :
and I have
cell.rightVoteButton.addTarget(self, action: #selector(voteRightButtonPressed), forControlEvents: .TouchUpInside)
cell.leftVoteButton.addTarget(self, action: #selector(voteLeftButtonPressed), forControlEvents: .TouchUpInside)
in the tableView function.
func voteRightButtonPressed(sender:UIButton){
print("Right Vote clicked is \(sender.tag)")
print(self.polls[sender.tag].poll_id)
}
in this way I am printing the polls id and cells index.
I want to hide the Vote button after clicking specific cell.
For example if I click the vote in first cell and the left picture, I want to hide the two buttons on the first cell. I now the cell's index but how can hide the buttons in specific cell.
My Custom TableViewCell:
class CustomTableViewCell: UITableViewCell {
#IBOutlet weak var leftImage: UIImageView!
#IBOutlet weak var rightImage: UIImageView!
#IBOutlet weak var userPicture: UIImageView!
#IBOutlet weak var userName: UILabel!
#IBOutlet weak var leftButton: UIButton!
#IBOutlet weak var rightButton: UIButton!
#IBOutlet weak var pollDescription: UILabel!
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
}
}
Rather than using tags, which have no intrinsic meaning and are easy to confuse, you can say something like:
func voteRightButtonPressed(sender:UIButton){
let location = self.tableView.convertPoint(sender.bounds.origin, fromView:sender)
let indexPath = self.tableView.indexPathForRowAtPoint(location)
if let cell = self.tableView.cellForRowAtIndexPath(indexPath) as? CustomUITableViewCell {
//hide views in cell and update your model to reflect vote.
}
print("Right Vote clicked is \(indexPath.row)")
print(self.polls[indexPath.row].poll_id)
}
Once you have the cell you can hide the views you want and you can update your model to reflect the vote just cast.
I suppose you have a tableview with several cells of this type, if this is the case you need a custonTableViewCell where you put this code. the buttons respond to a #IBAction that hide the buttons and call a delegate in his UITableViewController.
understand your custonTableViewCell like a viewController for each cell
add this in your custon cell and point the button
// IBAction for buttons
#IBAction func buttonPress(sender: UIButton){
leftButton.hidden = true
rightImage.hidden = true
self.delegate?.buttonPress(sender.tag)
}
add this before your custon cell class definition
protocol CustomTableViewCellDelegate {
func buttonPress(tag: Int)
}
and this after:
var delegate : CustomTableViewCellDelegate?
and in your tableviewcontroller
class TableViewController: UITableViewController, CustomTableViewCellDelegate
and your new func in some place
func buttonPress(tag: Int){
print(tag)
}

Resources