side menu Help 2 - swift

I'm trying to use tableviewcotroller with this but when look at the screenshot at the button will seen a issue I need helping fixing so if anyone knows how to fix this plz help I don't want use SWRevealViewController I'm also doing with all code not scoreboards thanks for the help
class SidebarView: UIView, UITableViewDelegate, UITableViewDataSource {
var titleArr = [String]()
weak var delegate: SidebarViewDelegate?
override init(frame: CGRect) {
super.init(frame: frame)
self.clipsToBounds=true
titleArr = ["Brittney Atwood", "Messages", "Contact", "Settings", "History", "Help", "Sign Out"]
setupViews()
myTableView.delegate=self
myTableView.dataSource=self
myTableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
myTableView.tableFooterView=UIView()
myTableView.separatorStyle = UITableViewCellSeparatorStyle.none
myTableView.allowsSelection = true
myTableView.bounces=false
myTableView.showsVerticalScrollIndicator=false
myTableView.backgroundView = UIImageView(image: #imageLiteral(resourceName: "Rectangle 96"))
myTableView.isOpaque = false
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return titleArr.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell=tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.backgroundColor = .clear
cell.selectionStyle = .none
if indexPath.row == 0 {
let cellImg: UIImageView!
cellImg = UIImageView(frame: CGRect(x: 15, y: 10, width: 80, height: 80))
cellImg.layer.cornerRadius = 40
cellImg.layer.masksToBounds=true
cellImg.contentMode = .scaleAspectFill
cellImg.layer.masksToBounds=true
cellImg.image=#imageLiteral(resourceName: "user11")
cell.addSubview(cellImg)
let cellLbl = UILabel(frame: CGRect(x: 110, y: cell.frame.height/2-15, width: 250, height: 30))
cell.addSubview(cellLbl)
cellLbl.text = titleArr[indexPath.row]
cellLbl.font=UIFont.systemFont(ofSize: 17)
cellLbl.textColor=UIColor.white
} else {
cell.textLabel?.text=titleArr[indexPath.row]
cell.textLabel?.textColor=UIColor.white
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.delegate?.sidebarDidSelectRow(row: Row(row: indexPath.row))
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.row == 0 {
return 100
} else {
return 60
}
}
func setupViews() {
self.addSubview(myTableView)
myTableView.topAnchor.constraint(equalTo: topAnchor).isActive=true
myTableView.leftAnchor.constraint(equalTo: leftAnchor).isActive=true
myTableView.rightAnchor.constraint(equalTo: rightAnchor).isActive=true
myTableView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive=true
}
let myTableView: UITableView = {
let table=UITableView()
table.translatesAutoresizingMaskIntoConstraints=false
return table
}()
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

Please write this code it may helps to you.
var topSafeArea: CGFloat
var bottomSafeArea: CGFloat
if #available(iOS 11.0, *) {
topSafeArea = view.safeAreaInsets.top
bottomSafeArea = view.safeAreaInsets.bottom
} else {
topSafeArea = topLayoutGuide.length
bottomSafeArea = bottomLayoutGuide.length
}
// safe area values are now available to use
Thank you.

that the view controller I don’t know where the issue is it probably in one of the two files that I post it still not fix
class ViewController: UITableViewController {
var sidebarView: SidebarView!
var blackScreen: UIView!
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Messages"
let btnMenu = UIBarButtonItem(image: #imageLiteral(resourceName: "menu"), style: .plain, target: self, action: #selector(btnMenuAction))
btnMenu.tintColor=UIColor(red: 54/255, green: 55/255, blue: 56/255, alpha: 1.0)
self.navigationItem.leftBarButtonItem = btnMenu
sidebarView=SidebarView(frame: CGRect(x: 0, y: 0, width: 0, height: self.view.frame.height))
sidebarView.delegate=self
sidebarView.layer.zPosition=100
self.view.isUserInteractionEnabled=true
self.navigationController?.view.addSubview(sidebarView)
blackScreen=UIView(frame: self.view.bounds)
blackScreen.backgroundColor=UIColor(white: 0, alpha: 0.5)
blackScreen.isHidden=true
self.navigationController?.view.addSubview(blackScreen)
blackScreen.layer.zPosition=99
let tapGestRecognizer = UITapGestureRecognizer(target: self, action: #selector(blackScreenTapAction(sender:)))
blackScreen.addGestureRecognizer(tapGestRecognizer)
}
#objc func btnMenuAction() {
blackScreen.isHidden=false
UIView.animate(withDuration: 0.3, animations: {
self.sidebarView.frame=CGRect(x: 0, y: 0, width: 250, height: self.sidebarView.frame.height)
}) { (complete) in
self.blackScreen.frame=CGRect(x: self.sidebarView.frame.width, y: 0, width: self.view.frame.width-self.sidebarView.frame.width, height: self.view.bounds.height+100)
}
}
#objc func blackScreenTapAction(sender: UITapGestureRecognizer) {
blackScreen.isHidden=true
blackScreen.frame=self.view.bounds
UIView.animate(withDuration: 0.3) {
self.sidebarView.frame=CGRect(x: 0, y: 0, width: 0, height: self.sidebarView.frame.height)
}
}
}
extension ViewController: SidebarViewDelegate {
func sidebarDidSelectRow(row: Row) {
blackScreen.isHidden=true
blackScreen.frame=self.view.bounds
UIView.animate(withDuration: 0.3) {
self.sidebarView.frame=CGRect(x: 0, y: 0, width: 0, height: self.sidebarView.frame.height)
}
switch row {
case .editProfile:
let vc=EditProfileVC()
self.navigationController?.pushViewController(vc, animated: true)
case .messages:
print("Messages")
case .contact:
print("Contact")
case .settings:
print("Settings")
case .history:
print("History")
case .help:
print("Help")
case .signOut:
print("Sign out")
case .none:
break
// default: //Default will never be executed
// break
}
}
}

Related

Value of type 'SSBadgeButton' has no member 'animationZoom'

I have following productviewcontroller which says "Value of type 'SSBadgeButton' has no member 'animationZoom'" -
import UIKit
class ProductViewController: UIViewController, UITableViewDataSource,
UITableViewDelegate {
let notificationButton = SSBadgeButton()
let rightbarbuttonimage = UIImage(named:"ic_cart")
fileprivate var cart = Cart()
let scrollView = UIScrollView()
let sections = ["Section A", "Section B","Section C", "Section D","Section E","Section F","Section G","Section H", "Section I","Section J","Section K","Section L"]
let rowspersection = [2,3,1,2,2,3,3,1,4,2,1,2]
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
self.tableView.backgroundColor = UIColor.gray
//Add and setup scroll view
self.tableView.addSubview(self.scrollView)
self.scrollView.translatesAutoresizingMaskIntoConstraints = false;
//Constrain scroll view
self.scrollView.leadingAnchor.constraint(equalTo: self.tableView.leadingAnchor, constant: 20).isActive = true;
self.scrollView.topAnchor.constraint(equalTo: self.tableView.topAnchor, constant: 20).isActive = true;
self.scrollView.trailingAnchor.constraint(equalTo: self.tableView.trailingAnchor, constant: -20).isActive = true;
self.scrollView.bottomAnchor.constraint(equalTo: self.tableView.bottomAnchor, constant: -20).isActive = true;
// customising rightBarButtonItems as notificationbutton
notificationButton.frame = CGRect(x: 0, y: 0, width: 44, height: 44)
notificationButton.setImage(UIImage(named: "ic_cart")?.withRenderingMode(.alwaysTemplate), for: .normal)
notificationButton.badgeEdgeInsets = UIEdgeInsets(top: 20, left: 0, bottom: 0, right: 15)
self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: notificationButton)
//following register is needed because I have rightbarbuttonitem customised as uibutton i.e. notificationbutton
notificationButton.addTarget(self, action: #selector(self.registerTapped(_:)), for: .touchUpInside)
}
#objc func registerTapped(_ sender: UIButton) {
self.performSegue(withIdentifier: "showCart", sender: nil)
}
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))"
notificationButton.badge = String(cart.items.count)// making badge equal to no.ofitems in cart
tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// this segue to transfer data
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 productMap.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return productMap[section]?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let product = productMap[indexPath.section]![indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "ProductTableViewCell") as! ProductTableViewCell
cell.imageView?.image = product.imagename
cell.delegate = self as CartDelegate
cell.setButton(state: self.cart.contains(product: product))
return cell
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 44
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
switch(section) {
case 0: return "Section A"
case 1: return "Section B"
case 2: return "Section C"
case 3: return "Section D"
case 4: return "Section E"
case 5: return "Section F"
case 6: return "Section G"
case 7: return "Section H"
case 8: return "Section I"
case 9: return "Section J"
case 10: return "Section K"
case 11: return "Section L"
default: return ""
}
}
}
extension ProductViewController: CartDelegate {
// MARK: - CartDelegate
func updateCart(cell: ProductTableViewCell) {
guard let indexPath = tableView.indexPath(for: cell) else { return }
let product = productMap[indexPath.section]![indexPath.row]
var selectedIndexPaths = [IndexPath]()
if selectedIndexPaths.contains(indexPath) {
if let index = selectedIndexPaths.firstIndex(of: indexPath) {
selectedIndexPaths.remove(at: index)
removeProductFromCart(indexPath: indexPath)
}
} else {
selectedIndexPaths.append(indexPath)
addProductToCart(indexPath: indexPath)
}
addProductToCart(indexPath: indexPath)
//Update Cart with product
cart.updateCart(with: product)
self.navigationItem.rightBarButtonItem?.title = "Checkout (\(cart.items.count))"
notificationButton.badge = String(cart.items.count) // making badge equal to noofitems in cart
}
func addProductToCart(indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? ProductTableViewCell {
if let imageView = cell.imagename {
let initialImageViewFrame = imageView.convert(imageView.frame, to: self.view)
let targetImageViewFrame = self.notificationButton.frame
let imgViewTemp = UIImageView(frame: initialImageViewFrame)
imgViewTemp.clipsToBounds = true
imgViewTemp.contentMode = .scaleAspectFill
imgViewTemp.image = imageView.image
self.view.addSubview(imgViewTemp)
UIView.animate(withDuration: 1.0, animations: {
imgViewTemp.transform = CGAffineTransform(scaleX: 1.5, y: 1.5)
}) { _ in
UIView.animate(withDuration: 0.5, animations: {
imgViewTemp.transform = CGAffineTransform(scaleX: 0.2, y: 0.2).rotated(by: CGFloat(Double.pi))
imgViewTemp.frame = targetImageViewFrame
}) { _ in
imgViewTemp.removeFromSuperview()
UIView.animate(withDuration: 1.0, animations: {
self.notificationButton.transform = CGAffineTransform(scaleX: 1.4, y: 1.4)
}, completion: {_ in
self.notificationButton.transform = CGAffineTransform.identity
})
}
}
}
}
}
func removeProductFromCart(indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? ProductTableViewCell {
if let imageView = cell.imagename {
let initialImageViewFrame = self.notificationButton.frame
let targetImageViewFrame = imageView.convert(imageView.frame, to: self.view)
let imgViewTemp = UIImageView(frame: initialImageViewFrame)
imgViewTemp.clipsToBounds = true
imgViewTemp.contentMode = .scaleAspectFill
imgViewTemp.image = imageView.image
self.view.addSubview(imgViewTemp)
var initialTransform = CGAffineTransform.identity
initialTransform = initialTransform.scaledBy(x: 0.2, y: 0.2)
initialTransform = initialTransform.rotated(by: CGFloat(Double.pi))
UIView.animate(withDuration: 0.5, animations: {
self.notificationButton.animationZoom(scaleX: 1.4, y: 1.4) ***//Error - Value of type 'SSBadgeButton' has no member 'animationZoom'***
imgViewTemp.transform = initialTransform
}) { _ in
UIView.animate(withDuration: 1, animations: {
self.notificationButton.animationZoom(scaleX: 1, y: 1)
imgViewTemp.transform = CGAffineTransform.identity
imgViewTemp.frame = targetImageViewFrame
}) { _ in
imgViewTemp.removeFromSuperview()
}
}
}
}
}
}
This is my code for "SSBadgeButton" -
import UIKit
class SSBadgeButton: UIButton {
var badgeLabel = UILabel()
var badge: String? {
didSet {
addBadgeToButon(badge: badge)
}
}
public var badgeBackgroundColor = UIColor.red {
didSet {
badgeLabel.backgroundColor = badgeBackgroundColor
}
}
public var badgeTextColor = UIColor.white {
didSet {
badgeLabel.textColor = badgeTextColor
}
}
public var badgeFont = UIFont.systemFont(ofSize: 12.0) {
didSet {
badgeLabel.font = badgeFont
}
}
public var badgeEdgeInsets: UIEdgeInsets? {
didSet {
addBadgeToButon(badge: badge)
}
}
override init(frame: CGRect) {
super.init(frame: frame)
addBadgeToButon(badge: nil)
}
func addBadgeToButon(badge: String?) {
badgeLabel.text = badge
badgeLabel.textColor = badgeTextColor
badgeLabel.backgroundColor = badgeBackgroundColor
badgeLabel.font = badgeFont
badgeLabel.sizeToFit()
badgeLabel.textAlignment = .center
let badgeSize = badgeLabel.frame.size
let height = max(18, Double(badgeSize.height) + 5.0)
let width = max(height, Double(badgeSize.width) + 10.0)
var vertical: Double?, horizontal: Double?
if let badgeInset = self.badgeEdgeInsets {
vertical = Double(badgeInset.top) - Double(badgeInset.bottom)
horizontal = Double(badgeInset.left) - Double(badgeInset.right)
let x = (Double(bounds.size.width) - 10 + horizontal!)
let y = -(Double(badgeSize.height) / 2) - 10 + vertical!
badgeLabel.frame = CGRect(x: x, y: y, width: width, height: height)
} else {
let x = self.frame.width - CGFloat((width / 2.0))
let y = CGFloat(-(height / 2.0))
badgeLabel.frame = CGRect(x: x, y: y, width: CGFloat(width), height: CGFloat(height))
}
badgeLabel.layer.cornerRadius = badgeLabel.frame.height/2
badgeLabel.layer.masksToBounds = true
addSubview(badgeLabel)
badgeLabel.isHidden = badge != nil ? false : true
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.addBadgeToButon(badge: nil)
fatalError("init(coder:) has not been implemented")
}
}
Earlier, it used to work fine. It used to zoom the animation Now, I don't know why it does not work fine ? please help me with this. The code also seems okay. still, it does not work fine.

