I am getting this error "'removeCircleLabel' is inaccessible due to 'internal' protection level" on this line of code. I was adding CVCalendar Library to my project.I added the pod but i when i am adding the view controller code in my project that time its giving me this error.
#IBOutlet weak var calendarView: CVCalendarView!
#IBAction func removeCircleAndDot(sender: AnyObject) {
if let dayView = selectedDay {
calendarView.contentController.removeCircleLabel(dayView)// **error on this line**
if dayView.date.day < randomNumberOfDotMarkersForDay.count {
randomNumberOfDotMarkersForDay[dayView.date.day] = 0
}
calendarView.contentController.refreshPresentedMonth()
}
}
public typealias ContentViewController = CVCalendarContentViewController
public final class CVCalendarView: UIView {
// MARK: - Public properties
public var manager: Manager!
public var appearance: Appearance!
public var touchController: TouchController!
public var coordinator: Coordinator!
public var animator: Animator!
public var contentController: ContentViewController!
public var calendarMode: CalendarMode!
public var (weekViewSize, dayViewSize): (CGSize?, CGSize?)
}
// MARK: Delete circle views (in effect refreshing the dayView circle)
extension CVCalendarContentViewController {
func removeCircleLabel(_ dayView: CVCalendarDayView) {
for each in dayView.subviews {
if each is UILabel {
continue
} else if each is CVAuxiliaryView {
continue
} else {
each.removeFromSuperview()
}
}
}
}
MY View Controller Code
import UIKit
import CVCalendar
class MainPageViewController: UIViewController, UITableViewDelegate,
UITableViewDataSource {
struct Color {
static let selectedText = UIColor.white
static let text = UIColor.black
static let textDisabled = UIColor.gray
static let selectionBackground = UIColor(red: 0.2, green: 0.2, blue: 1.0, alpha: 1.0)
static let sundayText = UIColor(red: 1.0, green: 0.2, blue: 0.2, alpha: 1.0)
static let sundayTextDisabled = UIColor(red: 1.0, green: 0.6, blue: 0.6, alpha: 1.0)
static let sundaySelectionBackground = sundayText
}
// MARK: - Properties
#IBOutlet weak var calendarView: CVCalendarView!
#IBOutlet weak var menuView: CVCalendarMenuView!
#IBOutlet weak var monthLabel: UILabel!
#IBOutlet weak var daysOutSwitch: UISwitch!
fileprivate var randomNumberOfDotMarkersForDay = [Int]()
var shouldShowDaysOut = true
var animationFinished = true
var selectedDay:DayView!
var currentCalendar: Calendar?
override func awakeFromNib() {
let timeZoneBias = 480 // (UTC+08:00)
currentCalendar = Calendar.init(identifier: .gregorian)
if let timeZone = TimeZone.init(secondsFromGMT: -timeZoneBias * 60) {
currentCalendar?.timeZone = timeZone
}
}
#IBOutlet weak var topCalBtnView = UIView()
#IBOutlet weak var sideBtnView = UIView()
#IBOutlet weak var calendarBigView = UIView()
#IBOutlet weak var filterBtn = UIButton()
#IBOutlet weak var calTable = UITableView()
#IBOutlet weak var calView = UIView()
var calendarContectObj = CVCalendarContentViewController()
convenience init() {
self.init(nibName:nil, bundle:nil)
}
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.isHidden = true
//Calendar Stuff
if let currentCalendar = currentCalendar {
monthLabel.text = CVDate(date: Date(), calendar: currentCalendar).globalDescription
}
randomizeDotMarkers()
// Do any additional setup after loading the view.
}
override func viewWillAppear(_ animated: Bool) {
self.setLayout()
navigationController?.interactivePopGestureRecognizer?.isEnabled = false
}
func setLayout(){
ConstantFile.roundViewCorner(customVw: topCalBtnView!)
ConstantFile.roundViewCorner(customVw: sideBtnView!)
ConstantFile.roundViewCorner(customVw: calendarBigView!)
ConstantFile.makeRoundBtnWithCornerRadius(btn: filterBtn!, cornerRadius: 0.02)
ConstantFile.roundTableViewCorner(tableVw: calTable!)
}
//Mark:- IBAction
#IBAction func toggleMenuBtn(_ sender: Any) {
let appDelegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.centerDrawwerController?.toggle(MMDrawerSide.left, animated: true, completion: nil)
}
//MARK:- UITableView Delegate and Data Source
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellId")
let cell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath)
return cell
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//Mark:- Calendar Stuff
#IBAction func removeCircleAndDot(sender: AnyObject) {
if let dayView = selectedDay {
calendarView.contentController.removeCircleLabel(dayView)
if dayView.date.day < randomNumberOfDotMarkersForDay.count {
randomNumberOfDotMarkersForDay[dayView.date.day] = 0
}
calendarView.contentController.refreshPresentedMonth()
}
}
#IBAction func refreshMonth(sender: AnyObject) {
calendarView.contentController.refreshPresentedMonth()
randomizeDotMarkers()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
calendarView.commitCalendarViewUpdate()
menuView.commitMenuViewUpdate()
}
private func randomizeDotMarkers() {
randomNumberOfDotMarkersForDay = [Int]()
for _ in 0...31 {
randomNumberOfDotMarkersForDay.append(Int(arc4random_uniform(3) + 1))
}
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
By default all the methods, variable, constants, etc are internal. With internal protection level those methods, variable, constants, etc are not accessible outside a module.
removeCircleLabel(:_) is an internal method of the calendar module, you need make it public to access it.
Also do read: What is the 'open' keyword in Swift?
This explains when you should use public and open.
In my quick search i found the function removeCircleLabel in CVCalendarContentViewController on GitHub.
// MARK: Delete circle views (in effect refreshing the dayView circle)
extension CVCalendarContentViewController {
func removeCircleLabel(_ dayView: CVCalendarDayView) {
for each in dayView.subviews {
if each is UILabel {
continue
} else if each is CVAuxiliaryView {
continue
} else {
each.removeFromSuperview()
}
}
}
}
it clearly you can access this method from your controller. There is no protection.Please check your calendarView source with latest one.
Related
When I click on “Add” Button below, the products do not get added to the cart and the Checkout (0) does not increase to Checkout (1) etc. What am I doing wrong ?
-- Original issue resolved after reading #Larme's first comment. It was a rookie mistake(I had forgotten to put cell.delegate = self in tableView(_ tableView:, cellForRowAt: in ProductViewController). Now, I have some other problemin CartViewController(See Edit please) --
posting relevant code -
struct Product -
import UIKit
struct Product:Equatable {
let name : String
var quantity : Int
var price : Double
let imagename: UIImage
// var subTotal : Double {
//return Double(quantity) * price }
}
var products = [Product(name: "a", quantity: 5, price: 5.0,imagename:#imageLiteral(resourceName: "PeasImge")),
Product(name: "b", quantity: 10, price: 10.0, imagename:#imageLiteral(resourceName: "CakeImage")),]
class ProductViewController -
import UIKit
class ProductViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
fileprivate var cart = Cart()
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self }
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
//Workaround to avoid the fadout the right bar button item
self.navigationItem.rightBarButtonItem?.isEnabled = false
self.navigationItem.rightBarButtonItem?.isEnabled = true
//Update cart if some items quantity is equal to 0 and reload the product table and right button bar item
cart.updateCart()
self.navigationItem.rightBarButtonItem?.title = "Checkout (\(cart.items.count))"
tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/* override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showCart" {
if let cartViewController = segue.destination as? CartViewController {
cartViewController.cart = self.cart
}
}
}*/
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return products.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ProductTableViewCell") as! ProductTableViewCell
let product = products[indexPath.item]
cell.delegate = self // original issue was here, now resolved.
cell.name?.text = product.name
cell.imageView?.image = product.imagename
cell.setButton(state: self.cart.contains(product: product))
// Configure YourCustomCell using the outlets that you've defined.
return cell
}
}
extension ProductViewController: CartDelegate {
// MARK: - CartDelegate
func updateCart(cell: ProductTableViewCell) {
guard let indexPath = tableView.indexPath(for: cell) else { return }
let product = products[indexPath.item]
//Update Cart with product
cart.updateCart(with: product)
self.navigationItem.rightBarButtonItem?.title = "Checkout (\(cart.items.count))"
}
}
class ProductTableViewCell-
import UIKit
protocol CartDelegate {
func updateCart(cell: ProductTableViewCell)
}
class ProductTableViewCell: UITableViewCell {
weak var myParent:ProductViewController?
#IBOutlet weak var name: UILabel!
#IBOutlet weak var price: UILabel!
#IBOutlet weak var imagename: UIImageView!
#IBOutlet weak var addToCartButton: UIButton!
var delegate: CartDelegate?
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
addToCartButton.layer.cornerRadius = 5
addToCartButton.clipsToBounds = true
}
func setButton(state: Bool) {
addToCartButton.isSelected = state
addToCartButton.backgroundColor = (!addToCartButton.isSelected) ? .black : .red
}
#IBAction func addToCart(_ sender: Any) {
setButton(state: !addToCartButton.isSelected)
self.delegate?.updateCart(cell: self)
}
}
class CartItem
import Foundation
class CartItem {
var quantity : Int = 1
var product : Product
/* var subTotal : Float { get { return Float(product.price) * Float(quantity) } } */
init(product: Product) {
self.product = product
}
}
class Cart -
import Foundation
class Cart {
var items : [CartItem] = []
}
extension Cart {
/* var total: Float {
get { return items.reduce(0.0) { value, item in
value + item.subTotal
}
}
}*/
var totalQuantity : Int {
get { return items.reduce(0) { value, item in
value + item.quantity
}
}
}
func updateCart(with product: Product) {
if !self.contains(product: product) {
self.add(product: product)
} else {
self.remove(product: product)
}
}
func updateCart() {
for item in self.items {
if item.quantity == 0 {
updateCart(with: item.product)
}
}
}
func add(product: Product) {
let item = items.filter { $0.product == product }
if item.first != nil {
item.first!.quantity += 1
} else {
items.append(CartItem(product: product))
}
}
func remove(product: Product) {
guard let index = items.firstIndex(where: { $0.product == product }) else { return}
items.remove(at: index)
}
func contains(product: Product) -> Bool {
let item = items.filter { $0.product == product }
return item.first != nil
}
}
I can also post “CartItemTableViewCell” and “CartViewController” if you will.
Any help would be greatly appreciated.
Edit: The original issue is resolved now, thanks to #Larme.
I have another issue for which I have pasted “CartViewController” and “CartItemTableViewCell” as well along with some rectifications in the old code after reading #Larme's first comment.
The issue is in CartViewController - When I click on Checkout button after loading the cart, it shows error in CartviewController's "tableView(_ tableView: UITableView, numberOfRowsInSection" - see CartVieController code below:-
class CartViewController
import UIKit
class CartViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var totalView: UIView!
#IBOutlet weak var totalLabel: UILabel!
var cart: Cart? = nil
fileprivate let reuseIdentifier = "CartItemCell"
override func viewDidLoad() {
super.viewDidLoad()
tableView.tableFooterView = UIView(frame: .zero)
}
}
extension CartViewController: UITableViewDelegate, UITableViewDataSource {
// MARK: - Table view data source
func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return (cart?.items.count)!// Error - Thread 1:EXC_BAD_INSTRUCTION..
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) as! CartItemTableViewCell
if let cartItem = cart?.items[indexPath.item] {
cell.delegate = self as CartItemDelegate
cell.nameLabel.text = cartItem.product.name
// cell.priceLabel.text = cartItem.product.price
cell.quantityLabel.text = String(describing: cartItem.quantity)
cell.quantity = cartItem.quantity
// cell.contentView.backgroundColor = !cell.decrementButton.isEnabled ? .white : .blue
}
return cell
}
}
extension CartViewController: CartItemDelegate {
// MARK: - CartItemDelegate
func updateCartItem(cell: CartItemTableViewCell, quantity: Int) {
guard let indexPath = tableView.indexPath(for: cell) else { return }
guard let cartItem = cart?.items[indexPath.row] else { return }
//Update cart item quantity
cartItem.quantity = quantity
//Update displayed cart total
// guard let total = cart?.total else { return }
//totalLabel.text = String(total)
// print(total)
}
}
class CartItemTableViewCell -
import UIKit
protocol CartItemDelegate {
func updateCartItem(cell: CartItemTableViewCell, quantity: Int)
}
class CartItemTableViewCell: UITableViewCell {
#IBOutlet weak var nameLabel: UILabel!
#IBOutlet weak var priceLabel: UILabel!
#IBOutlet weak var incrementButton: UIButton!
#IBOutlet weak var decrementButton: UIButton!
#IBOutlet weak var quantityLabel: UILabel!
var delegate: CartItemDelegate?
var quantity: Int = 1
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
incrementButton.layer.cornerRadius = 10
incrementButton.clipsToBounds = true
decrementButton.layer.cornerRadius = 10
decrementButton.clipsToBounds = true
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
#IBAction func updateCartItemQuantity(_ sender: Any) {
if (sender as! UIButton).tag == 0 {
quantity = quantity + 1
} else if quantity > 0 {
quantity = quantity - 1
}
decrementButton.isEnabled = quantity > 0
decrementButton.backgroundColor = !decrementButton.isEnabled ? .gray : .black
self.quantityLabel.text = String(describing: quantity)
self.delegate?.updateCartItem(cell: self, quantity: quantity)
}
}
I am facing the issue of passing the data from HomeViewController to PostDetailViewController,
I have checked the classes connected to the View Controllers are correct, class connected to the XIB file is PostTableViewCell,
and still getting this error of
'NSUnknownKeyException', reason:
'[
setValue:forUndefinedKey:]: this class is not key value
coding-compliant for the key description
upon clicking the tablecell
HOMEVIEWCONTROLLER
class HomeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var tableView:UITableView!
var posts = [Post]()
var db: Firestore!
var postKey:String = ""
private var documents: [DocumentSnapshot] = []
//public var posts: [Post] = []
private var listener : ListenerRegistration!
override func viewDidLoad() {
super.viewDidLoad()
db = Firestore.firestore()
self.navigationController?.navigationBar.isTranslucent = false
tableView = UITableView(frame: view.bounds, style: .plain)
let cellNib = UINib(nibName: "PostTableViewCell", bundle: nil)
tableView.register(cellNib, forCellReuseIdentifier: "postCell")
tableView.backgroundColor = UIColor(white: 0.90,alpha:1.0)
view.addSubview(tableView)
var layoutGuide:UILayoutGuide!
if #available(iOS 11.0, *) {
layoutGuide = view.safeAreaLayoutGuide
} else {
// Fallback on earlier versions
layoutGuide = view.layoutMarginsGuide
}
tableView.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor).isActive = true
tableView.topAnchor.constraint(equalTo: layoutGuide.topAnchor).isActive = true
tableView.trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor).isActive = true
tableView.delegate = self
tableView.dataSource = self
tableView.reloadData()
retrieveAllPosts()
//checkForUpdates()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func handleLogout(_ sender:Any) {
try! Auth.auth().signOut()
self.dismiss(animated: false, completion: nil)
}
func retrieveAllPosts(){
let postsRef = Firestore.firestore().collection("posts").limit(to: 50)
postsRef.getDocuments { (snapshot, error) in
if let error = error {
print(error.localizedDescription)
} else {
if let snapshot = snapshot {
for document in snapshot.documents {
let data = document.data()
// self.postKey = document.documentID
let username = data["username"] as? String ?? ""
let postTitle = data["postTitle"] as? String ?? ""
let postcategory = data["postcategory"] as? String ?? ""
let postContent = data["postContent"] as? String ?? ""
let newSourse = Post( _documentId: document.documentID, _username: username, _postTitle: postTitle, _postcategory: postcategory, _postContent: postContent)
self.posts.append(newSourse)
print(self.postKey)
}
self.tableView.reloadData()
}
}
}
}
/* postsRef.getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
print("\(document.documentID) => \(document.data())")
self.posts = querySnapshot!.documents.flatMap({Post(dictionary: $0.data())})
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
}*/
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.reloadData()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "postCell", for: indexPath) as! PostTableViewCell
cell.set(post: posts[indexPath.row])
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let post = self.posts[indexPath.row]
//print("row selected: \(indexPath.row)")
//Swift.print(post._documentId!)
let postKey = post._documentId
let postName = post._username
print(postKey! + postName!)
performSegue(withIdentifier: "toDetailView", sender: indexPath)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
//segue.forward(posts, to: segue.destination)
guard let details = segue.destination as? PostDetailViewController,
let index = tableView.indexPathForSelectedRow?.row
else {
return
}
details.detailView = posts[index]
}
}
POSTTABLEVIEWCELL
class PostTableViewCell: UITableViewCell {
#IBOutlet weak var usernameLabel: UILabel!
#IBOutlet weak var profileImageView: UIImageView!
#IBOutlet weak var subtitleLabel: UILabel!
#IBOutlet weak var postTextLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
// profileImageView.layer.cornerRadius = profileImageView.bounds.height / 2
// profileImageView.clipsToBounds = true
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func set(post:Post) {
usernameLabel.text = post._username
postTextLabel.text = post._postTitle
subtitleLabel.text = post._postcategory
}
}
POST DETAIL VIEW CONTROLLER
class PostDetailViewController: UIViewController {
#IBOutlet var usernamelabel: UILabel!
#IBOutlet var posttitlelabel: UILabel!
#IBOutlet var postIdlabel: UILabel!
// #IBOutlet var description: UILabel!
#IBOutlet var postcategorylabel: UILabel!
var detailView: Post?
var postId:String = ""
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
postIdlabel?.text = detailView?._documentId
posttitlelabel?.text = detailView?._postTitle
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
This situations usually happens when you have already set IBOutlet in your XIB file and you comment out it's connecting outlets in code.
Here in your case, In your PostDetailViewController
// #IBOutlet var description: UILabel!
You have commented the description Label, but IBOutlet is still connected in your XIB file.
So, Look for your XIB file and checkout for active IBOutlet Connections and remove it for description label, Clean, Build and Run.
Hope it helps.
I am creating a news feed, but nothing is being sent to it. I am currently just testing the gamertag (username), body text, and timestamp. Here are my classes:
1) NewPost (create a new post that is sent to the table view)
import Foundation
import UIKit
import Firebase
import FirebaseDatabase
class NewPost: UIViewController, UITextViewDelegate {
#IBOutlet var enterGamertag: UITextField!
#IBOutlet var enterMessage: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
//ADDTOLIST BUTTON
#IBAction func addToList(_ sender: UIButton) {
// guard let userProfile = UserService.currentProfile else {
return }
let postRef =
Database.database().reference().child("posts").childByAutoId()
let postObject = [
// "Gametag": [
//// "uid": userProfile.id,
//// "gamertag": userProfile.gamerTag
// ],
"gamerTag": enterGamertag.text as Any,
"bodytext": enterMessage.text as Any,
"timestamp": [".sv":"timestamp"]
] as [String:Any]
postRef.setValue(postObject, withCompletionBlock: { error, ref in
if error == nil {
self.dismiss(animated: true, completion: nil)
} else {
// Handle the error
}
})
// UserService.sharedInstance.validateUsername("Ninja")
}
//dismiss keyboard
#IBAction func dismissKeyboard(_ sender: UITextField) {
self.resignFirstResponder()
}
#IBAction func micPressed(_ sender: UIButton) {
if sender.isSelected {
sender.isSelected = false
} else {
sender.isSelected = true
}
}
#IBAction func logOutPressed(_ sender: UIButton) {
try! Auth.auth().signOut()
// performSegue(withIdentifier: "logOut", sender: self)
}
}
2) feedTable (shows the table view)
import UIKit
import Firebase
class FeedTable: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var tableFeedView: UITableView!
var posts = [Post]()
//VIEWDIDLOAD
override func viewDidLoad() {
super.viewDidLoad()
// Hide the navigation bar on the this view controller
tableFeedView.delegate = self
tableFeedView.dataSource = self
tableFeedView.register(UINib(nibName: "PostTableViewCell", bundle: nil), forCellReuseIdentifier: "customTableCell")
// self.tableFeedView?.backgroundColor = UIColor.black
tableFeedView.tableFooterView = UIView()
configureTableView()
}
func observePosts() {
let postRef = Database.database().reference().child("posts")
postRef.observe(.value, with: { snapshot in
var tempPosts = [Post]()
for child in snapshot.children {
if let childSnapshot = child as? DataSnapshot,
let dict = childSnapshot.value as? [String:Any],
let gamerTag = dict["gamerTag"] as? String,
let bodytext = dict["bodytext"] as? String,
let timestamp = dict["timestamp"] as? Double {
let post = Post(id: childSnapshot.key, gamerTag: gamerTag, bodyText: bodytext, timestamp: timestamp)
tempPosts.append(post)
}
}
self.posts = tempPosts
self.tableFeedView.reloadData()
})
}
#IBAction func refreshTable(_ sender: UIButton) {
tableFeedView.reloadData()
}
//Cell For Row At
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:PostTableViewCell = tableView.dequeueReusableCell(withIdentifier: "customTableCell", for: indexPath) as! PostTableViewCell
cell .set(post: posts[indexPath.row])
return cell
}
//Number Of Rows
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
//Automatic Row Height
func configureTableView() {
tableFeedView.rowHeight = UITableViewAutomaticDimension
tableFeedView.estimatedRowHeight = 120.0
}
}
3) PostTableViewCell (the cell that contains the text labels)
import UIKit
class PostTableViewCell: UITableViewCell {
#IBOutlet weak var customMessageBody: UILabel!
#IBOutlet weak var customConsole: UILabel!
#IBOutlet weak var ifMicUsed: UIImageView!
#IBOutlet weak var timeAdded: UILabel!
#IBOutlet weak var gameMode: UILabel!
#IBOutlet weak var customGamerTag: 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
}
func set(post:Post){
customGamerTag.text = post.gamerTag
customMessageBody.text = post.bodyText
customMessageBody.text = "\(post.timestamp) minutes ago."
}
}
I have a problem that I cannot wrap my head around.. You cannot create a button action in a UITableViewController.. So I tried to just control + drag from the button to the detailtableViewController and pressed push.. But when I use prepareForSegue and I then click on the button it should send the button text to a string in the detailtableViewController, but sometimes it's not the correct name, because there are multiple cells in the tableView and the name is not always the same..
What I need it to do is, when you click the button "Button:
It should go to this detailtableViewController:
With the name that is set as text to the Button.
The variable that should receive the name of the button is called viaSegue and it is a string.
My UITableViewController:
class feedTableViewController: UITableViewController, PostCellDelegate {
#IBOutlet weak var loadingSpinner: UIActivityIndicatorView!
#IBOutlet weak var profilePicture: UIImageView!
var sendName = "No name"
var facebookProfileUrl = ""
var dbRef: FIRDatabaseReference!
var updates = [Sweet]()
var gottenUserId : Bool? = false
var gottenUserIdWorkout : Bool? = false
override func viewDidLoad() {
super.viewDidLoad()
let logoImage = UIImageView(frame: CGRect(x:0, y:0, width: 60, height: 32))
logoImage.contentMode = .ScaleAspectFit
let logo = UIImage(named: "logo.png")
logoImage.image = logo
self.navigationItem.titleView = logoImage
loadingSpinner.startAnimating()
if let user = FIRAuth.auth()?.currentUser {
let userId = user.uid
let storage = FIRStorage.storage()
// Refer to your own Firebase storage
let storageRef = storage.referenceForURL("**********")
let profilePicRef = storageRef.child(userId+"/profile_pic.jpg")
// Download in memory with a maximum allowed size of 1MB (1 * 1024 * 1024 bytes)
profilePicRef.dataWithMaxSize(1 * 300 * 300) { (data, error) -> Void in
if (error != nil) {
// Uh-oh, an error occurred!
print("Unable to download image")
} else {
// Data for "images/island.jpg" is returned
// ... let islandImage: UIImage! = UIImage(data: data!)
if (data != nil){
self.profilePicture.image = UIImage(data: data!)
self.profilePicture.layer.cornerRadius = self.profilePicture.frame.size.width/2
self.profilePicture.clipsToBounds = true
}
}
}
}
dbRef = FIRDatabase.database().reference().child("feed-items")
startObersvingDB()
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 205
}
func startObersvingDB() {
FIRDatabase.database().reference().child("feed-items").queryOrderedByChild("date").observeEventType(.Value, withBlock: { (snapshot: FIRDataSnapshot) in
var newUpdates = [Sweet]()
for update in snapshot.children {
let updateObject = Sweet(snapshot: update as! FIRDataSnapshot)
newUpdates.append(updateObject)
}
self.updates = newUpdates.reverse()
self.tableView.reloadData()
}) { (error: NSError) in
print(error.description)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return updates.count
}
protocol PostCellDelegate: class {
func postCell(postCell: PostCell, didTouchUpInside button: UIButton)
}
func postCell(postCell: PostCell, didTouchUpInside button: UIButton) {
let identifier = "toDetailtableViewController"
let username = postCell.nameButton.titleLabel?.text
performSegue(withIdentifier: identifier, sender: username)
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// Lots of stuff happening here
My custom cell:
class updateTableViewCell: UITableViewCell {
#IBOutlet weak var updateLabel: UILabel!
#IBOutlet weak var picView: UIImageView!
#IBOutlet weak var likesLabel: UILabel!
#IBOutlet weak var likeButton: UIButton!
#IBOutlet weak var hand: UIImageView!
#IBOutlet weak var dateLabel: UILabel!
#IBOutlet weak var nameButton: UIButton!
weak var delegate: PostCellDelegate?
var pathDB : String!
var dbRef: FIRDatabaseReference!
var gottenUserId : Bool? = false
var sendNameCell = "No name here"
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 likeTapped(sender: AnyObject) {
//print(pathDB)
checkClickOnLikeButton()
}
#IBAction func didTouchUpInsideButton(sender: AnyObject) {
delegate?.postCell(self, didTouchUpInside: button)
}
func checkClickOnLikeButton() {
let dataPathen = self.pathDB
// print(dataPathen)
if let user = FIRAuth.auth()?.currentUser {
let userId = user.uid
FIRDatabase.database().reference().child("feed-items").child(dataPathen).child("likesForPost").observeSingleEventOfType(.Value, withBlock: { (snapshot) in
// Get user value
self.gottenUserId = snapshot.value![userId] as? Bool
// print(self.gottenUserId)
if self.gottenUserId == true {
print("Der er trykket high five før")
FIRDatabase.database().reference().child("feed-items").child(dataPathen).child("likesForPost").child(userId).removeValue()
let greyButtonColor = UIColor(red: 85/255, green: 85/255, blue: 85/255, alpha: 1.0)
self.likeButton.setTitleColor(greyButtonColor, forState: UIControlState.Normal)
self.hand.image = UIImage(named: "high.png")
} else {
print("Der er IKKE trykket like før")
let quoteString = [userId: true]
FIRDatabase.database().reference().child("feed-items").child(dataPathen).child("likesForPost").updateChildValues(quoteString)
let blueButtonColor = UIColor(red: 231/255, green: 45/255, blue: 60/255, alpha: 1.0)
self.likeButton.setTitleColor(blueButtonColor, forState: UIControlState.Normal)
self.hand.image = UIImage(named: "highfive.png")
}
// ...
}) { (error) in
print(error.localizedDescription)
}
}
}
}
Assuming you have already created a custom class for the cell containing the Button, you must create an #IBAction for the didTouchUpInside event. You must also create a segue directly from the UITableViewController to the detailtableViewController (so not from a button or a view, from one view controller to the other). You will need to give this segue an identifier since we're going to be performing it manually.
Once you've hooked up the #IBAction in the cell, we need a way of performing the segue from the cell. To do this, we need a reference to the UITableViewController. We could get it using delegates or maybe responders, recently I've been using responders.
Delegate
Create a protocol for your UITableViewController to conform to.
protocol PostCellDelegate: class {
func postCell(_ postCell: PostCell, didTouchUpInside button: UIButton)
}
Create a delegate variable in your custom cell class call it's didTouchUpInside method from button's #IBAction for that event.
weak var delegate: PostCellDelegate?
#IBAction func didTouchUpInsideButton() {
delegate?.postCell(self, didTouchUpInside: button)
}
Now in your UITableViewController, you must conform to the delegate and set the delegate of the cells in the cellForRowAt method.
class tableViewController: UITableViewController, PostCellDelegate {
//...
// MARK: PostCellDelegate
func postCell(_ postCell: PostCell, didTouchUpInside button: UIButton) {
let identifier = "toDetailtableViewController"
let username = postCell.button.titleLabel?.text
performSegue(withIdentifier: identifier, sender: username)
}
//...
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
...
cell.delegate = self
return cell
}
//...
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
switch (segue.destination, sender) {
case let (controller as detailtableViewController, username as String):
controller.usernameTextField.text = username
break
default:
break
}
}
}
I have created a navigation menu with four item, now I want to link every item with a view controller, how I can do this?
I have used this tutorial: How to create navigation panel
CenterViewControllerDelegate:
#objc
protocol CenterViewControllerDelegate {
optional func toggleLeftPanel()
optional func collapseSidePanels()
}
class CenterViewController: UIViewController {
#IBOutlet weak private var imageView: UIImageView!
#IBOutlet weak private var titleLabel: UILabel!
#IBOutlet weak private var creatorLabel: UILabel!
var delegate: CenterViewControllerDelegate?
// MARK: Button actions
#IBAction func kittiesTapped(sender: AnyObject) {
delegate?.toggleLeftPanel?()
}
}
extension CenterViewController: SidePanelViewControllerDelegate {
func ItemMenuSelected(ItemMenu: Menu) {
imageView.image = ItemMenu.image
titleLabel.text = ItemMenu.title
creatorLabel.text = ItemMenu.creator
delegate?.collapseSidePanels?()
}
}
SidePanelViewControllerDelegate:
#objc
protocol SidePanelViewControllerDelegate {
func ItemMenuSelected(ItemMenu: Menu)
}
class SidePanelViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
var delegate: SidePanelViewControllerDelegate?
var ItemMenus: Array<Menu>!
struct TableView {
struct CellIdentifiers {
static let MenuCell = "MenuCell"
}
}
func UIColorFromRGB(rgbValue: UInt) -> UIColor {
return UIColor(
red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
blue: CGFloat(rgbValue & 0x0000FF) / 255.0,
alpha: CGFloat(1.0)
)
}
override func viewDidLoad() {
super.viewDidLoad()
var tblView = UIView(frame: CGRectZero)
tableView.tableFooterView = tblView
tableView.tableFooterView!.hidden = true
tableView.backgroundColor = UIColorFromRGB(0xE2F2C9)
tableView.reloadData()
}
}
// MARK: Table View Data Source
extension SidePanelViewController: UITableViewDataSource {
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return ItemMenus.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(TableView.CellIdentifiers.MenuCell, forIndexPath: indexPath) as! MenuCell
cell.configureForMenu(ItemMenus[indexPath.row])
return cell
}
}
// Mark: Table View Delegate
extension SidePanelViewController: UITableViewDelegate {
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let selectedMenu = ItemMenus[indexPath.row]
delegate?.ItemMenuSelected(selectedMenu)
}
}
class MenuCell: UITableViewCell {
#IBOutlet weak var ItemMenuImageView: UIImageView!
#IBOutlet weak var imageNameLabel: UILabel!
#IBOutlet weak var imageCreatorLabel: UILabel!
func configureForMenu(ItemMenu: Menu) {
ItemMenuImageView.image = ItemMenu.image
imageNameLabel.text = ItemMenu.title
imageCreatorLabel.text = ItemMenu.creator
}
}