So I have an embedded tableview and I want to implement edit/delete behaviour:
In my HomePageViewController I have:
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.leftBarButtonItem = editButtonItem
}
However, all that happens is when I click on the edit button, it says done, and the embedded tableview does nothing at all. When I put the above code in the tableview nothing happens.
How do I get the navigation controller/parent view controller to recognise the embedded table view?
It looks like you're using an embed segue to embed a UITableViewController. In your parent view controller, you can do 1 of 2 things easily to achieve you goal.
Method 1: Use the child view controller's edit button
override func viewDidLoad() {
super.viewDidLoad()
// Find and (optionally assign it to a variable for later convenience) the embedded controller, IBOutlets aren't available for VCs embedded within a storyboard
let childControllers = childViewControllers.filter { return $0 is EventTableViewController }
let embeddedController = childControllers[0] as! EventTableViewController
navigationItem.leftBarButtonItem = embeddedController.editButtonItem
}
Method 2: Forward edit events to child view controllers
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.leftBarButtonItem = editButtonItem
}
override func setEditing(_ editing: Bool, animated: Bool) {
super.setEditing(editing, animated: animated)
// Forward editing state to children
childViewControllers.forEach { $0.setEditing(editing, animated: animated) }
}
Note: editButtonItem was exposed in iOS 10 (but was implemented much earlier). For deployment targets less than iOS 10, you can use a custom edit button combined with method 2.
In this situation, you can't use the automatic behavior of the edit button. It's up to you to implement it yourself. You need to toggle both the isEditing of the table view and the appearance of the button. Here's an example from one of my own apps:
func doEdit(_ sender: Any?) {
var which : UIBarButtonSystemItem
if !self.tableView.isEditing {
self.tableView.setEditing(true, animated:true)
which = .done
} else {
self.tableView.setEditing(false, animated:true)
which = .edit
}
let b = UIBarButtonItem(barButtonSystemItem: which,
target: self, action: #selector(doEdit))
self.navigationItem.rightBarButtonItem = b
}
Related
I have two view controllers in my application. Root view controller has some components and one of them is a button. That button provides to open another view controller using with present function. Second view controller(SelectTimeViewController) that opens when the button is tapped, was opened successfully. I am trying to set navigation title and items but I can not see them.
I did not use storyboard so root view controller is setting from AppDelegate.
let viewController = ViewController()
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = UINavigationController(rootViewController: viewController)
window?.makeKeyAndVisible()
When tapped the button, "openVC" function is invoked.
#IBAction func openVC(_ sender: Any) {
self.navigationController?.present(SelectTimeViewController(), animated: true, completion: nil)
}
I am trying to set title and rightBarButtonItem in SelectTimeViewController's viewDidLoad function but I can not see both of them.
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(named: "close"), style: .plain, target: self, action: #selector(closeIt))
self.navigationItem.title = "Select Time"
}
In additional to this, I can see both title and right bar button item when change the "openVC" function like as bellow.
#IBAction func openVC(_ sender: Any) {
self.navigationController?.pushViewController(vc, animated: true)
}
You have to push the SelectTimeViewController instead of present
Or if you really want to present it, you should present another UINavigationController that has the rootViewController as SelectTimeViewController()
I need to show the keyboard automatically when I will go to a particular View controller. Let take an example I have two view controller named "A" and "B". I have a text field present in the "B" view controller. When I am navigating from "A" to "B", I need to show the keyboard automatically. How to do it?
in B view controller
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
textField.becomeFirstResponder()
}
Type it in your B ViewController
override func viewDidLoad() {
super.viewDidLoad()
self.yourTextFieldName.delegate = self
self.showKeyBoard()
}
func showKeyBoard(){
self.yourTextFieldName.becomeFirstResponder()
}
I got a little problem.
On my main view controller I got a bar button that opens a slide menu, which is a regular view controller using a slide in transition. The slide menu has a button to open another view controller. When the new view controller is opened, you have the option to cancel, which dismisses the current view controller. The problem is, that the user ends up in the menu view once again, instead of the main view controller. Would be very happy to know what I am doing wrong :)
func openSupport() {
guard let creditViewContoller = storyboard?.instantiateViewController(withIdentifier: "support") as? CreditViewController else { return }
present(creditViewContoller, animated: true)
}
#IBAction func buttonSupport(_ sender: UIButton) {
let menuView = MenuViewController()
menuView.dismiss(animated: true, completion: nil)
openSupport()
print("Tap on Support")
}
you can dismiss view controller simply by using
self.dismiss(animated: true, completion: nil)
Consider
#IBAction func buttonSupport(_ sender: UIButton) {
let menuView = MenuViewController() // (1)
menuView.dismiss(animated: true, completion: nil) // (2)
openSupport() // (3)
print("Tap on Support")
}
This:
Creates new MenuViewController but never presents it;
Calls dismiss on view controller that was never presented; and
Calls openSupport from this MenuViewController instance (which was never dismissed).
Bottom line, you want to let the main view controller that presented the menu do the presenting. So, the menu view controller should:
Define a protocol for it to inform the presenting view controller to transition to the next scene:
protocol MenuViewControllerDelegate: class {
func menu(_ menu: MenuViewController, present viewController: UIViewController)
}
And then the menu view controller can, when it’s done dismissing, tell its delegate what it should present:
class MenuViewController: UIViewController {
weak var delegate: MenuViewControllerDelegate?
#IBAction func didTapSupport(_ sender: Any) {
dismiss(animated: true) {
guard let controller = self.storyboard?.instantiateViewController(withIdentifier: "support") else { return }
self.delegate?.menu(self, present: controller)
}
}
#IBAction func didTapCancel(_ sender: Any) {
dismiss(animated: true)
}
}
Then the main view controller needs to
Make sure to set the delegate of the menu view controller:
class ViewController: UIViewController {
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? MenuViewController {
destination.delegate = self
}
}
}
and
Make sure to present the view controller that the menu controller asked it to:
extension ViewController: MenuViewControllerDelegate {
func menu(_ menu: MenuViewController, present viewController: UIViewController) {
present(viewController, animated: true)
}
}
There are lots of different ways of achieving this, so don’t get lost in the details here. But the idea is to have some system by which the menu view controller can request whomever is to present the support view to do so, not try to do it itself.
when I am selected button twice will open a new page.
//////
Main viewController
var Country = []
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func taxiAction(sender: AnyObject) {
let opt = ["1","2","3","4","5"]
Country = opt
performSegueWithIdentifier("viewPlaceSegu", sender: sender)
}
...
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// get a reference to the second view controller
if segue.identifier == "viewPlaceSegu" {
if let secondViewController = segue.destinationViewController as? TableViewPlace {
// set a variable in the second view controller with the String to pass
secondViewController.tnt = Country as! [String]
}
}
}
////
http://i.stack.imgur.com/LKrN7.jpg
I tried so but didn't realize problem .
Does anyone know about this? :)
A likely cause is that you have connected the segue from the button to the new ViewController in the storyboard. When the button is pressed it will load the segue created in storyboard as well as the one created programatically.
If this is the cause then you would just need to delete the storyboard segue and create a new one from the ViewController rather than from the button.
I set my left bar button of UINavigationController as edit button using the code
leftBarButton = self.editButtonItem;
I want to change some disable/enable properties of other buttons with respect to the edit button's click action.
How can i find whether the Edit button is pressed or not?
The edit button's action sends your view controller the setEditing:animated message. Override this in your subclass to perform other actions when entering or leaving edit mode.
Be sure to call the super implementation at the end to manage the rest of the transition to editing view.
So finally i got the solution...
-(void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
if(editing) {
//Do something for edit mode
}
else {
//Do something for non-edit mode
}
}
This method will be called with out changing the original behavior of self.editButtonItem button.
In Swift:
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
....
self.navigationItem.leftBarButtonItem = self.editButtonItem()
}
override func setEditing(editing: Bool, animated: Bool) {
// Toggles the edit button state
super.setEditing(editing, animated: animated)
// Toggles the actual editing actions appearing on a table view
tableView.setEditing(editing, animated: true)
}
In Swift you can follow the below methods:
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItem = editButtonItem()
}
override func setEditing(editing: Bool, animated: Bool){
super.setEditing(editing, animated: animated)
tableView.setEditing(editing, animated: true)
}
UIBarButtonItem *barBut=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:#selector(doSomething)];
self.navigationItem.leftBarButtonItem=barBut;
[barBut release];
.h
-(void)doSomething;
.m
-(void)doSomething{
NSLog(#"dooooooooooooo");
//ur stuff
}
updated:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
will be called
editButtonItem
Returns a bar button item that toggles its title and associated state between Edit and Done.
- (UIBarButtonItem *)editButtonItem
Discussion
If one of the custom views of the navigationItem property is set to the returned object, the associated navigation bar displays an Edit button if editing is NO and a Done button if editing is YES. The default button action invokes the setEditing:animated: method.
Availability
Available in iOS 2.0 and later.
See Also
#property editing
– setEditing:animated:
Declared In
UIViewController.h
http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UIViewController_Class/Reference/Reference.html