Style content in a TableView without causing the scrolling to lag

I have a TableView, with about 15 to 20 displayed cells. The cell has a Label with the following class:
import Foundation
import UIKit
class RoundedLabel: UILabel {
var inset: CGFloat = 16
override func drawText(in rect: CGRect) {
let insets = UIEdgeInsets(top: 2, left: 2, bottom: 2, right: 2)
super.drawText(in: rect.inset(by: insets))
}
override func layoutSubviews() {
super.layoutSubviews()
updateCornerRadius()
}
override var intrinsicContentSize: CGSize {
let size = super.intrinsicContentSize
return CGSize(
width: size.width + inset,
height: size.height
)
}
#IBInspectable var rounded: Bool = false {
didSet {
updateCornerRadius()
}
}
func updateCornerRadius() {
layer.cornerRadius = rounded ? frame.size.height / 2 : 0
layer.masksToBounds = true
}
}
In my VC I have the following (I have to TableViews in one VC):
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableView == tableViewMainLatest {
let cell = tableViewMainLatest.dequeueReusableCell(withIdentifier: "cellMainLatest", for: indexPath) as! MainLatestTableViewCell
let postDate = posts[indexPath.row].postDate ?? 0
let formattedPostDate = Date(timeIntervalSince1970: postDate)
let timeAgo = formattedPostDate.timeAgo(numericDates: false)
let postCity = posts[indexPath.row].postFromCity ?? "?"
let postCountry = posts[indexPath.row].postFromCountry ?? "?"
let postComments = posts[indexPath.row].comments ?? 0
let maxPostComments: String?
// Only show the number if comment amount is less than 100
if postComments > 99 {
maxPostComments = "99+"
} else {
maxPostComments = String(postComments)
}
cell.labelPostDate.text = timeAgo
cell.labelPostFrom.text = postCity + ", " + postCountry
cell.labelAmountComments.text = maxPostComments
return cell
} else if tableView == tableViewCategories {
let cell = tableViewCategories.dequeueReusableCell(withIdentifier: "cellMainCategories", for: indexPath) as! MainApplicationCategoriesTableViewCell
cell.labelCategories.text = pseudo[indexPath.row] as? String
cell.alpha = 0.55
UIView.animate(withDuration: 0.5, animations: {
cell.alpha = 1
})
return cell
}
return UITableViewCell()
}
My CustomCell:
class MainApplicationCategoriesTableViewCell: UITableViewCell {
// Storyboard
#IBOutlet weak var labelCategories: UILabel! {
didSet {
labelCategories.layer.borderWidth = 1
labelCategories.layer.borderColor = UIColor(red:0.88, green:0.88, blue:0.88, alpha:1.0).cgColor
}
}
override func awakeFromNib() {
super.awakeFromNib()
self.selectionStyle = .none
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
When I use this piece of code:
// Storyboard
#IBOutlet weak var labelCategories: UILabel! {
didSet {
labelCategories.layer.borderWidth = 1
labelCategories.layer.borderColor = UIColor(red:0.88, green:0.88, blue:0.88, alpha:1.0).cgColor
}
}
The scrolling of the TableView is lagging. Where do I have to apply the borderWidth / borderColor, to still have a good user experience without lagging?

