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
Related
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.
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")
}
}
I have a dynamically generated UITableView with many dynamic UITableViewCells and one static UITableViewCell.
The static one has a button and I want to refresh the whole table view when user presses it.
My code attached to the cell is simple:
class MyStaticCell: UITableViewCell {
#IBOutlet weak var sendCommentButton: UIButton!
#IBAction func sendCommentButtonAction(sender: AnyObject) {
//from here I want to refresh the table
}
}
How can I refresh the parent table from that button? In the class MyStaticCell I don't have any instance of the table, so that's my problem for now :|
The cleanest way to do this is through delegation. This ensures that the cell class doesn't need to know what should happen when the button is pressed; that logic can remain in your view controller where it belongs.
protocol CommentButtonProtocol {
func commentButtonTapped(sender: MyStaticCell)
}
class MyStaticCell: UITableViewCell {
#IBOutlet weak var sendCommentButton: UIButton!
var delegate: CommentButtonProtocol?
#IBAction func sendCommentButtonAction(sender: AnyObject) {
self.delegate?.commentButtonTapped(self)
}
}
Then in your view controller you can set it as the delegate in cellForRowAtIndexPath and comply with the protocol in order to handle the event:
class ViewController: UIViewController, CommentButtonProtocol {
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("staticCell", forIndexPath: indexPath) as! MyStaticCell
cell.delegate = self
return cell
}
func commentButtonTapped(sender: MyStaticCell) {
// Do whatever you need to do when the button is tapped
}
}
You could access the tableView using superview.
class MyStaticCell: UITableViewCell {
#IBOutlet weak var sendCommentButton: UIButton!
#IBAction func sendCommentButtonAction(sender: AnyObject) {
(superview as? UITableView)?.reloadData()
}
}
This isn't as stable as it could be so maybe consider this extension:
extension UIResponder {
func nextResponder<T: UIResponder>(ofType type: T.Type) -> T? {
switch nextResponder() {
case let responder as T:
return responder
case let .Some(responder):
return responder.nextResponder(ofType: type)
default:
return nil
}
}
}
It allows you to find the next parent of a particular type, in the cells case, a UITableView.
class MyStaticCell: UITableViewCell {
#IBOutlet weak var sendCommentButton: UIButton!
#IBAction func sendCommentButtonAction(sender: AnyObject) {
nextResponder(ofType: UITableView.self)?.reloadData()
}
}
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)
}
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