Swift FSCalendar Interactive Scope Gesture programmatically - swift

I'm using FSCalendar to create a calendar for my app but I can not get the Interactive Scope Gesture to work. I have downloaded the example project and read through the documentation but it still crashes with this error Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value on line calendarHeightConstraint.constant = 350. All I'm trying to achieve is the exact same as the documentation shows with the Interactive Scope Gesture but programmatically.
var calendarHeightConstraint: NSLayoutConstraint!
let calendarView: FSCalendar = {
let cl = FSCalendar()
cl.allowsMultipleSelection = false
return cl
}()
let collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.backgroundColor = UIColor(named: "backgroundColor")
cv.showsVerticalScrollIndicator = false
cv.showsHorizontalScrollIndicator = false
return cv
}()
fileprivate lazy var scopeGesture: UIPanGestureRecognizer = {
[unowned self] in
let panGesture = UIPanGestureRecognizer(target: self.calendarView, action: #selector(self.calendarView.handleScopeGesture(_:)))
panGesture.delegate = self
panGesture.minimumNumberOfTouches = 1
panGesture.maximumNumberOfTouches = 2
return panGesture
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor(named: "backgroundColor")
collectionView.delegate = self
collectionView.dataSource = self
calendarView.delegate = self
calendarView.dataSource = self
calendarHeightConstraint.constant = 350
self.calendarView.select(Date())
self.view.addGestureRecognizer(self.scopeGesture)
self.calendarView.addGestureRecognizer(self.scopeGesture)
self.calendarView.scope = .week
setupLayout()
setupCollectionView()
}
func setupLayout() {
view.addSubview(calendarView)
calendarView.anchor(top: topLayoutGuide.bottomAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 75, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: view.frame.width, height: 350)
view.addSubview(collectionView)
collectionView.anchor(top: calendarView.bottomAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, paddingTop: 15, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
}
func setupCollectionView() {
collectionView.register(CalendarCollectionCell.self, forCellWithReuseIdentifier: cellId)
collectionView.dataSource = self
collectionView.delegate = self
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! CalendarCollectionCell
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width, height: 70)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 15
}
func calendar(_ calendar: FSCalendar, boundingRectWillChange bounds: CGRect, animated: Bool) {
self.calendarHeightConstraint.constant = bounds.height
self.view.layoutIfNeeded()
}

You don't init
var calendarHeightConstraint: NSLayoutConstraint!
or link it as an outlet hence it's nil , you need to link it here
calendarView.anchor(top: topLayoutGuide.bottomAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 75, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: view.frame.width, height: 350)
so you can play with it's constant as needed , so you can do
NSLayoutConstraint.activate([
// add left , right and top constraints
])
in addition to
calendarHeightConstraint = calendarView.heightAnchor.constraint(equalToConstant: 350)
calendarHeightConstraint.isActive = true
Don't try to use calendarHeightConstraint before the above 2 lines as this will give the nil crash

You can fix this by doing two things.
Remove the line calendarHeightConstraint.constant = 350 from viewDidLoad.
Initialize the calendarHeightConstraint in setupLayout.
Instead of:
calendarView.anchor(top: topLayoutGuide.bottomAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 75, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: view.frame.width, height: 350)
Use:
calendarView.anchor(top: topLayoutGuide.bottomAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 75, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: view.frame.width, height: 0)
calendarHeightConstraint = calendarView.heightAnchor.constraint(equalToConstant: 350)
calendarHeightConstraint.isActive = true

Related

uiCollectionView inside a uiCollectionViewCell is not scrolling horizontally

Hey Everyone and thank you for taking your time to view this, I am trying to make a uiCollectionView scroll horizontally within a uiCollectionViewCell, the background and elements are showing but im unable to scroll, the uiCollectionViewcontaining the uiCollectionViewCell (which contains the uiCollectionView i need to scroll horizontally) in scrolling vertically as expected. Below are the relative classes:
The uiCollectionView and its uiCollectionViewCells which contains the uiCollectionView that needs horizontal scrolling, in the collectionView method the cases that needs scrolling are Prop4 and Countries:
lazy var collView: UICollectionView = {
let sub = SubclassedCollectionViewCell.self
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.itemSize = CGSize(width: self.view.frame.width, height:self.view.frame.height/100)
layout.scrollDirection = .vertical
// layout.minimumLineSpacing = 1000
layout.sectionInset = UIEdgeInsets(top:100, left: 0, bottom: 100, right: 0)
print("the frame",self.view.frame)
let view = UICollectionView(frame: CGRect(x:0, y:0, width: self.view.frame.width, height: self.view.frame.height), collectionViewLayout: layout)
view.register(sub, forCellWithReuseIdentifier: "profInfo")
view.backgroundColor = .clear
view.isUserInteractionEnabled = true
view.dataSource = self
view.delegate = self
return view
}()
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let myCell = collectionView.dequeueReusableCell(withReuseIdentifier: "profInfo", for: indexPath) as! SubclassedCollectionViewCell
myCell.isUserInteractionEnabled = true
myCell.frame = CGRect(x: 10, y: (indexPath.row+1)*75, width: Int(self.view.frame.width) - 10, height: 50)
myCell.backgroundColor = .clear
let v = UIView(frame: CGRect(x: 0, y: 0, width: 150, height: 50))
let v2 = UIView(frame: CGRect(x: 150, y: 0, width: Int(self.view.frame.width) - 160, height: 50))
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 21))
let label2 = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 21))
let imageV = UIImageView(frame: CGRect(x: 0, y: 12.5, width: 25, height: 25))
let imageV2 = UIImageView(frame: CGRect(x: 0, y: 12.5, width: 25, height: 25))
label.center = CGPoint(x: 150, y: 25)
label.textColor = .white
label2.textColor = .white
label2.center = CGPoint(x: 115, y: 25)
label2.textAlignment = .center
imageV2.center = CGPoint(x: 115, y: 25)
label.text = prof!.arrInfo[indexPath.row].title + ":"
print("array info", prof!.arrInfo)
switch(prof!.arrInfo[indexPath.row].title){
case "Prop1" :
imageV.image = UIImage(named: "art.scnassets/prop1.png")?.resized(to: CGSize(width: 10, height: 10))
label2.text = prof!.arrInfo[indexPath.row].text
v2.addSubview(label2)
break;
case "DOB" :
imageV.image = UIImage(named: "art.scnassets/DOB.png")?.resized(to: CGSize(width: 10, height: 10))
label2.text = getDOBFormat(dateStr: prof!.arrInfo[indexPath.row].text!)
v2.addSubview(label2)
break;
case "Prop3" :
imageV.image = UIImage(named: "art.scnassets/prop3.png")?.resized(to: CGSize(width: 10, height: 10))
imageV2.image = UIImage(named: prof!.arrInfo[indexPath.row].text!)?.resized(to: CGSize(width: 10, height: 10))
break;
case "Prop4" :
imageV.image = UIImage(named: "art.scnassets/prop4.png")?.resized(to: CGSize(width: 10, height: 10))
collectionViews[prof!.arrInfo[indexPath.row].title] = GeneralCollectionView()
collectionViews[prof!.arrInfo[indexPath.row].title]?.type = "Images"
collectionViews[prof!.arrInfo[indexPath.row].title]?.data = prof!.arrInfo[indexPath.row].selected
myCell.contentView.addSubview(collectionViews[prof!.arrInfo[indexPath.row].title]!.Container)
break;
case "Countries" :
imageV.image = UIImage(named: "art.scnassets/translation.png")?.resized(to: CGSize(width: 10, height: 10))
collectionViews[prof!.arrInfo[indexPath.row].title] = GeneralCollectionView()
collectionViews[prof!.arrInfo[indexPath.row].title]?.type = "Countries"
collectionViews[prof!.arrInfo[indexPath.row].title]?.data = prof!.arrInfo[indexPath.row].selected
myCell.contentView.addSubview(collectionViews[prof!.arrInfo[indexPath.row].title]!.Container)
break;
case "location":
imageV.image = UIImage(named: "art.scnassets/location.png")?.resized(to: CGSize(width: 10, height: 10))
label2.text = prof!.arrInfo[indexPath.row].text
v2.addSubview(label2)
break;
default:
break;
}
v.addSubview(label)
v.addSubview(imageV)
v2.addSubview(imageV2)
myCell.contentView.addSubview(v)
myCell.contentView.addSubview(v2)
return myCell
}
And this is the uiCollectionView that needs Horizontal scrolling and thats within the uiCollectionViewCell:
public class GeneralCollectionView:NSObject,UICollectionViewDelegate,UICollectionViewDataSource{
weak var parent:AnyObject?
var data:[String]?
var type:String?
lazy var Container: UICollectionView = {
let sub = SubclassedCollectionViewCell.self
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.itemSize = CGSize(width: 50, height:50)
layout.scrollDirection = .horizontal
let view = UICollectionView(frame: CGRect(x:150, y:0, width: 250, height: 50), collectionViewLayout: layout)
view.showsHorizontalScrollIndicator = false
view.isDirectionalLockEnabled = true
view.isScrollEnabled = true
view.isPagingEnabled = true
view.isUserInteractionEnabled = true
view.alwaysBounceHorizontal = true
view.clipsToBounds = true
view.translatesAutoresizingMaskIntoConstraints = false
view.register(sub, forCellWithReuseIdentifier: "myGenCell")
view.dataSource = self
view.delegate = self
view.backgroundColor = .white
layout.sectionInset = UIEdgeInsets(top:0, left: 10, bottom: 0, right: 10)
layout.minimumLineSpacing = 10 // space between rows
layout.minimumInteritemSpacing = 5 // space between items in the same
layout.itemSize = CGSize(width: 50, height: 50)
return view
}()
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return data!.count
}
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let myCell = collectionView.dequeueReusableCell(withReuseIdentifier: "myGenCell", for: indexPath) as! SubclassedCollectionViewCell
myCell.isUserInteractionEnabled = true
if type == "Countries"{
let country = data![indexPath.item].split(separator: "-")
let label = UILabel()
label.frame.size = CGSize(width: 50, height: 50)
label.text = countryFlag(country: String(country[1]))
label.center = CGPoint(x: 30, y: 25)
myCell.contentView.addSubview(label)
print(label, countryFlag(country: String(country[1])))
} else {
let val = data![indexPath.item]
let imgView = UIImageView()
imgView.frame.size = CGSize(width: 20, height: 20)
imgView.image = UIImage(named: val)?.resized(to: CGSize(width: 25, height: 25))
imgView.center = CGPoint(x: 30, y: 25)
myCell.contentView.addSubview(imgView)
}
return myCell
}
}
It is because v2 is added after the horizontal collection view, therefore coming on top blocking all user interactions like your scroll gestures.
Give all your views different background colors to debug this sort of thing.
Set isUserInteractionEnabled = false to v2 and any other view blocking your scroll gestures.
Besides that,
Check out Modern collection views to get some examples of how to build a collection view.
Checkout Auto layout to properly size your views.

