I'm working on creating a 'Rate' feature in my app where it pulls the users to rate from an external API. I then create a TableView which adds cells that contain a section name (the name of the User) and a UISlider.
What I'm trying to do is gather the data from the UISliders along with the User ID associated with the User who's section it is so that I can call a POST action to the API to send the rating data too.
Here's the code I have: (For the record, first time with Swift, the comments are me trying to figure out how to do this). Any ideas?
import UIKit
import Alamofire
class RateViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var submitButton: UIButton!
#IBOutlet weak var activeSurveyLabel: UILabel!
private var myTableView: UITableView!
var usersToRate = [User]()
var activeSurveyId: String?
var rateData = [String: Int]()
var sectionIdToUserId = [Int: String]()
var userIdSection = [Int: String]()
override func viewDidLoad() {
super.viewDidLoad()
submitButton.isHidden = true
submitButton.addTarget(self, action: #selector(pressSubmitButton(button:)), for: UIControlEvents.touchUpInside)
activeSurveyLabel.isHidden = false
self.loadUsersToRate()
Alamofire.request(RateRouter.getSurvey()).responseJSON { response in
debugPrint(response)
if let string = response.result.value as? [[String: Any]]{
if string.count == 0 {
return
}
self.submitButton.isHidden = false
self.activeSurveyLabel.isHidden = true
for survey in string {
if let survey = Survey(json: survey) {
self.activeSurveyId = survey._id!
print(survey._id!)
}
}
//if there's a result, show slider bars for each person on the team with rating scales (except for the person logged in)
//have a submit button with a post request for the votes
let barHeight: CGFloat = UIApplication.shared.statusBarFrame.size.height
let displayWidth: CGFloat = self.view.frame.width
let displayHeight: CGFloat = barHeight * CGFloat(self.usersToRate.count * 5)
self.myTableView = UITableView(frame: CGRect(x: 0, y: barHeight, width: displayWidth, height: displayHeight - barHeight))
self.myTableView.register(UITableViewCell.self, forCellReuseIdentifier: "MyCell")
self.myTableView.dataSource = self
self.myTableView.delegate = self
self.view.addSubview(self.myTableView)
} else {
print(response.result.error!)
let label = UILabel()
label.center = self.view.center
label.text = "No Active Surveys"
self.view.addSubview(label)
}
}
// Do any additional setup after loading the view.
}
func loadUsersToRate() {
Alamofire.request(RateRouter.getUsers()).responseJSON { response in
guard let jsonArray = response.result.value as? [[String: Any]] else {
print("didn't get array, yo")
return
}
for item in jsonArray {
if let user = User(json: item) {
self.usersToRate.append(user)
self.rateData.updateValue(5, forKey: user.userId!) //initialize user average data at 5 in case they don't change it
print (self.rateData)
}
}
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("Num: \(indexPath.row)")
print("Value: \(usersToRate[indexPath.row])")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
self.sectionIdToUserId.updateValue(usersToRate[section].userId!, forKey: section)
print(self.sectionIdToUserId)
return "\(usersToRate[section].name!)"
}
func numberOfSections(in tableView: UITableView) -> Int {
return usersToRate.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath as IndexPath)
let slider = UISlider(frame: CGRect(x: 0, y:0, width: 400, height: 44))
slider.isUserInteractionEnabled = true
slider.minimumValue = 1
slider.maximumValue = 10
slider.value = 5
slider.tag = indexPath.section
slider.addTarget(self, action: #selector(sliderValueChange(sender:)), for: UIControlEvents.valueChanged)
cell.addSubview(slider)
return cell
}
func sliderValueChange(sender: UISlider) {
//get slider value
var currentValue = Int(sender.value)
print(currentValue)
//self.rateData.updateValue(currentValue, forKey: self.sectionIdToUserId.values[sender.])
//get user id for that value
//self.rateData.updateValue(currentValue, rateData[section])
// self.rateData.updateValue(currentValue, forKey: 0)
}
func pressSubmitButton(button: UIButton) {
for user in usersToRate {
// Alamofire.request(RateRouter.vote(voteFor: user.userId!, survey: activeSurveyId, rating:))
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// 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.
}
*/
}
To answer my own question, what I did was create a different model called 'Votes' that stored the information for each vote.
Then to fill that array I created a tag for the slider in the tableView based on the section ID and used that to update the current value.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath as IndexPath)
let slider = UISlider(frame: CGRect(x: 0, y:0, width: cell.frame.width , height: 44))
slider.tag = indexPath.section
slider.addTarget(self, action: #selector(sliderValueChange(sender:)), for: UIControlEvents.valueChanged)
cell.addSubview(slider)
return cell
}
func sliderValueChange(sender: UISlider) {
//get slider value
var currentValue = Int(sender.value)
print(currentValue)
voteData[sender.tag].rating = currentValue
}
Related
I am using third party control for sidemenu named : MMDrawerController, and m handling UI using multiple storyboards.let me come to the point my sidemenu looks like this : Sidemenu Image
Trying to achieve :
1)When I click on the Parent, "main.storyboard" should be displayed.
2)When I click on the Management, "management.storyboard" should be displayed.
same sidemenu should be displayed across all storyboard file.
I have tried some code by my own but m not getting the sidemenu on "management.storyboard" :(
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch(indexPath.row)
{
case 4:
let mainstoryboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
var welview = mainstoryboard.instantiateViewController(withIdentifier: "WelcomeParentViewController") as! WelcomeParentViewController
var welnav = UINavigationController(rootViewController: welview)
var appdel : AppDelegate = UIApplication.shared.delegate as! AppDelegate
appdel.centerContainer!.centerViewController = welnav
appdel.centerContainer!.toggle(MMDrawerSide.left, animated: true, completion: nil)
break
case 5:
let mainstoryboard : UIStoryboard = UIStoryboard(name: "Management-Storyboard", bundle: nil)
var welview = mainstoryboard.instantiateViewController(withIdentifier: "ReportsViewController") as! ReportsViewController
var welnav = UINavigationController(rootViewController: welview)
var appdel : AppDelegate = UIApplication.shared.delegate as! AppDelegate
appdel.centerContainer!.centerViewController = welnav
appdel.centerContainer!.toggle(MMDrawerSide.left, animated: true, completion: nil)
break
default :
break
}
I want same sidemenu across all storyboard file.
how to accomplish the above feature.Please Help.Thank you in advance.
MMDrawerController Code inside the appdelegate.swift
import UIKit
import GoogleMaps
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var centerContainer : MMDrawerController?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
if isUserLoggedIn()
{
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.gotoMainvc()
}
else
{
let rootViewController = self.window!.rootViewController
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let setViewController = mainStoryboard.instantiateViewController(withIdentifier: "LoginViewController") as! LoginViewController
rootViewController?.navigationController?.popToViewController(setViewController, animated: false)
}
return true
}
func isUserLoggedIn() -> Bool{
if let accessToken = UserDefaults.standard.object(forKey: "access_token") as? String
{
if (accessToken.characters.count) > 0{
return true
} else {
return false
}
}
else {
return false
}
}
func gotoMainvc()
{
var rootviewcontroller = self.window?.rootViewController
if(UIDevice.current.userInterfaceIdiom == .phone)
{
let mainstoryboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
var centerviewcontroller = mainstoryboard.instantiateViewController(withIdentifier: "WelcomeParentViewController") as! WelcomeParentViewController
var leftsideviewcontroller = mainstoryboard.instantiateViewController(withIdentifier: "LeftSideMenuViewController") as! LeftSideMenuViewController
let leftsidenav = UINavigationController(rootViewController: leftsideviewcontroller)
let centernav = UINavigationController(rootViewController: centerviewcontroller)
centerContainer = MMDrawerController(center: centernav, leftDrawerViewController: leftsidenav)
centerContainer?.openDrawerGestureModeMask = MMOpenDrawerGestureMode.panningCenterView
centerContainer?.closeDrawerGestureModeMask = MMCloseDrawerGestureMode.panningCenterView
window?.rootViewController = centerContainer
window?.makeKeyAndVisible()
}
else{
let mainstoryboard2 : UIStoryboard = UIStoryboard(name: "Storyboard-iPad", bundle: nil)
var centerviewcontroller = mainstoryboard2.instantiateViewController(withIdentifier: "WelcomeParentViewController") as! WelcomeParentViewController
var leftsideviewcontroller = mainstoryboard2.instantiateViewController(withIdentifier: "LeftSideMenuViewController") as! LeftSideMenuViewController
let leftsidenav = UINavigationController(rootViewController: leftsideviewcontroller)
let centernav = UINavigationController(rootViewController: centerviewcontroller)
centerContainer = MMDrawerController(center: centernav, leftDrawerViewController: leftsidenav)
centerContainer?.openDrawerGestureModeMask = MMOpenDrawerGestureMode.panningCenterView
centerContainer?.closeDrawerGestureModeMask = MMCloseDrawerGestureMode.panningCenterView
window?.rootViewController = centerContainer
window?.makeKeyAndVisible()
}
}
//MARK: sharedDelegate
func sharedDelegate() -> AppDelegate
{
return UIApplication.shared.delegate as! AppDelegate
}
}
Main View Controller
import UIKit
class ViewController: UIViewController , UICollectionViewDelegate , UICollectionViewDataSource , UIGestureRecognizerDelegate {
#IBOutlet weak var collectioncell: UICollectionView!
var objectProfile:SideMenuViewController!
var tapGesture = UITapGestureRecognizer()
override func viewDidLoad() {
super.viewDidLoad()
tapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.myviewTapped(_:)))
tapGesture.numberOfTapsRequired = 1
tapGesture.numberOfTouchesRequired = 1
collectioncell.addGestureRecognizer(tapGesture)
collectioncell.isUserInteractionEnabled = true
let storyboard = UIStoryboard(name: "Main", bundle: nil)
self.objectProfile = storyboard.instantiateViewController(withIdentifier: "SideMenuViewController") as! SideMenuViewController
self.objectProfile.view.frame = CGRect(x: -(self.view.frame.size.width - 40), y: 0, width: self.view.frame.size.width - 40, height: self.view.frame.size.height)
self.view.addSubview(self.objectProfile.view)
self.navigationController?.didMove(toParentViewController: self.objectProfile)
self.collectioncell.layer.cornerRadius = 5.0
self.collectioncell.layer.borderWidth = 5.0
self.collectioncell.clipsToBounds = true
self.collectioncell.layer.borderColor = UIColor.clear.cgColor
self.collectioncell.layer.masksToBounds = true
}
func myviewTapped(_ sender: UITapGestureRecognizer) {
if self.objectProfile.view.isHidden == false {
UIView.animate(withDuration: 0.3)
{
self.objectProfile.view.frame = CGRect(x: -(self.view.frame.size.width - 90), y: 0, width: self.view.frame.size.width - 90, height: self.view.frame.size.height)
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func Mrnupressed(_ sender: UIBarButtonItem) {
UIView.animate(withDuration: 0.3)
{
self.objectProfile.view.frame = CGRect(x: 0 , y: 0, width: (self.view.frame.size.width - 100), height: self.view.frame.size.height)
}
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return 6
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionCell", for: indexPath) as! MainCollectionViewCell
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize {
let cellsize = CGSize(width: (collectioncell.bounds.size.width/2) - 12, height:(collectioncell.bounds.size.height/3) - 20)
return cellsize
}
}
Child View Controller
import UIKit
class SideMenuViewController: UIViewController,UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var sidemenutable: UITableView!
var stri:String!
var ArrarMenu:[String] = ["Home","SiteMep","Student","About Us","Help"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return ArrarMenu.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SideMenuCell") as! SideMenuTableViewCell
let objarray = ArrarMenu[indexPath.row]
cell.lblitem.text = objarray
stri = objarray
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.row == 0{
self.performSegue(withIdentifier: "SegueForHome", sender: self)
}
}
}
In This Code I Am use Child View As Side Manu Controller
here is code open side from other storyboard
#IBAction func menutapped(_ sender: Any) {
var appdelegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
appdelegate.centerContainer?.toggle(MMDrawerSide.left, animated: true, completion: nil)
}
I found an error with my code recently, and after doing everything I could think of to trouble shoot it, I was able to figure out what I believe to be happening. In my app, I have it changing the background color if a user selects that cell, this way you can have multiple cells selected. But if the first cell is selected it will deselect (change the background color) of all the other ones. But it turns out I get the following error:
fatal error: unexpectedly found nil while unwrapping an Optional value
when I try to change the background color of a cell that isn't visible on the screen. I'm assuming this is because only the visible cells are loaded in memory and all the others will only get loaded when they are visible again.
So How would I manually load a cell that I know the IndexPath for but also know it is outside of the view. Also, is there a way to know if cell at an IndexPath is loaded or not?
Here is my current code.
func selectAnyList(tableView: UITableView) {
let sections = frc!.sections!
let currentSection = sections[0]
let numRows = currentSection.numberOfObjects
for i in 0...(numRows - 1) {
let indexPath = IndexPath(row: i, section: 0)
let cell = tableView.cellForRow(at: indexPath) as! ItemListTVCell //This is where the error happens if the cell is not visible
if (i == 0) {
cell.backgroundColor = UIColor.activeAqua.withAlphaComponent(0.85)
} else {
cell.backgroundColor = UIColor.white.withAlphaComponent(0.85)
}
}
}
EDIT: Adding how cell is loaded
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let list: Ent_Lists = frc!.object(at: indexPath)
let cell = tableView.dequeueReusableCell(withIdentifier: "itemListCell", for: indexPath) as! ItemListTVCell
if (list == Ent_Lists.anyList) {
self.anyCell = cell
}
cell.listName.text = list.name
cell.listImage.image = list.image!.uiImage
if ((indexPath as NSIndexPath).row != 0 && listSet!.contains(list)) {
numLists += 1
}
return cell
}
Edit2: Added Image of Ent_List in Coredata.
I have created a small sample file, where you can dynamically set the background color, and every time the one you select will have a different bg color.
import UIKit
// This is your core data entity
struct Entity {
let title: String
}
// This is a basic viewModel, holding the selected property and the core data entity
class EntityViewModel {
let entity: Entity
// Set the selected property to false
var selected: Bool = false
init(entity: Entity) {
self.entity = entity
}
}
class TableViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
lazy fileprivate var entityViewModels: [EntityViewModel] = self.makeEntityViewModels(count: 20)
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
}
}
extension TableViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return entityViewModels.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")!
// Work with viewModels, instead of the CoreData entities directly
let viewModel = entityViewModels[indexPath.row]
// Set the title of the cell
cell.textLabel?.text = viewModel.entity.title
// Based on the selected property, set the background color
cell.backgroundColor = viewModel.selected ? .black : .yellow
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// Reset the selection for all viewModels
entityViewModels.forEach {
$0.selected = false
}
// Get the viewModel at the right indexPath
let viewModel = entityViewModels[indexPath.row]
// Set its selected state to true
viewModel.selected = true
// Reload the tableView -> this will trigger `cellForRowAt`, and your background colors will be up to date
self.tableView.reloadData()
}
}
extension TableViewController {
// This is where you read up from core data
private func makeEntities(count: Int) -> [Entity] {
var entities: [Entity] = []
for index in 0..<count {
entities.append(Entity(title: "\(index) Some title"))
}
return entities
}
// Just wrap the core data objects into viewModels
func makeEntityViewModels(count: Int) -> [EntityViewModel] {
let entities = makeEntities(count: count)
var viewModels: [EntityViewModel] = []
for (index, entity) in entities.enumerated() {
let viewModel = EntityViewModel(entity: entity)
// Intialy, set the first viewModel to selected
if index == 0 {
viewModel.selected = true
}
viewModels.append(viewModel)
}
return viewModels
}
}
I'm trying to create two tableViews in one UIViewController. But when I'm trying to assign value to UILabel, getting an error: fatal error: unexpectedly found nil while unwrapping an Optional value
I wonder why, I have almost the same code for TableViewController with one tableView and it works with no issues. It looks like these UI Labels are not initialized when trying to assign value to it. But don't understand how to fix it.
It fails here:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell: UITableViewCell?
if tableView == self.guestsTableView {
let cell = tableView.dequeueReusableCell(withIdentifier: "guestCell", for: indexPath) as! GuestAtTableTableViewCell
if let guestsTable = guestsTableFetchedResultsController?.object(at: indexPath) {
print(guestsTable.guestName) // works fine, prints the value
print(cell.guestNameLabel.text) //fails here with error fatal error: unexpectedly found nil while unwrapping an Optional value
cell.guestNameLabel.text = guestsTable.guestName
cell.openTimeLabel.text = String(describing: guestsTable.openTime)
cell.cellDelegate = self
}
}
else if tableView == self.ordersTableView {
cell = tableView.dequeueReusableCell(withIdentifier: "orderCell", for: indexPath)
//to be done
}
// Configure the cell...
return cell!
}
Full code of this class:
import UIKit
import CoreData
class TableUIViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, CellWithButtonDelegate {
//The following two variables will not be nil because prepare for segue will set them
var tableName: String?
var table: TablesTable? = nil
fileprivate var currentTableSession: TableSessionTable? {
get {
let tableSessionTable = TableSessionTable()
return tableSessionTable.getCurrentTableSession(table: table!)
}
}
fileprivate var guestsTableFetchedResultsController: NSFetchedResultsController<GuestsTable>?
fileprivate var ordersTableFetchedResultsController: NSFetchedResultsController<OrdersTable>?
#IBOutlet weak var tableNameLabel: UILabel!
#IBOutlet weak var tableCapacityLabel: UILabel!
#IBOutlet weak var tableCountOfGuestsLabel: UILabel!
#IBOutlet weak var tableDescriptionTextView: UITextView!
#IBAction func closeTableButtonPressed(_ sender: UIButton) {
}
#IBOutlet weak var guestsTableView: UITableView!
#IBOutlet weak var ordersTableView: UITableView!
#IBAction func addGuestButtonPressed(_ sender: UIButton) {
let guestsTable = GuestsTable()
let tablesTable = TablesTable()
let table = Table(tableName: tableName!, tableCapacity: 0, locationX: nil, locationY: nil, tableImage: nil)
try? guestsTable.addNewGuest(table: tablesTable.getOrCreateTable(table: table))
updateUI()
}
#IBAction func addOrderButtonPressed(_ sender: UIButton) {
}
override func viewDidLoad() {
guestsTableView.dataSource = self
guestsTableView.delegate = self
guestsTableView.register(GuestAtTableTableViewCell.self, forCellReuseIdentifier: "guestCell")
ordersTableView.dataSource = self
ordersTableView.delegate = self
ordersTableView.register(UITableViewCell.self, forCellReuseIdentifier: "orderCell")
updateUI()
}
func didPressButton(table: TablesTable) {
}
private func updateUI () {
let tableView = guestsTableView
let context = AppDelegate.viewContext
let request : NSFetchRequest<GuestsTable> = GuestsTable.fetchRequest()
request.predicate = NSPredicate(format: "table= %#", currentTableSession!)
request.sortDescriptors = [NSSortDescriptor(key: "guestName", ascending: true, selector: #selector(NSString.localizedCaseInsensitiveCompare(_:)))]
guestsTableFetchedResultsController = NSFetchedResultsController<GuestsTable>(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
try? guestsTableFetchedResultsController?.performFetch()
tableView?.reloadData()
}
private func updateUI1 () {
let tableView = ordersTableView
let context = AppDelegate.viewContext
let request : NSFetchRequest<OrdersTable> = OrdersTable.fetchRequest()
request.sortDescriptors = [NSSortDescriptor(key: "menuItem", ascending: true, selector: #selector(NSString.localizedCaseInsensitiveCompare(_:)))]
ordersTableFetchedResultsController = NSFetchedResultsController<OrdersTable>(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
try? ordersTableFetchedResultsController?.performFetch()
tableView?.reloadData()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell: UITableViewCell?
if tableView == self.guestsTableView {
let cell = tableView.dequeueReusableCell(withIdentifier: "guestCell", for: indexPath) as! GuestAtTableTableViewCell
if let guestsTable = guestsTableFetchedResultsController?.object(at: indexPath) {
print(guestsTable.guestName) // works fine, prints the value
print(cell.guestNameLabel.text) //fails here with error fatal error: unexpectedly found nil while unwrapping an Optional value
cell.guestNameLabel.text = guestsTable.guestName
cell.openTimeLabel.text = String(describing: guestsTable.openTime)
cell.cellDelegate = self
}
}
else if tableView == self.ordersTableView {
cell = tableView.dequeueReusableCell(withIdentifier: "orderCell", for: indexPath)
//to be done
}
// Configure the cell...
return cell!
}
func numberOfSections(in tableView: UITableView) -> Int {
if tableView == self.guestsTableView {
return guestsTableFetchedResultsController?.sections?.count ?? 1
}
else if tableView == self.ordersTableView {
return ordersTableFetchedResultsController?.sections?.count ?? 1
}
else {return 1}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView == self.guestsTableView {
if let sections = guestsTableFetchedResultsController?.sections, sections.count > 0 {
return sections[section].numberOfObjects
}
else {
return 0
}
}
else if tableView == self.ordersTableView {
if let sections = ordersTableFetchedResultsController?.sections, sections.count > 0 {
return sections[section].numberOfObjects
}
else {
return 0
}
}
else {return 0}
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if tableView == self.guestsTableView {
if let sections = guestsTableFetchedResultsController?.sections, sections.count > 0 {
return sections[section].name
}
else {
return nil
}
}
else if tableView == self.ordersTableView {
if let sections = ordersTableFetchedResultsController?.sections, sections.count > 0 {
return sections[section].name
}
else {
return nil
}
}
else {return nil}
}
func sectionIndexTitles(for tableView: UITableView) -> [String]? {
if tableView == guestsTableView {
return guestsTableFetchedResultsController?.sectionIndexTitles
}
else {
return ordersTableFetchedResultsController?.sectionIndexTitles
}
}
func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int {
if tableView == guestsTableView {
return guestsTableFetchedResultsController?.section(forSectionIndexTitle: title, at: index) ?? 0
}
else if tableView == ordersTableView {
return ordersTableFetchedResultsController?.section(forSectionIndexTitle: title, at: index) ?? 0
}
else {return 0}
}
}
And full code of UITableViewCell class:
import UIKit
class GuestAtTableTableViewCell: UITableViewCell {
weak var cellDelegate: CellWithButtonDelegate?
#IBOutlet weak var guestNameLabel: UILabel!
#IBOutlet weak var openTimeLabel: UILabel!
#IBAction func didPressButton(_ sender: UIButton) {
}
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
}
}
I guess you have a xib for your UITableViewCell register the xib instead of the class.
Use the following:
guestsTableView.register(UINib.init(nibName: "GuestAtTableTableViewCell", bundle: nil), forCellReuseIdentifier: "guestCell")
As you have created a prototype cell in the storyboard itself you should select the cell in the storyboard and set its identifier there. Next remove the register line from your code for guestCell. It should work
It's been awhile since I've made a fool of myself here, so here goes again as I'm still trying to learn and feel as though I'm chasing my tail on this project.
With that said, ultimately I would like to get Jerkoch's SwipeCellKit to work, but not necessary at this point as I just need to figure out how to add more options other than just the 'delete' cell action.
This is what I've got: My Project
This is what I'd like: Jerkoch's Project
I loose my data if I set the delegate property on tableView from
let cell = tableView.dequeueReusableCell(withIdentifier: "CommentCell", for: indexPath) as! CommentTableViewCell
to
let cell = tableView.dequeueReusableCell(withIdentifier: "CommentCell", for: indexPath) as! SwipeTableViewCell
Here is my CommentViewController Code:
import UIKit
import SwipeCellKit
class CommentViewController: UIViewController {
var postId: String!
var comments = [Comment]()
var users = [User]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.tableFooterView = UIView(frame: CGRect.zero)
tableView.separatorInset = UIEdgeInsets.zero
tableView.dataSource = self
tableView.estimatedRowHeight = 100
tableView.rowHeight = UITableViewAutomaticDimension
loadComments()
}
func loadComments() {
Api.Post_Comment.REF_POST_COMMENTS.child(self.postId).observe(.childAdded, with: {
snapshot in
Api.Comment.observeComments(withPostId: snapshot.key, completion: {
comment in
self.fetchUser(uid: comment.uid!, completed: {
self.comments.append(comment)
self.tableView.reloadData()
})
})
})
}
func fetchUser(uid: String, completed: #escaping () -> Void ) {
Api.User.observeUser(withId: uid, completion: {
user in
self.users.append(user)
completed()
})
}
}
extension CommentViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return comments.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CommentCell", for: indexPath) as! CommentTableViewCell// Can't update this to SwipeTableViewCell - Will loose data
cell.selectedBackgroundView = createSelectedBackgroundView()
let comment = comments[indexPath.row]
let user = users[indexPath.row]
cell.comment = comment
cell.user = user
cell.delegate = self
return cell
}
}
extension CommentViewController: SwipeTableViewCellDelegate{
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]? {
guard orientation == .right else { return nil }
let deleteAction = SwipeAction(style: .destructive, title: "Delete") { action, indexPath in
// handle action by updating model with deletion
}
// customize the action appearance
deleteAction.image = UIImage(named: "delete")
let flagAction = SwipeAction(style: .destructive, title: "Flag") { action, indexPath in
// handle action
}
deleteAction.image = UIImage(named: "flag")
let blockAction = SwipeAction(style: .destructive, title: "Block") { action, indexPath in
// handle action
}
deleteAction.image = UIImage(named: "block")
return [deleteAction, flagAction, blockAction]
}
}
I've even tried something like the following:
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
// THIS GIVES THE DEFAULT 'DELETE' ACTION
print("Commit editingStyle")
}
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
print("editActionsForRowAtIndexPath")
let blockAction = UITableViewRowAction(style: UITableViewRowActionStyle.normal, title: "Block", handler: { (action:UITableViewRowAction, IndexPath:IndexPath) in
//self.isEditing = false
print("Block action Pressed")
})
let flagAction = UITableViewRowAction(style: UITableViewRowActionStyle.normal, title: "Flag", handler: { (action:UITableViewRowAction, IndexPath:IndexPath) in
print("Flag action Pressed")
})
let deleteAction = UITableViewRowAction(style: UITableViewRowActionStyle.destructive, title: "Delete", handler: { (action:UITableViewRowAction, IndexPath:IndexPath) in
print("Delete action Pressed")
})
return [blockAction, flagAction, deleteAction]
}
No matter what I do, I can't get more than just the generic 'Delete' action to show on a swipe action.
I don't even think the following function is being called/referenced:
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
What am I doing wrong, or what do I need to CUD to get 3 swipe actions; Delete, Flag and Block, to make Apple happy for my next submission.
Thank you all in advance!
This question is outdated but i'll write the answer which i think would have done the trick :)
You should be using UITableViewController not UIViewController for your view. SwipeCellKit only works with TableViewControllers.
I know that this question has answered in this site But I tried the code and receive an Error please help me to show my camera roll in a collection view (I know that I have to add photo usage in info.plist please Just focus on my codes thanks!!!)
here is my view controller code
class translateViewController: UIViewController , UINavigationControllerDelegate , UIImagePickerControllerDelegate , UICollectionViewDataSource, UICollectionViewDelegate {
#IBOutlet var myimageView: UIImageView!
#IBAction func importImage(_ sender: Any) {
let image = UIImagePickerController()
image.delegate = self
image.sourceType = UIImagePickerControllerSourceType.photoLibrary
image.allowsEditing = false
self.present(image , animated: true)
{
}
}
#IBOutlet weak var cameraRollCollectionView: UICollectionView!
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage{
myimageView.image = image
}
else {
print("Error")
}
self.dismiss(animated: true, completion: nil)
}
#IBOutlet var translatebackgroundimg: UIImageView!
#IBOutlet var translatefrontimg: UIImageView!
var assetCollection: PHAssetCollection!
var photosAsset: PHFetchResult<AnyObject>!
var assetThumbnailSize: CGSize!
override func viewDidLoad() {
super.viewDidLoad()
let fetchOptions = PHFetchOptions()
let collection:PHFetchResult = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: fetchOptions)
if let first_Obj:AnyObject = collection.firstObject{
//found the album
self.assetCollection = first_Obj as! PHAssetCollection
}
let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.light)
let blurView = UIVisualEffectView(effect: blurEffect)
blurView.frame = CGRect(x: self.translatebackgroundimg.frame.origin.x, y: self.translatebackgroundimg.frame.origin.y, width: self.translatebackgroundimg.frame.size.width, height: self.translatebackgroundimg.frame.size.height)
blurView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.translatebackgroundimg.addSubview(blurView)
// Do any additional setup after loading the view.
translatefrontimg.image = UIImage(named: "Translate.png")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewDidAppear(_ animated: Bool) {
let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.dark)
let blurView = UIVisualEffectView(effect: blurEffect)
blurView.frame = translatebackgroundimg.bounds
translatebackgroundimg.addSubview(blurView)
translatebackgroundimg.frame = self.view.bounds
}
override func viewWillAppear(_ animated: Bool) {
// Get size of the collectionView cell for thumbnail image
if let layout = self.cameraRollCollectionView!.collectionViewLayout as? UICollectionViewFlowLayout{
let cellSize = layout.itemSize
self.assetThumbnailSize = CGSize(width: cellSize.width, height: cellSize.height)
}
//fetch the photos from collection
self.photosAsset = (PHAsset.fetchAssets(in: self.assetCollection, options: nil) as AnyObject!) as! PHFetchResult<AnyObject>!
self.cameraRollCollectionView!.reloadData()
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of items
var count: Int = 0
if(self.photosAsset != nil){
count = self.photosAsset.count
}
return count;
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cameraCell", for: indexPath as IndexPath)
//Modify the cell
let asset: PHAsset = self.photosAsset[indexPath.item] as! PHAsset
PHImageManager.default().requestImage(for: asset, targetSize: self.assetThumbnailSize, contentMode: .aspectFill, options: nil, resultHandler: {(result, info)in
if result != nil {
cameraCell.userImage.image = result
}
})
return cell
}
// MARK: - UICollectionViewDelegateFlowLayout methods
func collectionView(collectinView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
return 4
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
return 1
}
// UIImagePickerControllerDelegate Methods
func imagePickerControllerDidCancel(_ picker: UIImagePickerController){
picker.dismiss(animated: true, completion: nil)
}
and here is my CollectionViewCell codes
class cameraCell: UICollectionViewCell , UIImagePickerControllerDelegate {
#IBOutlet weak var userImage: UIImageView!
func configurecell(image: UIImage){
userImage.image = image
}
}