Table Cells Are A Big - ios

I'm going to make this as clear as possible. In my Xcode project, I am reusing a prototype cell and I want each cell to open a different view controller. How would you guys think I would be able to do that?
Here is a pic of the reusable cell in my Main.storyboard:
Here is the result of the cells being reused:
And here is the code of my controller class:
import UIKit
class NewsTableViewController: UITableViewController {
#IBOutlet var menuButton:UIBarButtonItem!
#IBOutlet var extraButton:UIBarButtonItem!
override func viewDidLoad() {
super.viewDidLoad()
tableView.estimatedRowHeight = 242.0
tableView.rowHeight = UITableViewAutomaticDimension
if revealViewController() != nil {
menuButton.target = revealViewController()
menuButton.action = #selector(SWRevealViewController.revealToggle(_:))
revealViewController().rightViewRevealWidth = 150
extraButton.target = revealViewController()
extraButton.action = #selector(SWRevealViewController.rightRevealToggle(_:))
view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// Return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of rows
return 3
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! NewsTableViewCell
// Configure the cell...
if indexPath.row == 0 {
cell.postImageView.image = UIImage(named: "watchkit-intro")
cell.postTitleLabel.text = "WatchKit Introduction: Building a Simple Guess Game"
} else if indexPath.row == 1 {
cell.postImageView.image = UIImage(named: "custom-segue-featured-1024")
cell.postTitleLabel.text = "Building a Chat App in Swift Using Multipeer Connectivity Framework"
} else {
cell.postImageView.image = UIImage(named: "webkit-featured")
cell.postTitleLabel.text = "A Beginner’s Guide to Animated Custom Segues in iOS 8"
}
return cell
}
}
To be clear, I want each cell in pic 2 to open a different view controller. For example, I would want Cell 1 to open New View Controller 1, Cell 2 to open New View Controller 2, and Cell 3 to open New View Controller 3.
Thanks for reading!

I think you should implement tableview's delegate method
e.g.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
if indexPath.row == 0
{
// open VC1
}
else if indexPath.row == 1
{
// open VC2
}
else if indexPath.row == 2
{
// open VC3
}
}

i think it something like this
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath.row {
case 0:
// segue to view 1
case 1:
// segue to view 2
case 2:
// segue to view 3
case 3:
// segue to view 4
default:
// default go here
}
}