Messaging App: Textview not autoresizing it's height to display full message

For the ChatLogController of my messaging feature, I'm having trouble getting the message bubble to automatically adjust its size based on its textView content size. It's showing only one line from the textview as the rest of the text is truncated. Here's how I've defined my textView and the message bubbleContainer:
private let textView: UITextView = {
let tv = UITextView()
tv.backgroundColor = .clear
tv.font = .systemFont(ofSize: 16)
tv.isScrollEnabled = false
tv.isEditable = false
tv.textColor = .white
return tv
}()
private let bubbleContainer: UIView = {
let view = UIView()
view.backgroundColor = .systemPurple
return view
}()
And here are the constraints:
addSubview(bubbleContainer)
bubbleContainer.layer.cornerRadius = 12
bubbleContainer.anchor(top: topAnchor, bottom: bottomAnchor)
bubbleContainer.widthAnchor.constraint(lessThanOrEqualToConstant: 250).isActive = true
bubbleLeftAnchor = bubbleContainer.leftAnchor.constraint(equalTo: profileImageView.rightAnchor, constant: 12)
bubbleLeftAnchor.isActive = false
bubbleRightAnchor = bubbleContainer.rightAnchor.constraint(equalTo: rightAnchor, constant: -12)
bubbleRightAnchor.isActive = false
bubbleContainer.addSubview(textView)
textView.anchor(top: bubbleContainer.topAnchor, left: bubbleContainer.leftAnchor,
bottom: bubbleContainer.bottomAnchor, right: bubbleContainer.rightAnchor,
paddingTop: 4, paddingLeft: 12, paddingBottom: 4, paddingRight: 12)
The ChatLogController is a UICollectionViewController, and this is the way I've set up sizeForItemAt:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let frame = CGRect(x: 0, y: 0, width: view.frame.width, height: 50)
let estimatedSizeCell = MessageCell(frame: frame)
estimatedSizeCell.message = messages[indexPath.row]
estimatedSizeCell.layoutIfNeeded()
let targetSize = CGSize(width: view.frame.width, height: 1000)
let estimatedSize = estimatedSizeCell.systemLayoutSizeFitting(targetSize)
return .init(width: view.frame.width, height: estimatedSize.height)
}
The delegate is set to self but it seems as if the function is not even being called.
in the pic below, you can see how the messages are being truncated and the cell height is stuck to 50 pixels, where it should have been adjusted to display the rest of the message:
Inside cell take label with 0 number of lines which has following constraints:
Leading: Grater than 90 superview
All other with as usual

