How to change button name when cell selected in UITableView in swift? - ios

I have two UIButton and when you click on each you will go to table view controller and there you can select something.
My question is how to change the button title on selection of any cell.
I want to replace button title with selected cell's name.

There are two ways to pass data back to the previous viewController.
1) Using Delegates, check this
2) Using Notifications, check this

Bind button in your cell as #IBOutlet
When cell selected delegate method tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath. Here you can get your cell with [tableView cellForRowAtIndexPath:indexPath]
Change your button's title [cell.yourButton setTitle...]

If you were to make your navigation controller into you root view controller and put the view controller you wish to access the buttons from as its top view controller then you could do the following when a cell is tapped:
if let topVC = navigationController?.topViewController as? MyButtonViewController {
topVC.button1Name.setTitle("New Title", forState: .Normal)
}
Then you can hide the navigation bar on the top view controller with the following:
override func viewWillAppear(animated: Bool) {
navigationController?.setNavigationBarHidden(true, animated: animated)
}
override func viewWillDisappear(animated: Bool) {
navigationController?.setNavigationBarHidden(false, animated: animated)
}

Instead of using two navigation controllers you can use a single NavC and then make your view controller with the two buttons as the root view controller. Then when the buttons are pressed you load the appropriate table view controller. Also if your table view controller has the same data source then you can use a single table view controller itself.
Then depending on which button is pressed you push the appropriate table view controller but in the prepareForSegue keep track of which button was pressed so that you can change its title when a cell is selected in the table view controller.
To pass the selected cell details from the table view controller you can make use of a delegate which your view controller can implement and the table view controller will call and pass the selected cell details.
So in short do this.
Make your navC as the initial view controller.
Make your view controller with the two buttons as the root view controller of the navC
In the IBAction of the two buttons store which button was pressed so that you will know which buttons's title has to be changed.
When you load table view controller set the view controller as a custom delegate.
In the language list table view controller's didSelectRowWithIndexPath use the delegate to pass the selected cell info and pop the view controller.
In the delegate method of the view controller change the button title that you have stored in step 3 to the selected cell's text.
I have another solution which I have uploaded here. It does not contain any custom view controllers except the ViewController that has the two buttons. It makes use of segues and unwind segues.
http://www.filedropper.com/twobuttonnavc

Related

TabBarController disappears when I segue back to the view from another view

I have a viewController that is embedded in a nav controller. This nav controller is then embedded in a tab bar controller.
I have another viewController that is not supposed to be accessible from the tabBarController. It should only be accessible from the first viewController using a button. From the secondViewController, I made a UIBarButtonItem to move back to the original view. From the first view to the second view and vice versa, I used a Storyboard reference to move to and from from the views.
However, when I move from the first view to the second view, the tab bar controller disappears (like it should). When I move back to the first view, the tab bar controller disappears and I cannot move between tabs anymore.
I tried including:
self.hidesBottomBarWhenPushed = false
on the first view and
self.hidesBottomBarWhenPushed = true
on the second view
and nothing seems to work. The tab bar controller disappears every time i move from the second view to the first view.
You are following a wrong hierarchy. You are actually using seagues to go back and forth. This creates a new instance every time you try to come back to the first controller.
Let's make it clear:
You need to follow the below approach:
1 You have two controllers A and B.
2 Use self.hidesBottomBarWhenPushed = true in viewDidLoad or viewWillAppear of controller A.
3 Controller A is embedded in a navigation controller which is further embedded in a UITabBarController.
Tapping a button in controller A, you need to push to controller B. So you can use segue for this or you can do it programatically like:
let controllerB = B()
A.navigationController?.pushViewController(controllerB, animated: true)
4 Go Back to Controller A on the tap UIBarButtonItem. So your code in the action of UIBarButtonItem should be something like:
self.navigationController?.popViewController(animated: true)
Remember you should not should segue to go back to the previous controller.
you should use
override func viewWillDisappear(_ animated: Bool) {
self.tabBarController?.tabBar.isHidden = false
}
in that controller where the back button is placed, I am using the exact scenario in one of the my app.

Embed view controller inside container view based on selection from tableview

I'm trying to change the content of my container view based on what has been chosen from TableViewController and I'm out of an idea.
The structure in my storyboard looks like this:
Currently, my container view has embed segue with Table View and that's working great. Now after select something from Table View for example Map I want to display MapViewController inside container view and keep my header and footer. How can I do this?
First disable the segue form your container view to a DestinationViewController in your storyboard.
Now load your viewController object based on your previous tableViewController selection.
//this controller will be change on tableView selection make your own logic here.
let controller = storyboard!.instantiateViewController(withIdentifier: "Second")
addChildViewController(controller)
//Set this value false if you want to set Autolayout programmatically or set it true if you want to handle it with `frame`
controller.view.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(controller.view)
controller.didMove(toParentViewController: self)

Open URL in different ViewController when tableView cell is pressed

I am using SWRevealViewController for a slide-out menu in my app. The main View Controller contains a WKWebView to open URLs. When the slide-out button is pressed, a table view Controller appears.
I want to have the name of a website displayed in a Table View Cell in the Table View Controller in the slide-out menu and open that website in the WKWebView in the main View Controller when the cell is pressed.
This may seem like an easy question, but I can't seem to find anything about it online.
Thanks in advance for your help.
As far as I remember the implementation of SWRevealViewController, it uses the static table view.
If you are okay with the static table view that will have your links then you may just create a delegate method that will be called based on the cell that was chosen on the Table View Controller. This delegate will notify your ViewController and say which link to open.
Hope it's clear. Let me know if you need more details.
In SideMenuViewController (view controller in which you have table with links)
public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let mainViewController = MainViewController()
mainViewController.link = linksArray[indexPath.row]
self.revealViewController().setFrontViewController(mainViewController, animated: true)
}
init new main view controller that have WKWebView
pass link as a property
set that view controller as new front view controller