You would have to implement tableView(_:, didSelectRowAt:):
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.row == 0 {
let newViewController1 = ...
present(newViewController1, animated: true, completion: nil)
} else if indexPath.row == 1 {
let newViewController2 = ...
present(newViewController2, animated: true, completion: nil)
} else {
let newViewController3 = ...
present(newViewController3, animated: true, completion: nil)
}
}
Alternatively, you could add a gesture recognizer to your table view cells and implement a custom cell delegate. It doesn't seem like that would be necessary in your situation though, so I won't recommend it. It seems like it may be overkill. If you're interested, though:
class NewsTableViewCell: UITableViewCell {
var delegate: NewsTableViewCellDelegate?
override func awakeFromNib() {
let recognizer = UIGestureRecognizer(target: self, action: #selector(tapped))
contentView.addGestureRecognizer(recognizer)
}
func tapped() {
delegate?.cellTapped(self)
}
}
protocol NewsTableViewCellDelegate {
func cellTapped(_ cell: NewsTableViewCell)
}
extension MyViewController: NewsTableViewCellDelegate {
func cellTapped(_ cell: NewsTableViewCell) {
if cell == cell1 { }
else if cell == cell2 { }
else if cell == cell3 { }
//You would have to manually determine how to check if a cell is cell1, cell2, or cell3, since you wouldn't have an indexPath available.
}
}

For both the error,
Remove segue from main.storyboard because you are using segue from storyboard but in code work you presenting your ViewConroller.
In code work, replace your lines by below
**
`let storyboard = UIStoryboard(name: "main.Storyboard", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier:"myViewController") as! UIViewController
self.present(controller, animated: true, completion: nil)`
**
If you are pushing your VC, then use this below code:
let myViewController = self.storyboard?.instantiateViewController(withIdentifier: "myViewController") as! Conversation_VC
self.navigationController?.pushViewController(myViewController, animated: true)

Related

Change button title in section of tableview on specific row

I have view controller in which there are multiple section of tableview. In section 0 I have multiple row . Each row having button named as Add Comments when I click on button it pushes me to other view controller having text field when i wrote something and press done button then through delegate I passes textfield data and set it in button title. But problem is my button present in all row changes value. I want only selected row in section changes its button title. below is my code of first viewcontroller
class MyTabViewController: UIViewController {
var addCommentsValueStore: String = "Add Comments"
#IBOutlet weak var tabTableView : ContentWrappingTableView!
#IBAction func addCommentsAction(_ sender: UIButton) {
guard let nextVC = MyCommentsRouter.getMyCommentsViewScreen() else { return }
nextVC.passAddCommentsDelegate = self
self.navigationController?.pushViewController(nextVC, animated: true)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if(indexPath.section == 0)
{
let indetifier = "MyTabTableViewCell"
let cell = tableView.dequeueReusableCell(withIdentifier: indetifier, for: indexPath) as! MyTabTableViewCell
cell.addCommentsButton.setTitle(addCommentsValueStore, for: UIControl.State.normal)
}
return cell
}
extension MyTabViewController: AddCommentsDelegate{
func passAddComments(instruction: String) {
addCommentsValueStore = instruction
print(addCommentsValueStore)
}
}
}
below is code of second view controller:
import UIKit
protocol AddCommentsDelegate{
func passAddComments(instruction: String)
}
class MyCommentsViewController: UIViewController {
#IBOutlet var addCommentsTextField: UITextField!
var passAddCommentsDelegate: AddCommentsDelegate?
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func backActionClick(_ sender: UIButton) {
self.navigationController?.popViewController(animated: true)
}
#IBAction func DoneActionClick(_ sender: Any) {
let dataToBeSent = addCommentsTextField.text
self.passAddCommentsDelegate?.passAddComments(instruction: dataToBeSent!)
self.navigationController?.popViewController(animated: true)
}
}
by using tag on the cell button, you can fix your problem.
on your cellForRowAt delegate method, put this line:
cell.addCommentsButton.tag = indexPath.item
now you know exactly which button did select, then you can use this tag to specify which row in your tableView should change its title.
your implementation has some problems:
first of all, the addCommentsValueStore have to be an array of strings.
var addCommentsValueStore: [String] = []
then tell the delegate to show the right title:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell: MyTabTableViewCell!
if (indexPath.section == 0) {
cell = tableView.dequeueReusableCell(withIdentifier: "MyTabTableViewCell", for: indexPath) as! MyTabTableViewCell
cell.tag = indexPath.item
cell.addCommentsButton.setTitle(addCommentsValueStore[indexPath.item], for: UIControl.State.normal)
}
return cell
}
the AddCommentsDelegate should return the index too:
protocol AddCommentsDelegate {
func passAddComments(instruction: String, atIndex: Int)
}
then every time you want to pass comment to another viewController, you should pass the index too.
by using this index, you will specify where you should change the row button title.
#UIBotton func DoneActionClick(_ sender: UIButton) {
let dataToBeSent = addCommentsTextField[sender.tag].text
self.passAddCommentsDelegate?.passAddComments(instruction: dataToBeSent!, atIndexPath: sender.tag)
self.navigationController?.popViewController(animated: true)
}

How to remove row in UITableViewController presented as popover