How to animate elements of a UIStackView that’s created in a separate function

I'm trying to animate a stackview and its elements upon pressing a UIButton. the problem is that the stackview is created inside a function which is called in viewdidload.
Because the stackview is created inside a function I cannot call it inside the function that manages the animation... I think i'm doing something wrong...
my stackview creation function
fileprivate func variableContent() {
let stackviewButtons = UIStackView(arrangedSubviews: [registerSerialNumberButton, dothislaterButton])
stackviewButtons.axis = .vertical
stackviewButtons.alignment = .fill
stackviewButtons.spacing = 10
let stackview = UIStackView(arrangedSubviews: [registerTitlelabel, registerdescriptionLabel, serialnumberInput, stackviewButtons])
stackview.axis = .vertical
stackview.spacing = 20
stackview.setCustomSpacing(40, after: registerdescriptionLabel)
stackview.setCustomSpacing(100, after: serialnumberInput)
view.addSubview(stackview)
stackview.anchor(top: nil, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 0, paddingLeft: 20, paddingBottom: 0, paddingRight: 20, width: 0, height: 0)
stackview.centerXInSuperview()
stackview.centerYInSuperview()
}
viewdidload
override func viewDidLoad() {
variableContent()
}
You can return the stackview from your function and keep a reference to it as an instance variable. That way you can reuse it later.
class Controller: UIViewController {
var stackView: UIStackView!
fileprivate func variableContent() -> UIStackView {
let stackviewButtons = UIStackView(arrangedSubviews: [registerSerialNumberButton, dothislaterButton])
stackviewButtons.axis = .vertical
stackviewButtons.alignment = .fill
stackviewButtons.spacing = 10
let stackview = UIStackView(arrangedSubviews: [registerTitlelabel, registerdescriptionLabel, serialnumberInput, stackviewButtons])
stackview.axis = .vertical
stackview.spacing = 20
stackview.setCustomSpacing(40, after: registerdescriptionLabel)
stackview.setCustomSpacing(100, after: serialnumberInput)
view.addSubview(stackview)
stackview.anchor(top: nil, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 0, paddingLeft: 20, paddingBottom: 0, paddingRight: 20, width: 0, height: 0)
stackview.centerXInSuperview()
stackview.centerYInSuperview()
return stackview
}
override func viewDidLoad() {
super.viewDidLoad()
self.stackView = variableContent()
}
}
An other option would be to give it a tag (stackview.tag = 42)
and recover it with self.view.viewWithTag(42)
In addition to Marcio's answer, you can also declare the stackView optionally and set it in the function:
class Controller: UIViewController {
var stackview: UIStackView?
fileprivate func variableContent() {
let stackviewButtons = UIStackView(arrangedSubviews: [registerSerialNumberButton, dothislaterButton])
stackviewButtons.axis = .vertical
stackviewButtons.alignment = .fill
stackviewButtons.spacing = 10
self.stackview = UIStackView(arrangedSubviews: [registerTitlelabel, registerdescriptionLabel, serialnumberInput, stackviewButtons])
stackview.axis = .vertical
stackview.spacing = 20
stackview.setCustomSpacing(40, after: registerdescriptionLabel)
stackview.setCustomSpacing(100, after: serialnumberInput)
view.addSubview(stackview)
stackview.anchor(top: nil, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 0, paddingLeft: 20, paddingBottom: 0, paddingRight: 20, width: 0, height: 0)
stackview.centerXInSuperview()
stackview.centerYInSuperview()
}
// Whatever your animating function is:
func animateStackView() {
guard let stackview = self.stackview else { return }
// You now have access to your stackView for the rest of this function.
}
}
Note: For consistency with your question, I kept the name of the UIStackView as stackview in the code, but according to Swift naming conventions, you should name variables in camelcase (stackView)

