Delegate between Container Views without using Segue - ios

I'm trying to pass text from one textField to another textField (both of them are located in two different containerViews). I try to accomplish this with delegate. I've already read tons of related questions here, at stack overflow and read a couple of articles, so, I think I'm doing well except one thing: I don't know how to delegate without segue. Here's the code:
protocol AddOneWordViewControllerDelegate: class {
func changeTexeValue(_ text: String?)
}
class AddOneWordViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var oneWordAddWord: UITextField!
weak var delegate: AddOneWordViewControllerDelegate?
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func addOneWordWordChanged(_ sender: UITextField) {
self.delegate?.changeTexeValue(oneWordAddWord.text!)
print ("Value of the textField did change \(oneWordAddWord.text!)")
} // this action is from textField, named "Value Changed"
}
class AddTwoWordsViewController: UIViewController, UITextFieldDelegate, AddOneWordViewControllerDelegate {
#IBOutlet weak var twoWordsAddWord: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
func changeTexeValue(_ text: String?) {
self.twoWordsAddWord.text = text
print("Delegate is working")
}
}

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.

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

Setting delegate for UITextField produces error

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

Delegate error for UIStepper in TableViewCell and TableViewController

I have an issue with my delegate for UIStepper, TableViewCell and TableViewController. I am unable to pass a delegate command to my TableViewCell in the TableViewController.
My TableViewCell code is as below:
CampTableCell.swift
import UIKit
protocol ReviewCellDelegate{
func stepperButton(stepper_value:Int)
}
class CampTableCell: UITableViewCell {
#IBOutlet var campqty: UILabel!
#IBOutlet var stepper: UIStepper!
var delegate:ReviewCellDelegate!
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
}
#IBAction func stepperValueChanged(sender: UIStepper) {
self.delegate.stepperButton(Int(stepper.value))
campqty.text = String(Int(stepper.value))
}
}
The start of my TableGenController.swift is this:
class TableGenController: UITableViewController, UISearchBarDelegate, ReviewCellDelegate {
and I have added this function (as a test):
func stepperButton(stepper_value:Int) {
print("Value Changed!")
}
Next, I believe, is I have to add this under viewDidLoad:
CampTableCell.delegate = self
However, this causes an error stating that:
Instance member 'delegate' cannot be used on type 'CampTableCell'
I might be doing something conceptually wrong, but it's been difficult to find resources for this particular setup. Would be really grateful for some help on this, thanks!
I'm not proficient in delegates, but have you tried removing the line with the error? I'm not sure you need it.
Also I think you can remove self in
self.delegate.stepperButton(Int(stepper.value))

Custom TableView functions are not getting called?

On my main.Storyboard I have a TableViewController which is set to a custom class with TableViewController.swift.
The swift file has all the tableview functions defined and the #IBOutlet for the UITableView connected. The classes defined are UINavigationController,UITableViewDelegate. This viewController is called from a secondViewController via the prepareForSegue function.
I also created CustomCell.swift with class UITableViewCell and all #IBOutlet for the labels in my UITableViewCell which has been set to the customCell class.
I can't paste all my code but if you need to look at any specific code let me know and I will be happy to post that.
The Build succeeds and the app runs but the tableviewcells don't show up and none of the tableview functions are called. I see 2 flash animated screens - indicating that the tableviewcell might have 2 views - but can't figure out where I should be checking?
//Below is the segue function triggering the TableViewController
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
//print("In prepareswgue: ",segue, " ",sender)
if(segue.identifier == "resultSegue")
{
let nav = segue.destinationViewController as! UINavigationController
let svc = nav.topViewController as! TableViewController
svc.serialNo = self.TSSerialNoField.text
}
}
//Below is the custom TableVIewController class code
class TableViewController: UINavigationController,UITableViewDataSource, UITableViewDelegate
{
var serialNo:String!
var ashHardwareData: NSMutableArray!
#IBOutlet var ResultTableView: UITableView!
//#IBOutlet weak var LogCaseButton: UIButton!
#IBOutlet weak var TypeResultLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
self.ResultTableView?.allowsSelectionDuringEditing = true
self.ResultTableView?.delegate = self
ResultTableView?.dataSource = self
}
override func viewDidAppear(animated: Bool) {
self.getHardwareData(serialNo.uppercaseString)
}
/*override func viewWillAppear(animated: Bool) {
super.viewWillAppear(true)
}*/
func getHardwareData(serialno:String)
{
ashHardwareData = NSMutableArray()
ashHardwareData = ModelManager.getInstance().getHardwareData(serialno)
ResultTableView?.reloadData()
}
//TableView Delegate Methods
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
print("In height func")
return 50
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print(ashHardwareData.count)
return ashHardwareData.count
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView:UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:ResultsCell = tableView.dequeueReusableCellWithIdentifier("results", forIndexPath: indexPath) as! ResultsCell
let hardware:HardwareInfo = ashHardwareData.objectAtIndex(indexPath.row) as! HardwareInfo
let contract:ContractInfo = ashHardwareData.objectAtIndex(indexPath.row) as! ContractInfo
cell.SNOLabel.text = "Serial N0: \(hardware.SerialNo)"
cell.ContractIDLabel.text = "Contract ID: \(contract.ContractID)"
cell.OrgLabel.text = "Organisation: \(hardware.Organisation)"
cell.ModelLabel.text = "Model: \(hardware.Model)"
if(contract.DaystoExpiry > 0) {
cell.TypeLabel.text = "Contract Type: Active"
self.TypeResultLabel.hidden = false
self.TypeResultLabel.text = "To log a technical case for the Hardware please click on Log Technical Case button."
cell.LogCaseButton.hidden = false
cell.LogCaseButton.tag = indexPath.row
}
else {
cell.TypeLabel.text = "Contract Type: Expired"
cell.LogCaseButton.hidden = true
self.TypeResultLabel.hidden = false
self.TypeResultLabel.text = "Support Contract for the hardware expired. Please contact Sales team to renew the contract."
}
return cell
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
//here is the code for the ResultsCell custom UITableViewCell
import Foundation
import UIKit
class ResultsCell: UITableViewCell {
#IBOutlet weak var SNOLabel: UILabel!
#IBOutlet weak var LogCaseButton: UIButton!
#IBOutlet weak var ContractIDLabel: UILabel!
#IBOutlet weak var OrgLabel: UILabel!
#IBOutlet weak var TypeLabel: UILabel!
#IBOutlet weak var ModelLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
have you configured ResultsCell in story board or in view didload. check it once. if not try to add the following code into your view didload
[self.tableView registerNib:[UINib nibWithNibName:#"ResultsCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:#"ResultsCell"];
I have spent fair bit of my time trying to get this issue resolved and decided to go without the tableviewcell, instead I have created custom viewControllers and defined labels to display the results from the DB search (which is working OK) and used the perform segue function to pass values between viewcontrollers. So now my app works the way I want - maybe not ideal from a programming side but due to time constraints I had to get this working.
I have my app as a Tabbed Application with First and Second ViewControllers. The FirstViewController adds data to the SQLLite DB and the Second searches for the data and displays the results. for displaying the results I created a Custom viewController with labels for the data that I wanted displayed and passed all data from the DB results in SecondViewController functions to it and updated the labels with the data. As long as I get the results I wanted I am happy. I will re-visit this for improvement if I have to. Thanks to all who responded with solutions and suggestions. It has been a good learning experience :)

Resources