Edit button does not have any functionality, no red circle with a minus appears on the left side of cells - swift

I have looked at another question that was asking the exact same question as mine, but the answer told them to call the setEditing function (which I tried, and say later in the question). But I don't see how you could call this function only when the edit button is clicked. I suppose I could create my own BarButtonItem and run this method when my bar button item is clicked, but I figured this would be far easier since I need the basic functionality of the edit button.
I have a UIViewController that has a table on it named peersTable. When I click the edit button it switches to done, but nothing happens on the table. I have also added my own UITableViewRowActions and when I swipe to the left on the cells, my custom actions do show up.
Here is some of my code:
class PeerViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, ConnectionManagerDelegate {
#IBOutlet weak var peersTable: UITableView!
...
override func viewDidLoad() {
...
peersTable.delegate = self
peersTable.dataSource = self
self.navigationItem.rightBarButtonItem = self.editButtonItem
...
}
I have also tried calling the peersTable.setEditing(true, animated: true) method myself, and in this case, the red minus does appear. I've never seen this issue before, so I don't understand why it's happening. Am I somehow setting the delegate wrong? Or possibly I'm doing something wrong since this is a regular View and not a TableView (even though I've done this before in a previous project).
Thanks in advance! If you need any more information let me know!

Since this is a not a TableViewController it won't automatically set your tableView to editing mode when you press the edit button.
You need to override setEditing method so you can set the tableView to editing mode.
Add this to your ViewController class:
override func setEditing(_ editing: Bool, animated: Bool) {
super.setEditing(editing, animated: animated)
peersTable.setEditing(editing, animated: animated)
}

Related

How to perform the instantiation of UISearchBar properly from a nested VC

I have the firstVC as 'homeController' which has an instance of UISearchBar and implements its delegate (UISearchBarDelegate), and doing this will instantiate the secondVC which is 'searchController' and has its delegate on another instance of UISearchBar as well, I need to fix that redundancy. I am using the homeController UISearchBarDelegate just because it let me instantiate the 'searchController'.
1: I'm using the method for the instantiation searchBarShouldBeginEditing on 'homeController' and perhaps it is wrong because the first second loads the color properly and then it changes to black.
2: searchBarTextDidBeginEditing loop itself. (from the color that I want to again the color that I want). -(infinite loop)
I can only use one at the time or searchBarShouldBeginEditing or searchBarTextDidBeginEditing. I would like to use the behavior of searchBarTextDidBeginEditing, but it reloads like crazy. Or the first second of searchBarShouldBeginEditing and know where does the application is in the state of that black screen because definitely, it is not the default color that I set, because it changes the color that I want on the first second and on the second second it is black. By the way, The application is not using the UISearchBar from the 'searchController', it is using the UISearchBar from 'homeController'. What is recommended?
Just right there I got two points.
1: Should I keep separated the logic as I am doing or should I mix it?
1.1: home and search have different cells, that's why I don't mix them. How can I use the instance of UISearchBar on 'searchController'?
2: If I keep it separated, should I use the UISearchBar from the 'searchController' or delete that instance and just use 'homeController'?
how to implement or instantiate properly the UISearchBar with the current scenario?
func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool {
handleShowSearchVC()
return false
}
#objc func handleShowSearchVC() {
let modalUserSearchController = UserSearchController(collectionViewLayout: UICollectionViewFlowLayout())
modalUserSearchController.modalPresentationStyle = .overCurrentContext
navigationController?.pushViewController(modalUserSearchController, animated: true)
}
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
handleShowSearchVC()
}

navigationController?.navigationBar.isUserInteractionEnabled not working as expected