Text Overlapping Text That Should've deleted

HI, so this is my vc for a view where I save info about a plane (the type and rego). It saves the plane and deletes and you can close the app and come back and it saves it there in the core data model but I have a weird problem. After you make a plane and it shows in the table view and add a few more planes (table view cell which has info) then the labels which display the info start to overlap with what should be deleted information. The pictures bellow show what I mean. Any help would be greatly appreciated.
var context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
var typeField: UITextField?
var regoField: UITextField?
#IBAction func addPlaneButton(_ sender: Any) {
let alertController = UIAlertController(title: "New Plane", message: "Please Input The Type And Registration", preferredStyle: .alert)
alertController.addTextField(configurationHandler: typeField)
alertController.addTextField(configurationHandler: regoField)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
let saveAction = UIAlertAction(title: "Save", style: .default, handler: self.savePlane)
alertController.addAction(cancelAction)
alertController.addAction(saveAction)
self.present(alertController, animated: true)
print("Add Plane Pressed")
}
func typeField(textField: UITextField!) {
typeField = textField
typeField?.placeholder = "Aircraft Type"
}
func regoField(textField: UITextField!) {
regoField = textField
regoField?.placeholder = "Aircraft Registration"
}
#IBOutlet weak var tableView: UITableView!
var timer = Timer()
let utcItem = UIBarButtonItem()
let utcLbl = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
//Table View
tableView.delegate = self
tableView.dataSource = self
self.tableView.rowHeight = 88
setupView()
}
//////Functions////
func setupView() {
//UTC Time Formatter
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
dateFormatter.dateFormat = "HH:mm"
_ = Timer.scheduledTimer(timeInterval: 0.05, target: self, selector: #selector(updateTime), userInfo: nil, repeats: true)
//UTC Time
utcLbl.frame = CGRect(x: 0, y: 0, width: 100, height: 20)
utcLbl.text = "\(dateFormatter.string(from: Date())) UTC"
utcItem.customView = utcLbl
utcLbl.backgroundColor = UIColor.init(fromHexCode: "4FB7F1")
utcLbl.layer.cornerRadius = 10
utcLbl.textAlignment = .center
utcLbl.layer.masksToBounds = true // Or utcLbl.clipsToBounds = true
self.navigationItem.setLeftBarButtonItems([utcItem], animated: true)
// Large Title
self.title = "Planes"
self.navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedString.Key.font: UIFont(name: "Avenir-Black", size: 35)!]
self.navigationController?.navigationBar.prefersLargeTitles = true
let customBlue = UIColor(red:0.08, green:0.38, blue:0.75, alpha:1.0)
navigationController?.navigationBar.barTintColor = customBlue
}
//Constant UTC Time Lbl
#objc func updateTime() {
let formatter = DateFormatter()
formatter.timeZone = TimeZone(abbreviation: "UTC")
formatter.dateFormat = "HH:mm"
utcLbl.text = formatter.string(from: Date()) + " UTC"
}
//Save the Plane Info
func savePlane(alert: UIAlertAction) {
if typeField?.text != "" || regoField?.text != "" {
let newLog = NSEntityDescription.insertNewObject(forEntityName: "Planes", into: context)
newLog.setValue(self.typeField?.text, forKey: "type")
newLog.setValue(self.regoField?.text, forKey: "rego")
do{
try context.save()
}
catch {
print(error)
}
//Making the table update itself when user logs the plane
self.fetchData()
self.tableView.reloadData()
}
print("Plane Saved")
}
func fetchData() {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
do{
planeArray = try context.fetch(Planes.fetchRequest())
}
catch{
print(error)
}
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
if editingStyle == .delete {
let save = planeArray[indexPath.row]
context.delete(save)
(UIApplication.shared.delegate as! AppDelegate).saveContext()
do {
planeArray = try context.fetch(Planes.fetchRequest())
}
catch {
print(error)
}
tableView.reloadData()
}
}
//Table View Functions
public func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (planeArray.count)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
//Plane Pic
let planeView = UIImageView()
planeView.frame = CGRect(x: 0, y: 0, width: 69, height: 67)
//planeView.center = CGPoint(x: cell.center.x - 150, y: cell.center.y)
planeView.center = CGPoint(x: cell.center.x - 145, y: cell.center.y)
let planeImage: UIImage = UIImage(named: "plane")!
planeView.image = planeImage
cell.addSubview(planeView)
//Type Label
let type = UILabel()
type.frame = CGRect(x: 0, y: 0, width: 45, height: 21)
type.center = CGPoint(x: cell.center.x - 80, y: cell.center.y - 22.5)
type.text = "Type:"
type.font = UIFont(name: "Montserrat-Medium", size: 17)
cell.addSubview(type)
//Type Answer
let typeAnswer = UILabel()
typeAnswer.frame = CGRect(x: 0, y: 0, width: 220, height: 21)
typeAnswer.center = CGPoint(x: cell.center.x + 62.5, y: cell.center.y - 22.5)
typeAnswer.text = ""
typeAnswer.font = UIFont(name: "Montserrat-Light", size: 17)
typeAnswer.textAlignment = .right
cell.addSubview(typeAnswer)
//Rego Label
let rego = UILabel()
rego.frame = CGRect(x: 0, y: 0, width: 110, height: 21)
rego.center = CGPoint(x: cell.center.x - 47.5, y: cell.center.y + 18.5)
rego.text = "Registration:"
rego.font = UIFont(name: "Montserrat-Medium", size: 17)
cell.addSubview(rego)
//rego answer
let regoAnswer = UILabel()
regoAnswer.frame = CGRect(x: 0, y: 0, width: 160, height: 21)
regoAnswer.center = CGPoint(x: cell.center.x + 92.5, y: cell.center.y + 18.5)
regoAnswer.text = ""
regoAnswer.font = UIFont(name: "Montserrat-Light", size: 17)
regoAnswer.textAlignment = .right
cell.addSubview(regoAnswer)
let save = planeArray[indexPath.row]
typeAnswer.text = save.type
regoAnswer.text = save.rego
return cell
}
override func viewWillAppear(_ animated: Bool) {
//Making the table update itself when user logs the plane
fetchData()
tableView.reloadData()
}
}
UITableView reuses the cells. In your case, when the cells are created the first time, you add a UILabel to it. The next time this cell is loaded, UITableView reuses the existing cell and cellForRowAt adds another UILabel to this cell. The proper implementation is to create a custom UITableViewCell and reset the value of all the attributes in cellForRowAt method.
You can try something like below (please note that this is just a rough implementation and it is assumed that you know the basics of ios programming. If that is not the case, I'd recommend researching it a bit):
Add a custom tableview cell
class CustomTableViewCell: UITableViewCell {
#IBOutlet weak var imgViewPlane: UIImageView!
#IBOutlet weak var lblType: UILabel!
#IBOutlet weak var lblTypeAnswer: UILabel!
#IBOutlet weak var lblRego: UILabel!
#IBOutlet weak var lblRegoAnswer: UILabel!
}
Create a dynamic prototype cell in storyboard tableview and link the IBOutlets. Then in your cellForRowAt, do something like this
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomTableViewCell
cell.imgViewPlane.image = planeImage
cell.lblType.text = "Type:"
cell.lblTypeAnswer.text = planeArray[indexPath.row].type
cell.lblRego.text = "Registration:"
cell.lblRegoAnswer.text = planeArray[indexPath.row].rego
return cell
}
You’re adding new subviews to your cell every time that cell is dequeued.
I would recommend you to create these views, labels, etc. as lazy variables inside UITableViewCell subclass and add them as subviews inside awakeFromNib()
class YourCell: UITableViewCell {
lazy var label: UILabel = {
var label = UILabel(...)
...
return label
}()
...
override func awakeFromNib() {
addSubview(label)
...
}
}
.... or use IBOutlet if you’re using storyboard
Then in cellForRowAt just change properties of you downcasted cell subclass’s views
let cell = ... as! YourCell
cell.label.text = ""
cell.anotherLabel.isHidden = true
...