I have a custom UITableViewController that I present as a popover in my app. In some of the cells there is a delete button (trash can) to remove that item. Everything works as it should except that I the UI is not update when pressing the delete button. That is, the data is cleared and I call self.tableView.reloadData(), but the cell remains visible in the UI. (Pressing the delete button again makes the app crash in my C++ code because of an assert). I have no storyboard or xib as I do not need it. I only want this to be in code.
What am I missing? It might be something simple, but I cannot fathom why. I have tried:
Separate data source implementation.
Calling reloadData() both sync and async.
Setting delegate to self.
Various other hacks.
Here is the UITableViewController implementation:
import Foundation
class IngredientInfoPopoverViewController : UITableViewController
{
var slViewController: ShoppingListViewController?;
var ingredientName: String = "Ingrediens";
#IBOutlet var uniqueIngredients: [Ingredient] = []; // Unique per *recipe* so that we can list all the recipes for the ingredients
var clickedCellIndexPath: IndexPath? = nil;
enum SECTIONS : Int
{
case HEADER = 0;
case RECIPE = 1;
}
static let ROW_HEIGHT = 44;
override func viewDidLoad()
{
super.viewDidLoad();
tableView.register(UINib(nibName: "OpenIngredientInfoCell", bundle: nil), forCellReuseIdentifier: "OpenIngredientInfoCell");
tableView.register(UINib(nibName: "OpenRecipeCell", bundle: nil), forCellReuseIdentifier: "OpenRecipeCell");
tableView.separatorStyle = .singleLine;
tableView.bounces = false; // "Static" table view
updateSize();
}
func updateSize()
{
let totalCount = min(uniqueIngredients.count + 1, 6); // + 1: header row. min: Allow max 5 recipes in list (enables scrolling)
self.preferredContentSize = CGSize(width: 300, height: totalCount * IngredientInfoPopoverViewController.ROW_HEIGHT);
}
func setup(slvc: ShoppingListViewController?, ingredients: [Ingredient], clickedCellIndexPath: IndexPath)
{
self.slViewController = slvc;
self.clickedCellIndexPath = clickedCellIndexPath;
if (ingredients.count > 0)
{
let first = ingredients[0];
for i in ingredients
{
assert(i.getId() == first.getId());
}
ingredientName = first.getName();
var uniqueRecipeNames: Set<String> = [];
for i in ingredients
{
uniqueRecipeNames.insert(i.getRecipeName());
}
let sorted = uniqueRecipeNames.sorted();
uniqueIngredients.removeAll();
for s in sorted
{
for i in ingredients
{
if (i.getRecipeName() == s)
{
uniqueIngredients.append(i);
break;
}
}
}
}
}
override func numberOfSections(in tableView: UITableView) -> Int
{
return 2;
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
switch section
{
case SECTIONS.HEADER.rawValue:
return 1;
case SECTIONS.RECIPE.rawValue:
return uniqueIngredients.count;
default:
assert(false);
return 0;
}
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
switch (indexPath.section)
{
case SECTIONS.HEADER.rawValue:
assert(indexPath.row == 0);
if (uniqueIngredients.count > 0)
{
let ingredient = uniqueIngredients[0]; // All are the same ingredient
self.dismiss(animated: true, completion: nil);
slViewController?.onIngredientInfoButtonClicked(ingredient);
}
break;
case SECTIONS.RECIPE.rawValue:
if (indexPath.row < uniqueIngredients.count)
{
let ingredient = uniqueIngredients[indexPath.row];
self.dismiss(animated: true, completion: nil);
slViewController?.onRecipeInfoButtonClicked(ingredient);
}
break;
default:
break;
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = UITableViewCell();
switch (indexPath.section)
{
case SECTIONS.HEADER.rawValue:
if (uniqueIngredients.count > 0)
{
let ingredient = uniqueIngredients[0];
let cell = tableView.dequeueReusableCell(withIdentifier: "OpenIngredientInfoCell", for: indexPath) as! OpenIngredientInfoCell;
cell.setup(ingredient);
}
break;
case SECTIONS.RECIPE.rawValue:
if (indexPath.row < uniqueIngredients.count)
{
cell.selectionStyle = .none; // Without this the cell contents become gray and disappear when long pressing! FML
let ingredient = uniqueIngredients[indexPath.row];
let cell = tableView.dequeueReusableCell(withIdentifier: "OpenRecipeCell", for: indexPath) as! OpenRecipeCell;
cell.setup(self, ingredient, clickedCellIndexPath);
}
break;
default:
break;
}
return cell;
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
return CGFloat(IngredientInfoPopoverViewController.ROW_HEIGHT);
}
func ingredientRemoved(_ ingredient: Ingredient)
{
for i in 0..<uniqueIngredients.count
{
if (uniqueIngredients[i].getRecipeId() == ingredient.getRecipeId())
{
uniqueIngredients.remove(at: i);
// let indexPath = IndexPath(row: i, section: SECTIONS.RECIPE.rawValue);
// self.tableView.deleteRows(at: [indexPath], with: .fade);
DispatchQueue.main.async {
self.tableView.reloadData();
}
break;
}
}
if (uniqueIngredients.count == 0)
{
self.dismiss(animated: true, completion: nil);
}
else
{
DispatchQueue.main.async {
self.tableView.reloadData();
}
}
}
}
Here is how I present the IngredientInfoPopoverViewController:
#objc func ingredientInfoClicked(_ sender: UITapGestureRecognizer)
{
let tapLocation = sender.location(in: self.tableView)
let indexPath = self.tableView.indexPathForRow(at: tapLocation)!
let ingredients = CppInterface.shoppingList.getIngredients(UInt(indexPath.section), position: UInt(indexPath.row));
let controller = IngredientInfoPopoverViewController();
controller.setup(slvc: self, ingredients: ingredients!, clickedCellIndexPath: indexPath);
controller.modalPresentationStyle = .popover;
controller.popoverPresentationController!.delegate = self;
self.present(controller, animated: true, completion: {
self.tableView.reloadData();
});
}
Here is how the view controller looks when presented. If I click the trash can on one of the items, the data is cleared, but the cell is not removed from the UI, which is what I am trying to achieve.
I'm actually surprised your tableView shows any data at all. Because you declare cell as a let in cellForRowAt when you do let cell = UITableViewCell();, that makes it immutable, and the first cell (outside of the switch) is the one that should technically get returned. Hence why no data should be displaying. And probably also the reason why your tableView is not updating correctly.
Anyway, you should only declare cell when you're dequeueing it, and you should as much as possible, avoid force-unwrapping of a variable.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == SECTIONS.HEADER.rawValue, let cell = tableView.dequeueReusableCell(withIdentifier: "OpenIngredientInfoCell", for: indexPath) as? OpenIngredientInfoCell {
// not sure this check is necessary, but I'm adding it because it was in your original code
guard uniqueIngredients.count > 0 else { return UITableViewCell() }
let ingredient = uniqueIngredients[0]
cell.setup(ingredient)
return cell
} else if indexPath.section == SECTIONS.RECIPE.rawValue, let cell = tableView.dequeueReusableCell(withIdentifier: "OpenRecipeCell", for: indexPath) as? OpenRecipeCell {
// it shouldn't be possible for the indexPath to ever be greater than the dataSource items count, but I'll keep the check
guard indexPath.row < uniqueIngredients.count else { return UITableViewCell() }
cell.selectionStyle = .none
let ingredient = uniqueIngredients[indexPath.row]
cell.setup(self, ingredient, clickedCellIndexPath)
return cell
}
return UITableViewCell()
}
I've removed the semi-colons as they're not necessary in Swift.
For specifying the table cells' reuse identifiers, using the class names would probably be better. So you would use "\(OpenRecipeCell.self)" instead of "OpenRecipeCell"
If you are using the defaulted way of editing a UITableView (either swiping or entering edit mode), then here's my delegate code that works fine:
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let movedStep = appState.recipe.steps[sourceIndexPath.row]
appState.recipe.steps.remove(at: sourceIndexPath.row)
appState.recipe.steps.insert(movedStep, at: destinationIndexPath.row)
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
appState.recipe.steps.remove(at: indexPath.row)
tblSteps.deleteRows(at: [indexPath], with: .automatic)
}
}
Notes:
I manually place this table view in edit mode through a UIBarButtonItem, and a cell can both be moved or deleted.
My data source is in my model, at appState.recipe.steps. The structure doesn't matter, just handling the array.
I set a Notification anytime this array is changed that triggers a reloadData() in this table view.
I don't see either of these delegate methods listed, so I'm posting this answer. If by chance it doesn't help you, I'll gladly delete this.