When i try dismiss keyBoard with interactive mode, i have an error for my inputAccessoryView

I've implemented inputAccessoryView with UITextView. I also set collectionView.keyboardDismissMode = .interactive
When i dissmiss keyboard by using interactive mode i have this two error
1) - First responder warning: '<.InputTextView: 0x7f8f54061800; baseClass = UITextView; frame = (8 8; 307 35.5); text = ''; clipsToBounds = YES; gestureRecognizers = ; layer = ; contentOffset: {0, 0}; contentSize: {130, 0}; adjustedContentInset: {0, 0, 0, 0}>' rejected resignFirstResponder when being removed from hierarchy
2) - [UIWindow endDisablingInterfaceAutorotationAnimated:] called on > without matching -beginDisablingInterfaceAutorotation. Ignoring.
Xcode 10 and swift 4
Code For CollectionViewController
lazy var containerView: InputAccesoryView = {
let frame = CGRect(x: 0, y: 0, width: view.frame.width, height: 50)
let containerView = InputAccesoryView(frame: frame)
containerView.backgroundColor = UIColor.groupTableViewBackground
containerView.autoresizingMask = .flexibleHeight
containerView.delegate = self
return containerView
}()
override var inputAccessoryView: UIView {
get {
return containerView
}
}
override var canBecomeFirstResponder: Bool {
return true
}
Code for InputAccesoryView
public let inputTextView: InputTextView = {
let textView = InputTextView()
textView.font = UIFont.systemFont(ofSize: 16)
textView.isScrollEnabled = false
textView.textAlignment = .left
textView.layer.cornerRadius = 10
return textView
}()
private lazy var sendButton: UIButton = {
let button = UIButton(type: .system)
button.setImage(UIImage(named: "send2"), for: .normal)
button.tintColor = .black
button.addTarget(self, action: #selector(handleUploadComment), for: .touchUpInside)
return button
}()
override init(frame: CGRect) {
super.init(frame: frame)
configureViewComponents()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override var intrinsicContentSize: CGSize {
return CGSize.zero
}
private func configureViewComponents(){
addSubview(sendButton)
sendButton.setPosition(top: nil, left: nil, bottom: nil, right: rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 8, width: 44, height: 0)
sendButton.centerYAnchor.constraint(equalTo: layoutMarginsGuide.centerYAnchor).isActive = true
addSubview(inputTextView)
inputTextView.setPosition(top: topAnchor, left: leftAnchor, bottom: layoutMarginsGuide.bottomAnchor, right: sendButton.leftAnchor, paddingTop: 8, paddingLeft: 8, paddingBottom: 8, paddingRight: 8, width: 0, height: 0)
let separatorView = UIView()
separatorView.backgroundColor = UIColor(red: 230/255, green: 230/255, blue: 230/255, alpha: 1)
addSubview(separatorView)
separatorView.setPosition(top: topAnchor, left: leftAnchor, bottom: nil, right: rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0.5)
}
func clearCommentTextView() {
inputTextView.text = nil
inputTextView.placeHolder.isHidden = false
}

UICollectionViewCell Protocol is not working

I have a Protocol inside my CellClass which is detect the function 'editCommentInFeed'. I have create an 'editButton' inside my Cell and define the handler with 'editCommentField' which is calling per Delegate the function and over give the 2 Parameters. This 2 Parameters are important I need this Informations from the cell to detect in future actions which will be provided.
For example I had tried to print something when the Button ist Pressed inside the Cell. But even this Statement is not execute.
//This is the Cell Class
protocol CommentFeedProtocol {
func editCommentInFeed(cell: CommentCell, comment: Comment)
}
class CommentCell: BaseCell {
var delegate: CommentFeedProtocol?
let editButton: UIButton = {
let editbttn = UIButton(type: UIButton.ButtonType.system)
editbttn.setImage(UIImage(named: "editButton"), for: UIControl.State.normal)
editbttn.addTarget(self, action: #selector(editCommentField), for: UIControl.Event.touchUpInside)
return editbttn
}()
override func setUpCell() {
super.setUpCell()
backgroundColor = UIColor.white
setUpCommentCell()
}
fileprivate func setUpCommentCell(){
addSubview(profileImageView)
addSubview(editButton)
addSubview(commentTextView)
addSubview(seperator)
profileImageView.anchor(top: topAnchor, left: leftAnchor, bottom: nil, right: nil, paddingTop: 8, paddingLeft: 8, paddingBottom: 0, paddingRight: 0, width: 40, height: 40)
profileImageView.layer.cornerRadius = 40/2
editButton.anchor(top: topAnchor, left: nil, bottom: bottomAnchor, right: rightAnchor, paddingTop: 5, paddingLeft: 0, paddingBottom: 5, paddingRight: 10, width: 45, height: 0)
commentTextView.anchor(top: topAnchor, left: profileImageView.rightAnchor, bottom: bottomAnchor, right: editButton.leftAnchor, paddingTop: 4, paddingLeft: 4, paddingBottom: 4, paddingRight: 4, width: 0, height: 0)
seperator.anchor(top: bottomAnchor, left: leftAnchor, bottom: nil, right: rightAnchor, paddingTop: 5, paddingLeft: 20, paddingBottom: 0, paddingRight: 20, width: 0, height: 1.5)
}
/*Objecthandler*/
#objc func editCommentField(){
guard let comment = comment else { return}
delegate?.editCommentInFeed(cell: self, comment: comment)
}
// This is the CollectionViewController
// As you can see I am also add the Protocol to the class
class CommentsController: UICollectionViewController, UICollectionViewDelegateFlowLayout, CommentFeedProtocol {
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "Kommentare"
postButton.imageView?.alpha = 0.5
postButton.isEnabled = false
collectionView.keyboardDismissMode = .interactive
collectionView.register(CommentCell.self, forCellWithReuseIdentifier: commentCell)
collectionView.alwaysBounceVertical = true
self.collectionView.backgroundColor = UIColor.white
fetchComments()
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: commentCell, for: indexPath) as! CommentCell
cell.comment = comments[indexPath.item]
cell.delegate = self
return cell
}
// Here is the Delegate Function
func editCommentInFeed(cell: CommentCell, comment: Comment) {
print("Button was Pressed")
}
You can see inside the example that I am Adding the Protocol to the class and also call the function inside the Class. I am not getting a Error Message. The Button is only light hovered when is clicked, but don't execute anything ?!
Seems the delegate is not set to your ViewController.
inside your cellForItemAt function, you need to set cell.delegate = self.
so when your cell calls delegate.editCommentInFeed it actually calls your viewController's editCommentInFeed implemented function.
You haven't set the delegate in cellForItemAt:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: commentCell, for: indexPath) as! CommentCell
cell.comment = comments[indexPath.item]
cell.delegate = self. // You forgot to add this line
return cell
}
you can read more about it here:
https://developer.apple.com/library/archive/documentation/General/Conceptual/CocoaEncyclopedia/DelegatesandDataSources/DelegatesandDataSources.html
You can also search for great tutorials about it.