dFroze
dFroze

Reputation: 51

Adding back button and gesture to TableViewController

I've started recently my debut in swift, so I still can't get the hang of it.

I am trying to make a ViewController to display some results, a list of element each having 2 string and a image. Thus I've gotten to the following code:

@objc class TableViewController: UITableViewController {

    var tableList = [cellData]()
    var viewImages = false
    var advancedMode = false

    override func viewDidLoad() {
        super.viewDidLoad()

        self.tableView.allowsSelection = false
        self.tableView.delegate = self
    }

    func goBack(){
        dismiss(animated: true, completion: nil)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return tableList.count;
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        switch tableList[indexPath.row].cell {
        case 2:
            let cell = Bundle.main.loadNibNamed("TableViewCell2", owner: self, options: nil)?.first as! TableViewCell2
            cell.Header.text = tableList[indexPath.row].header
            cell.Details.text = tableList[indexPath.row].details
            cell._Image.image = tableList[indexPath.row]._image

            return cell

        default:
            let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
            return cell

        }

    }

    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
    {
        switch tableList[indexPath.row].cell {
        case 1:
            return 127.0;
        case 2:
            return 50 +
                ((tableList[indexPath.row].details != nil && tableList[indexPath.row].details.count > 0) ? 100 : 0) +
                (tableList[indexPath.row]._image != nil && tableList[indexPath.row]._image.size.height > 0
                    ? ((tableList[indexPath.row]._image.size.width/self.view.frame.size.width) *  tableList[indexPath.row]._image.size.height)
                    : 0);  // TODO: here we should get the proper height from the image based on the with of the view
        default:
            return 50.0;
        }
    }

    @objc
    func clearTable() ->Void {
        tableList.removeAll()
    }

    @objc
    func addElement(header: String, details: String, image:UIImage) -> Void{
        tableList.append(cellData(cell: 2, header: header, details: details, _image: image))
    }


}

This codes works great by listing the results. But I want to add the back feature.

Any ideas where I might have made a mistake or what I am missing?

Update 1: In the previous view controller I used the following code to go to the TableViewController:

TableViewController *vc = [[TableViewController alloc] init];
[self presentViewController:vc animated:YES completion:nil];

I needed to jump to TableViewController when a certain process/condition was done (so not by pressing a button)

Upvotes: 0

Views: 1174

Answers (3)

dFroze
dFroze

Reputation: 51

Ok, after I watched some videos on CS193P (thank you @Tigran Iskandaryan) and played in another project, I've found the solution.

So, the problem was: [self presentViewController:vc animated:YES completion:nil];

From what I've read, in order for NavigationController to work as should, it needs the ViewControllers to be stacked. And because I used a diffrent way to jump to the next ViewController, it didn't need to display the navigation bar.

So, the fix was to use pushViewController instead of presentViewController. That way, the ViewController will be stacked within the NavigationBar.

Thus, it will be:

TableViewController *vc = [[TableViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];

Note, that in order for it to work I had to make sure to embed the nMvigationController into the root ViewController

Upvotes: 0

Tigran Iskandaryan
Tigran Iskandaryan

Reputation: 1451

I assume you are using the Storyboard. When you create a segue by control dragging to another view controller and letting the mouse a small menu should appear like this:

enter image description here

Under the Action Segue section there are segue types. For your case, you need to select Show. Now, if you embed the first view controller in a navigation controller, a back button will appear on the second one.

This will also work if your first view controller is already embedded in a navigation controller and you create a Show segue from it to another one.

For checking your segue's kind, just tap on its arrow and in the utilities area (the right panel) you can see its kind under Kind section.

EDIT

If you are using Objective-C and do segueing programatically, here is the way: Each view controller has a property called navigationController, which holds a reference to the navigation controller in which it is embedded. If your view controller is already embedded in a navigation controller here is how you can do your transition:

 - (IBAction)buttonTapped:(UIButton *)sender {
ViewController2 *viewController2 = [[ViewController2 alloc ] init];

[self.navigationController pushViewController: viewController2 animated:YES];

}

P.s. You can check Stanford's course for iOS development: CS193P. It is free.

Upvotes: 1

Let's_Create
Let's_Create

Reputation: 3643

Have you tried setting the left bar button as:

let button1 = UIBarButtonItem(image: UIImage(named: "imagename"), style: .plain, target: 
self, action: Selector("action")) // action:#selector(Class.MethodName) for swift 3
self.navigationItem.rightBarButtonItem  = button1

Upvotes: 0

Related Questions