Two tableviews in one view controller, one table view not showing up

I have two TableViews in one ViewController and only one table is able to populate. I have created outlets for both tables in my view controller. Here is my viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
pickerTableView.delegate = self
pickerTableView.dataSource = self
tableView.delegate = self
tableView.dataSource = self
tableView.tableFooterView = UIView()
pickerTableView.reloadData()
tableView.reloadData()
}
It seems that the only table that is read is self.tableView and the pickerTableView is never read in the protocols for UITableView
extension MealViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if tableView == self.tableView {
let nameHeaderView = NameHeaderView(frame: CGRect(x: 0, y: 0, width: tableView.frame.size.width, height: 40))
nameHeaderView.delegate = self
nameHeaderView.sectionIndex = section
nameHeaderView.nameButton.setTitle(Data.userModels[section].name, for: .normal)
return nameHeaderView
} else {
return nil
}
}
func numberOfSections(in tableView: UITableView) -> Int {
if tableView == self.tableView {
return Data.userModels.count
} else {
return 0
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView == self.tableView {
if Data.userModels[section].isExpandable {
return Data.userModels[section].itemModels.count
} else {
return 0
}
} else if tableView == pickerTableView {
return Data.userModels.count
}
else {
return 0
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableView == self.tableView {
let cell = tableView.dequeueReusableCell(withIdentifier: "nameCells", for: indexPath) as! MealTableViewCell
cell.setup(itemModel: Data.userModels[indexPath.section].itemModels[indexPath.row])
return cell
} else if tableView == pickerTableView {
let cell2 = tableView.dequeueReusableCell(withIdentifier: "pickerCells", for: indexPath) as! NamePickerTableViewCell
cell2.setup(userModel: Data.userModels[indexPath.row])
print(Data.userModels)
return cell2
}
else {
return UITableViewCell()
}
}
}
I have also applied constraints on each tableView so they both appear on the screen. When I run the app, the data for self.tableView is shown however the pickerTableView appears empty. self.tableView requires sections and pickerTableView does not require sections, could this be an issue? Also there is data in the Data.userModels array.
And just for reference, here is my UITableViewCell class:
class NamePickerTableViewCell: UITableViewCell {
#IBOutlet weak var namePickerLabel: 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 setup(userModel: UserModel) {
namePickerLabel.text = userModel.name
}
}
Thanks for the help!
If you do not need any section in pickerTableView, then also it has to have at least one section.
So return 1 in method numberOfSections when tableview == self. pickerTableView.
func numberOfSections(in tableView: UITableView) -> Int {
if tableView == self.tableView {
return Data.userModels.count
} else {
return 1
}
}