swift 3 table view with slide out menu

I got problem with making table view on the same view with slide menu, could you help me how to do that, I created view controller and embeded navigation controller, now I just want add table vie behind the slide menu and show table view with two section and show data with one custom cell.
#Egle Matutyte, I am supposing that you have done all work except SlideBar.
I am providing code for SlideBar. Just add and try.
First Add the SideBar class i.e. below without any change
import UIKit
#objc protocol SideBarDelegate{
func sideBarDidSelectButtonAtIndex(_ index:Int)
#objc optional func sideBarWillClose()
#objc optional func sideBarWillOpen()
}
class SideBar: NSObject, SideBarTableViewControllerDelegate {
let barWidth:CGFloat = 150.0
let sideBarTableViewTopInset:CGFloat = 64.0
let sideBarContainerView:UIView = UIView()
let sideBarTableViewController:SideBarTableViewController = SideBarTableViewController()
var originView:UIView = UIView()
var animator:UIDynamicAnimator!
var delegate:SideBarDelegate?
var isSideBarOpen:Bool = false
override init() {
super.init()
}
init(sourceView:UIView, menuItems:Array<String>){
super.init()
originView = sourceView
sideBarTableViewController.tableData = menuItems
setupSideBar()
animator = UIDynamicAnimator(referenceView: originView)
let showGestureRecognizer:UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(SideBar.handleSwipe(_:)))
showGestureRecognizer.direction = UISwipeGestureRecognizerDirection.right
originView.addGestureRecognizer(showGestureRecognizer)
let hideGestureRecognizer:UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(SideBar.handleSwipe(_:)))
hideGestureRecognizer.direction = UISwipeGestureRecognizerDirection.left
originView.addGestureRecognizer(hideGestureRecognizer)
}
func setupSideBar(){
//sideBarContainerView.frame = CGRect(x: -barWidth - 1, y: originView.frame.origin.y, width: barWidth, height: originView.frame.size.height)
sideBarContainerView.frame = CGRect(x: -barWidth - 1, y: sideBarTableViewTopInset, width: barWidth, height: originView.frame.size.height)
sideBarContainerView.backgroundColor = UIColor.clear
sideBarContainerView.clipsToBounds = false
originView.addSubview(sideBarContainerView)
let blurView:UIVisualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: UIBlurEffectStyle.light))
blurView.frame = sideBarContainerView.bounds
sideBarContainerView.addSubview(blurView)
sideBarTableViewController.delegate = self
sideBarTableViewController.tableView.frame = sideBarContainerView.bounds
sideBarTableViewController.tableView.clipsToBounds = false
sideBarTableViewController.tableView.separatorStyle = UITableViewCellSeparatorStyle.none
sideBarTableViewController.tableView.backgroundColor = UIColor.clear
sideBarTableViewController.tableView.scrollsToTop = false
//sideBarTableViewController.tableView.contentInset = UIEdgeInsetsMake(sideBarTableViewTopInset, 0, 0, 0)
sideBarTableViewController.tableView.contentInset = UIEdgeInsetsMake(1, 0, 0, 0)
sideBarTableViewController.tableView.reloadData()
sideBarContainerView.addSubview(sideBarTableViewController.tableView)
}
func handleSwipe(_ recognizer:UISwipeGestureRecognizer){
if recognizer.direction == UISwipeGestureRecognizerDirection.left{
showSideBar(false)
delegate?.sideBarWillClose?()
}else{
showSideBar(true)
delegate?.sideBarWillOpen?()
}
}
func showSideBar(_ shouldOpen:Bool){
animator.removeAllBehaviors()
isSideBarOpen = shouldOpen
let gravityX:CGFloat = (shouldOpen) ? 0.5 : -0.5
let magnitude:CGFloat = (shouldOpen) ? 20 : -20
let boundaryX:CGFloat = (shouldOpen) ? barWidth : -barWidth - 1
let gravityBehavior:UIGravityBehavior = UIGravityBehavior(items: [sideBarContainerView])
gravityBehavior.gravityDirection = CGVector(dx: gravityX, dy: 0)
animator.addBehavior(gravityBehavior)
let collisionBehavior:UICollisionBehavior = UICollisionBehavior(items: [sideBarContainerView])
collisionBehavior.addBoundary(withIdentifier: "sideBarBoundary" as NSCopying, from: CGPoint(x: boundaryX, y: 20), to: CGPoint(x: boundaryX, y: originView.frame.size.height))
animator.addBehavior(collisionBehavior)
let pushBehavior:UIPushBehavior = UIPushBehavior(items: [sideBarContainerView], mode: UIPushBehaviorMode.instantaneous)
pushBehavior.magnitude = magnitude
animator.addBehavior(pushBehavior)
let sideBarBehavior:UIDynamicItemBehavior = UIDynamicItemBehavior(items: [sideBarContainerView])
sideBarBehavior.elasticity = 0.3
animator.addBehavior(sideBarBehavior)
}
func sideBarControlDidSelectRow(_ indexPath: IndexPath) {
delegate?.sideBarDidSelectButtonAtIndex(indexPath.row)
showSideBar(false)
}
}
After this, add a new swift class
SideBarTableViewController
which inherit UITableViewController
import UIKit
protocol SideBarTableViewControllerDelegate{
func sideBarControlDidSelectRow(_ indexPath:IndexPath)
}
class SideBarTableViewController: UITableViewController {
var delegate:SideBarTableViewControllerDelegate?
var tableData:Array<String> = []
override func viewDidLoad() {
super.viewDidLoad()
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableData.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell:UITableViewCell? = tableView.dequeueReusableCell(withIdentifier: "Cell")
if cell == nil {
cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")
cell!.backgroundColor = UIColor.clear
cell!.textLabel?.textColor = UIColor.darkText
let selectedView:UIView = UIView(frame: CGRect(x: 0, y: 0, width: cell!.frame.size.width, height: cell!.frame.size.height))
selectedView.backgroundColor = UIColor.black.withAlphaComponent(0.3)
cell!.selectedBackgroundView = selectedView
}
cell!.textLabel?.text = tableData[indexPath.row]
return cell!
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 45
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
delegate?.sideBarControlDidSelectRow(indexPath)
}
}
Now paste the code below in your TableViewController or the page on which you want to add SlideBar.
let the name of your page is Dashboard, add the delegate as below
class Dashboard: UIViewController, SideBarDelegate
{
//declare sidebar
var sideBar:SideBar = SideBar()
override func viewWillAppear(_ animated: Bool)
{
//Initialise the content of SlideBar Row
sideBar = SideBar(sourceView: self.view, menuItems: ["Home", "Dashboard"])
sideBar.delegate = self
}
func sideBarControlDidSelectRow(_ indexPath: IndexPath) {
print("Selected from SlideBar")
}
func sideBarDidSelectButtonAtIndex(_ index: Int)
{
//
}
//Add a button(Optional)in ViewDidLoad()
override func viewDidLoad()
{
super.viewDidLoad()
let btn_Hamburger = UIButton(frame: CGRect(x: 10, y: 70, width: 100, height: 25))
btn_Hamburger.addTarget(self, action: #selector(btn_hamburger(sender:)), for: .touchUpInside)
//add Image on Hamburger button
btn_Hamburger.setImage(#imageLiteral(resourceName: "img_hemberger"), for: .normal)
view.addSubview(btn_Hamburger)
}
//To in and out SideBar menu
var flag:Bool = true
func btn_hamburger(sender: UIButton!)
{
if flag == true {
sideBar.showSideBar(true)
flag = false
}
else{
sideBar.showSideBar(false)
flag = true
}
}
}

UITableViewCell with Custom View

i am desperately trying to add a custom View to a UITableViewCell. I have a UITableViewController in Storyboard wich is linked to a TestTableViewController Class and the prototype cell has the identifier "Cell2".
So this is the code in UITableViewController:
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return dataArray.count
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 190
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell2", forIndexPath: indexPath)
let data = dataArray[indexPath.row]
let ticket = YellowTackleTicketComplete()
ticket.frame = CGRect(x: 20, y: 20, width: 335, height: 150)
cell.addSubview(ticket)
// cell.textLabel!.text = tackl!.valueForKey("title") as? String
cell.backgroundColor = UIColor.clearColor()
print(cell.subviews)
return cell
}
The dataArray is just for testing purposes and has one item in it. So what i get is a Table View with one empty cell. In the Xcode UI Debugger i can see the custom view. But its not shown in the simulator or on a device.
If anyone can help, thank you so much!
This is the code of the view:
class YellowTackleTicketComplete: UIView {
var containerView: UIView!
var ticket: TacklTicket!
var dropDownMenu: YellowDrawer!
var dropDownBackground: YellowDrawerBackground!
var ticketShadowLine: UIView!
var lowAlphaView: UIView!
var outbackButton: UIButton!
var arrowView: UIView!
var bounceHeight: CGFloat?
var dropdownHeight: CGFloat?
var topBorder: CGFloat?
var bottomBorder: CGFloat?
//let arrowLayer = CALayer()
//let layerDelegate = LayerDelegate()
var dropDownElements = [String]()
var dropped = false
var animating = false
var delegate: YellowTackleTicketCompleteDelegate?
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.addObserver(self, forKeyPath: "highlighted", options: NSKeyValueObservingOptions.New, context: nil)
}
override init(frame: CGRect) {
super.init(frame: frame)
self.addObserver(self, forKeyPath: "highlighted", options: NSKeyValueObservingOptions.New, context: nil)
}
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
self.setNeedsDisplay()
if keyPath == "frame" {
// Set up DropdownMenu
self.dropDownBackground.frame.size.height = self.dropDownMenu.frame.maxY
}
}
override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
if(!self.clipsToBounds && !self.hidden && self.alpha > 0.0){
let subviews = self.subviews.reverse()
for member in subviews {
let subPoint = member.convertPoint(point, fromView: self)
if let result:UIView = member.hitTest(subPoint, withEvent:event) {
return result;
}
}
}
return nil
}
func ticketTapped() {
//if !animating {
if !dropped {
showDropdown()
NSLog("#")
// NSLog("Scrolling to \((dropDownMenu.indexPathForSelectedRow?.row)!)(the index of the tableview selection)")
// dropDownMenu.scrollToRowAtIndexPath((dropDownMenu.indexPathForSelectedRow)!, atScrollPosition: .Middle, animated: false)
} else {
hideDropdown()
}
// }
}
func showDropdown() {
dropDownMenu.hidden = false
self.ticket.drawShadowBeneathTicket()
print("showing")
if !animating {
animating = true
UIView.animateWithDuration(
1.0,
delay: 0,
usingSpringWithDamping: 0.7,
initialSpringVelocity: 0.5,
options: [],
animations: {
self.dropDownMenu.frame.origin.y = self.bottomBorder!
}, completion: { _ in
//self.delegate?.menuOpen?()
self.animating = false
print(self.dropDownBackground.frame.size.height)
print(self.dropDownMenu.frame.maxY)
}
)
}
self.setNeedsDisplay()
self.dropDownMenu!.setNeedsDisplay()
dropped = true
}
func hideDropdown() {
if !animating {
animating = true
UIView.animateWithDuration(
0.7,
delay: 0,
usingSpringWithDamping: 0.7,
initialSpringVelocity: 0.5,
options: [],
animations: {
self.dropDownMenu.frame.origin.y = self.topBorder! + self.bounceHeight!
}, completion: nil
)
}
UIView.animateWithDuration(
0.5,
delay: 0,
options: UIViewAnimationOptions.TransitionNone,
animations: {
self.dropDownMenu.frame.origin.y = self.topBorder! - self.dropdownHeight!
}, completion: { _ in
//self.delegate?.menuClosed?()
self.animating = false
self.dropDownMenu.hidden = true
self.ticket.setNeedsDisplay()
self.setNeedsDisplay()
}
)
dropped = false
}
func initSubViews() {
self.topBorder = self.frame.height*6/150
self.bottomBorder = self.frame.height - self.topBorder!
self.bounceHeight = 250
self.dropdownHeight = 350
containerView = UIView()
containerView.frame = CGRect(x: 0, y: topBorder!, width: self.bounds.width, height: dropdownHeight!+bounceHeight!)
containerView.clipsToBounds = true
ticket = TacklTicket()
ticket.frame = self.bounds
ticket.addTarget(self, action: #selector(YellowTackleTicketComplete.ticketTapped), forControlEvents: .TouchDown)
dropDownMenu = YellowDrawer()
dropDownMenu.frame = CGRect(x: 0, y: topBorder! - dropdownHeight!, width: containerView.bounds.width, height: dropdownHeight!)
dropDownMenu.hidden = true
dropDownMenu.backgroundColor = UIColor.clearColor()
dropDownMenu.addObserver(self, forKeyPath: "frame", options: .New, context: nil)
dropDownBackground = YellowDrawerBackground()
dropDownBackground.frame = CGRectMake(0,0,self.bounds.width,self.dropDownMenu.frame.maxY)
self.addSubview(containerView)
containerView.addSubview(dropDownBackground)
containerView.addSubview(dropDownMenu)
self.addSubview(ticket)
}
}
You should use a designated initializer for your UIView subview. That is either init(frame:CGRect) or in add it in Interface Builder. You are also not passing let data = dataArray[indexPath.row] to your cell, not sure if you're aware of that. You also never call initSubViews() which seems to be a big part of your custom view.
instead of
cell.addSubview(ticket)
try
cell.contentView.addSubview(ticket)
and the best place to customize cell's content is its init function.
Couple of things you should try, set translatesAutoresizingMaskIntoConstraints to false on the view you created programmatically since you are inserting it into an auto layout controller.
View that should also try just setting,
dropDownMenu, dropDownBackground, containerView and ticket
or
In your cellForRowAtIndexPath also try setting the property
ticket.translatesAutoresizingMaskIntoConstraints = false