For the following viewController hierarchy, isUserInteractionEnabled doesn't appear to be working as expected.
NavigationController(ViewController A) --- pushes to ---> NavigationController(ViewController B)
In ViewController A's viewDidAppear method I set navigationController?.navigationBar.isUserInteractionEnabled to false and set it to true in ViewController B's viewDidAppear method. However, upon popping ViewController B and returning to ViewController A, the navigation bar remains enabled for user interaction. Any thoughts as why this may be happening are greatly appreciated, thanks in advance!
That seems to be a bug for which you could get around by doing that on the main thread:
override func viewDidAppear(_ animated: Bool) {
//...
DispatchQueue.main.async {
self.navigationController?.navigationBar.isUserInteractionEnabled = false
}
}
But this still leaves a millisecond window where the navigationBar's interaction is enabled.
You have to be really quick.
However...
I wouldn't recommend what you're doing; i.e. disabling the navigationBar.
You could lose the back ability, if it had one, because you're just disabling the navigationBar entirely.
Suggestion:
Since every viewController in the navigation stack has it's own navigationItem, that contains it's own set of barButtonItems, I would recommend you keep references of the UIBarButtonItem and enable/disable them explicitly.
i.e.
#IBOutlet var myBarButtonItem: UIBarButtonItem!
override func viewDidAppear(_ animated: Bool) {
//...
myBarButtonItem.isEnabled = false
}
Furthermore, the state of this barButtonItem is handled in this viewController itself and you need not do things like self.navigationController?.navigationBar.isUserInteractionEnabled = true elsewhere.

Adding views with IBAction to a NSStackView crashes application

I want to use the NSStackView to stack views above each other, I also want them to de able to expand so I can't use the NSCollectionView if i understood it correctly.
So, in storyboard, I've created a NSStackView(embedded in scroll view) in the main view controller and a view controller that I want to fill it with:
The button will fill the stack view with ten views:
#IBOutlet weak var stackView: NSStackView!
#IBAction func redrawStackView(_ sender: Any) {
for i in 0..<10 {
let stackViewItemVC = storyboard?.instantiateController(withIdentifier: "StackViewItemVC") as! StackViewItemViewController
stackViewItemVC.id = i
stackView.addArrangedSubview(stackViewItemVC.view)
}
}
And the ViewController on the right simply looks like this:
class StackViewItemViewController: NSViewController {
var id: Int = -1
override func viewDidLoad() {
super.viewDidLoad()
// Do view setup here.
}
#IBAction func buttonPressed(_ sender: Any) {
debugPrint("StackViewItemViewController" + id.description + "pressed")
}
Running this small application works fine, every time I press the button ten more stack view items appears. But, when I have the audacity to press one of the buttons to the right the application crashes:
Where am I going wrong?
I have tried to work around the IBAction to verify that this what breaks, and the application will not crash if I subclass the button and make a "buttonDelegate" protocol with a function being called from mouseUp.
I guess the problem is that the viewController objects, which you create in the loop, are released immediately.
Even though the view is attached to the stackView, it's viewController is destroyed.
You can fix this issue by keeping a reference to each viewController.
You can do this by creating a new variable
var itemViewControllers = [StackViewItemViewController]()
and then add each newly created viewController to it:
itemViewController.append(stackViewItemVC)

Dismissing a numeric keyboard

A noob question here: I have read a lot about dismissing the keyboard from objects like labels or event when one taps the RETURN key or other areas of the screen. However, is there code to dismiss a keyboard from within a BUTTON? I tried various ways of ResignFirstResponder at the end of the code in my BUTTON but to no success.
Any help that can be shed would be appreciated. Please remember I a new to all this so I please be as specific as possible.
Thank you
You can send endEditing(_:) to the text field that is the first responder, or to any superview of it, to make it resign first responder and dismiss the keyboard. The window is a view, and is a superview of all your other views, and is easy to get a reference to:
#IBAction func calculateButtonWasTapped(sender: AnyObject?) {
view.window?.endEditing(true)
// perform calculation here
}
Let's just say that the text field is called theTextField, and when pressed the UIButton runs an #IBAction called buttonTapped().
class ViewController: UIViewController {
#IBOutlet var theTextField: UITextField!
#IBAction func buttonTapped(sender: AnyObject) {
theTextField.resignFirstResponder()
}
}

Update the data of a TableViewController after add item

I have tableView (A) responsible for listing items CoreData and viewController (B) to add new item. To create a ViewController (B) custom, they chose to use the following Present Modally to use presentation Over Current Context to enable transparent background and be able to apply the blur.
From tableView (A) press the button to add a new item, the viewController (B) appears.
Add a new item and saved in CoreData
The viewController (B) execute self.dismissViewControllerAnimated(true, completion: nil) and the display returns to the tableView (B)
The problem is that the table view does not update the data.
Following a post from Stack Overflow resulting in code:
override func viewDidAppear(animated: Bool) {
self.loadData()
}
But at the back of viewController (B), nothing happens in Xcode does not pass the lines of viewDidAppear.
Can anyone help me?
Try this:
override func viewDidAppear(animated: Bool)
{
self.yourTableViewName.reloadData()
}