update a cell in tableview

My code reads cities array to a tableView.
When a cell is clicked, it move to a SecondViewController. The SecondViewController has a button.
If I clicked the button, it will display an image into that cell.
Problem: I am trying to update the cell whenever the button is clicked. It is working but no matter which cell is clicked, it always displays the image for cell 3, if I clicked again it displays for cell number 1 image.
How to fix this so that when the button is clicked, it display the image for it's cell and if the same cell is clicked, hide the image.
My codes:
var first = 0
var reload = false
var cellNumber: Int!
var cities:[String] = ["paris", "moscow", "milan","rome","madrid","garda","barcelona"]
#IBOutlet weak var tableView: UITableView!
// func to reload a cell
#objc func toReload(rowNumber: Int){
reload = true
let indexPath = IndexPath(row: rowNumber , section: 0)
tableView.reloadRows(at: [indexPath], with: .none)
}
// load tableview from a SecondViewController call
#objc func loadList(notification: NSNotification){
self.tableView.reloadData() // reload tableview
toReload(rowNumber: cellNumber)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cities.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! CustomCell
cell.label1.text = cities[indexPath.row]
let image : UIImage = UIImage(named: "20870718")! // assign imageView to an image
if first == 0 {
cell.myimage.isHidden = true // hide image
first = 1 // condition to never enter again
}
if reload == true {
if cell.myimage.isHidden == true {
cell.myimage.image = image
cell.myimage.isHidden = false
}
else{
cell.myimage.isHidden = true
}
reload = false
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.cellNumber = indexPath.row
performSegue(withIdentifier: "send", sender: self)
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.reloadData()
NotificationCenter.default.addObserver(self, selector: #selector(loadList), name: NSNotification.Name(rawValue: "load"), object: nil)
// call load list method
}
}
SecondViewController:
#IBAction func displayImage(_ sender: Any) {
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "load"), object: nil)
}
There is a problem in your cellForRowAt.when secondViewController notify the first one no matter which cell you are reloading cellForRowAt always will be called because when you scroll tableView wants to recuse cell and reload == true becomes true for all cells.so you have to check if indexPath.row == cellNumber then do the rest work :
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! CustomCell
cell.label1.text = cities[indexPath.row]
let image : UIImage = UIImage(named: "20870718")! // assign imageView to an image
if first == 0 {
cell.myimage.isHidden = true // hide image
first = 1 // condition to never enter again
}
if indexPath.row == cellNumber {
if reload == true {
if cell.myimage.isHidden == true {
cell.myimage.image = image
cell.myimage.isHidden = false
}
else {
cell.myimage.isHidden = true
}
reload = false
}
}
return cell
}