How can I create a segue between a custom UITableViewCell button and a second view

I created a custom UITableViewCell in a separate nib, and inside it I have a button. I want the tableViewCell to segue to one view controller when the cell is tapped, but a different one when the button is tapped. The cell tap segue works fine, but I can't figure out how to setup a segue between the button in the cell and the next view. I have added a target to the button with
cell.imagePreview.addTarget(self, action: "segueToImageView:", forControlEvents: .TouchUpInside)
Then in that method
#IBAction func segueToImageView(sender: UIButton) {
performSegueWithIdentifier("ImageViewSegue", sender: self)
}
But obviously I end up with a "has no segue with identifier 'ImageViewSegue'" error. I tried connecting the button to the new view in my main.storyboard, but it won't let me drag between the nib and the storyboard. I also tried creating a segue in main.storyboard between the two views and calling it "ImageViewSegue" but I get the same error.
Is there a way to create a segue with identifier through code? If not, how should I go about segueing to the new view via the button?
Instead of a segue, just do this the old-fashioned way (from before there were storyboards and segues): set the button's action–target pair (in code, when you load) so that when the button is tapped, your action handler is called. In the action handler, do whatever the segue would do, i.e. instantiate the view controller from the storyboard and push or present it.

How to name a back button in UISplitViewController

I have UITableViewController (its name is News) and UIViewController (its name is DetailViewController) and UISplitViewController. I want it to show a back button when I use an iPad in portrait orientation. I made the button but I cannot name it. I wrote following code
detailController.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem()
detailController.navigationItem.leftItemsSupplementBackButton = true
detailController.navigationItem.leftBarButtonItem?.title = navigationController?.topViewController.title
But it doesn't show the name of the button. I see only the arrow (the arrow works).
I also tried the following in my UITableViewController(News) but it didn't help me
I use two segues for different devices with this code.
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){
var screen = UIScreen.mainScreen().currentMode?.size.height
if (UIDevice.currentDevice().userInterfaceIdiom == UIUserInterfaceIdiom.Pad) || screen >= 2000 && UIDevice.currentDevice().orientation.isLandscape == true && (UIDevice.currentDevice().userInterfaceIdiom == .Phone){
performSegueWithIdentifier("showDetailParse", sender: nil)
self.dismissViewControllerAnimated(true, completion: nil)
} else if (UIDevice.currentDevice().userInterfaceIdiom == .Phone) {
performSegueWithIdentifier("showParse", sender: nil)
}
}
My result on an iPad
My result on an iPhone
Thanks to Paul Hegarty and his invaluable lectures at Stanford University and available on iTunes U... in this case his 2013 lectures under the title "Developing iOS 7 Apps for iPhone and iPad" and specifically "Lecture 11 Table View and the iPad".
If you're using storyboards, then:
Open your main storyboard and select the Navigation Controller that links to the Master View Controller in your Split View Controller group;
Open the Inspector;
Under the heading View Controller, against the property Title, enter the words that you would like to appear alongside the "Back" button chevron.
See screenshot of Master Detail Xcode template set up with a Split View Controller...
If you're instantiating views in code, then:
obtain a reference to the Navigation Controller for the Master View controller;
set the title property of that Navigation Controller with the NSString of words that you would like to appear alongside the "Back" button chevron.
As an aside, I would highly recommend implementation of Auto Layout and Size Classes, that you remove the text for the Back Button property and let size classes determine the appropriate words for your Back Button.
For example, as per the question...
The Solution:
Here is the way to fix the issue with the detail view controller's back button:
For any view controller that gets pushed onto the primary navigation controller's stack, set that view controller's title. (Either in its viewDidLoad: method or in the pushing view controller's prepareForSegue:sender: method.)
Set the primary navigation controller's title in the child view controller's viewDidLoad: method.
For example, in MasterViewController.m:
- (void)viewDidLoad {
[super viewDidLoad];
[self setTitle:#"Foo"];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[self navigationController] setTitle:[self title]];
}
This will keep the detail view controller's back button title in sync with the top primary view controller's title.
What Is Going On:
UINavigationController, its rootViewController, and UINavigationItem each have a title property.
Note that the back button shown for a current view controller is actually the previous view controller's backButtonItem. (See Figure 1-7 Navigation bar structure)
A UINavigationController will automatically inherit the value of the title of its root view controller, but will not automatically inherit the title of any other controller that gets pushed onto its stack. This is why, by default, the back button of the detail view controller will always show the title of the primary navigation controller's root view controller. You might allocate, initialize, and push multiple child view controllers, but only one navigation controller is allocated and initialized for each side of a standard split view controller.
Additionally, a view controller's navigationItem's title property (whose value will appear in the label in the center of the navigation bar) does not inherit its value from the navigation controller, but from the view controller itself. If you set the view controller's title property to "Bar", and the containing navigation controller's title to "Foo", the label displayed in the center of the navigation bar will say "Bar".

Resources