navigating from uitableviewcell to multiple uinavigationcontroller using swrevealviewcontroller

I am new to swift language and start to creating stub application having sliding menu. I used tutorial from http://www.appcoda.com/sidebar-menu-swift/ to create slide menu but want to create application which is dynamic not static as shown in example. I am facing problem in creating segue or doing navigation from the uitableviewcell to the respective uiviewcontrollers which is connected to respective uinavigationcontroller.
following is the code for sliding menu class:
MenuController.swift
import UIKit
class MenuController:UITableViewController
{
let menuControlList = ["Category 1", "Category 2", "Category 3", "Category 4"]
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// Return the number of sections.
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of rows in the section.
return menuControlList.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! MenuTableCell
let row = indexPath.row
cell.menuCellText.text = menuControlList[row]
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("row clicked :: ", indexPath.row)
switch indexPath.row
{
case 0:
var cat1View = Category1(nibName:"Category1", bundle:nil)
self.navigationController?.pushViewController(cat1View, animated: true)
print(indexPath.row)
break
case 1:
var cat2View = Category2(nibName:"Category2", bundle:nil)
self.navigationController?.pushViewController(cat2View, animated: true)
print(indexPath.row)
break
case 3:
var cat3View = Category3(nibName:"Category3", bundle:nil)
self.navigationController?.pushViewController(cat3View, animated: true)
print(indexPath.row)
break
case 4:
var cat4View = Category4(nibName:"Category4", bundle:nil)
self.navigationController?.pushViewController(cat4View, animated: true)
print(indexPath.row)
break
default:
return;
}
}
}
Following is the screenshot of my storyboard:
if i am doing any mistake in creating this please let me know and help me rectify it.
Following is the code of my category 1 class :
class Category1 :UIViewController
{
#IBOutlet var menuBtn: UIBarButtonItem!
override func viewDidLoad() {
super.viewDidLoad()
if self.revealViewController() != nil {
menuBtn.target = self.revealViewController()
menuBtn.action = "revealToggle:"
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
EDIT:
Tried following solution:
let vc = storyboard.instantiateViewControllerWithIdentifier("Category1") as! Category1
presentViewController(vc, animated: true, completion: nil)
the above code directly opens up category 1 viewcontroller with slideup animation but it is not opening through the navigationcontroller attached with the respective viewcontroller.
if i use the following code:
let vc = storyboard.instantiateViewControllerWithIdentifier("Category1") as! Category1
self.revealViewController().setFrontViewController(vc, animated: true)
the above code also loads viewcontroller but the sliding menu doesnt slide back in?
First of all, give your Navigation View Controllers a storyboard ID, and not the actual view controllers. So for example, if Category1 is embedded in the Navigation Controller, then give the Navigation Controller a storyboard ID of Category1NavController for example. Then your code should be as follows:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("row clicked :: ", indexPath.row)
switch indexPath.row
{
case 0:
let navController1 = storyboard.instantiateViewControllerWithIdentifier("Category1NavController") as! UINavigationController
self.revealViewController().setFrontViewController(navController1, animated: true)
print(indexPath.row)
break
..........
// Handle other cases similarly here
case 1:
.....
case 2:
.....
default:
return;
}
self.revealViewController().setFrontViewPosition(FrontViewPosition.Left, animated: true)
}
You should also reset the Top View position after your switch statement ends. Here's how it should be (sorry again if syntax is not correct, please fix accordingly):
self.revealViewController().setFrontViewPosition(FrontViewPosition.Left, animated: true)
There must be a similar method to be called in Swift.
Hope this helps. Please pardon my SWIFT syntax and correct it if needed.

Resources