unwinding segue, need to refresh tableview - ios

I have looked all over for this problem and I cannot find an answer.
So on the first page of my app I have a page in a navigation controller. Within that page is a tableview. Within the cells of the table, there is a button. For the view controller of the cells, I say remove the button from superview if user is not signed in. So when you first load the app, there is no button.
Now if you click the sign in button (a button at the top of the page), it goes to that page, then there's two possible things that can happen. At first what I was doing was making a segue back to the main page. Everything worked perfectly fine. The button appears in the cells.
But I don't like how a second copy of the main page is being added to the stack of navigation controllers. So what I have explored with now is the popnavigationcontroller method and the unwind segue. So they both work but the problem is when it unwinds back to the new page, the button I mentioned earlier does not appear in the cells, even though its supposed to appear since the user is signed in. The reason for this is because the method "dequeueReusuableCell" is using the old cells, in which I have removed the button. And now that the button is removed, there is no easy way for me to add it back in at the right place in the view.
So what is the best solution here? At first I was looking for a way to "clear" all the reusuablecells for a tableView but I'm not sure if I found an answer. What I would like to do is when I rewind back to that navigation controller, refresh everything like it was the first time ever seeing it.
I guess another solution I could do is to perform a normal segue from the sign in page to the main page, and then remove the previous redundant main navigation controller. Is there a better solution?

When your controller pops off the stack, the underlying view controller will have its viewDidAppear(animated:) function called. So you could have:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
tableView.reloadData()
}
This is assuming based on your post that the issue is only about reloading your table. If you reload the table and your cells are still not updating properly, you have an issue with your dataSource not configuring the cells properly. But I cannot tell if this is the case without any code.
Edit: this was a cell reuse issue. Cell configuation had some code to remove a subview in some instances, but never add the subview back if it was supposed to be there. The simplest fix is to use isHidden instead of outright removing the subview.

Related

How to automatically update a label on a viewcontroller from another viewcontroller while using a UIpageviewcontroller to navigate pages

I am currently using a UIPageviewcontroller to navigate between my 3 main viewcontrollers. I have a global variable that I set on the first page using a stepper. The value of that global variable is then used as the value for a label on the second page.
This works, but it requires a button on the 2nd page to update the label. The exception being when I first run the app and change the stepper on the first page before swiping to the second page - as I have the label being updated in the "override func viewdidload()"
I dont want to use a button to update my label on page 2. I would like to be able swipe to page 1, change the stepper, then when I swipe back to page 2, the label on page 2 is automatically updated. (repeatedly)
How do I do this?
Is there a way to kill view controllers within the UIpageviewcontroller? or is there a way to get the "override fun viewdidload()" function to run every time I swipe to a page?
The simple way to do this would be to update the label on page 2 in it's viewWillAppear method. That will get called each time you go back to your page 2 view controller.
Globals are not a great way to set up your data handling however.
You'd be better off making page 2's view controller the delegate on the first view controller. When the users changes the stepper on the first view controller, it could call a "valueChanged()` method on it's delegate.
You should read up on the delegate design pattern to figure out how to do this. It's VERY well documented, and is one of the most common patterns you will find in iOS development.

Swift canEditRowAtIndexPath not working in UIPageViewController EZSwipeViewController

I have the following scenario and need help in resolving a tricky situation in the scenario
There is an Xcode project and am using EzSwipeController for swipe (pagination effect) between three View Controllers at the moment.
In my first ViewController (this viewController is fetched from my custom dynamic framework as part of my requirement) -
Code to fetch ViewController:
userProfile.createProfileUI(userSession!) { result in
switch result {
case let .Success(profileViewController):
myDetailsVC = profileViewController //myDetailsVc is passed to EZSwipControllerDataSource array
default:
break
}
}
The other two ViewControllers are within my project storyboard
The Problem -
In the first ViewController, there is a tableView with canEditRowAtIndexPath enabled for few cells (phone numbers).
So when I try to swipe the row, the EZSwipeController responds first and
hence, I am not able to edit the row.
Here is what is happening - http://recordit.co/SOJgdeYchP
Here is what should happen - http://recordit.co/EBPSbjH31q
How do I handle this problem? Is there a way where I can override the default swipe controller action when I try to edit the row?
Please help!
Attach the swipe gesture recognizer to a parent in the hierarchy.
If you're using a UITableViewController, replace it with a UIViewController with a UITableView inside it. Then just drag the gesture recognizer onto the view controller in Storyboard, and it'll attach to the UIViewController's Content View instead of the UITableView.
Though at the end of the day, this is inherently a flawed approach, since swiping to flip pages in an app is only ever viable if you don't have any elements on the pages that also have swipe gestures in them. If you do, even if you code a workaround to make the gesture recognizer for the element in the view controller (in this case, a table view cell) fire instead of the page flipping swipe gesture, that creates an inconsistent user experience.
My suggestion: don't use a table view for such a form altogether. On top of the aforementioned mechanical UX issue, from a user perception perspective, there's nothing indicating visually that this is a table view and not just a scroll view, so there's nothing indicating to the user that swipe actions (Delete) are available. Use a scroll view instead, and take a different approach to deleting (Delete buttons that are always visible, Delete buttons that are only visible after the user hits Edit somewhere, etc.).

UITableViewController auto-scrolling stops taking into account keyboard when shown from a UISplitViewController

When you subclass UITableViewController, you normally get certain behaviors "for free". For example, when a text field in your table view becomes first responder, the view controller automatically scrolls itself to ensure the field is fully visible.
However, when the table view controller is the detail view controller of a UISplitViewController, this auto-scrolling no longer takes into account the presence of the keyboard. The table view controller will still auto-scroll to keep the text field within the bounds of the screen, but it no longer scrolls to keep the field from being covered by the keyboard.
You can test this yourself by creating a new project using Xcode's "Master-Detail Application" template, and replacing the detail view controller with a table view controller that displays cells with text fields in them.
I would like to understand why the auto-scrolling stops accounting for the keyboard in this case, and if possible how to rectify that without having to duplicate the auto-scrolling functionality myself. BTW, this has nothing to do with overriding viewWillAppear (as in some other questions here about table view controller auto-scrolling).
I know its late but this might help others who are having this issue. This happens to me as well when I added textfield in UITableViewCell. What I did was to remove
superViewWilAppear:animated
line in viewWillAppear method.So the method looks like this
-(void)viewWillAppear:(BOOL)animated{
//[superViewWilAppear:animated];
Your rest of code
}
But what this does is it removes the auto scrolling all together and you have to manage the scrolling of UITableView when textField starts editing. Don't know if this solved your problem but it will save you the trouble of considering keyboard height for different devices and its better to manage on your own. Also I am not sure if this is the right way to do it but it worked for me.

Possible to update a UIViewController that is not on screen?

I have a side menu controller that is part of the rootViewControllerI never remove it from there and when it slides off screen - its just an animation that updates its frame details.
Is it possible to update this view, while it is not displayed on scene? I have a UiTableView in there and I would like to reload it while it is off screen - so when the user slides out the screen, its already populated with new content.
My first approach was a delegate - however, the delegate method doesn't get fired and I believe this is due to it being off screen. But, I somehow think side its in UIWindow it is never really deallocated like a normal view when it leaves the screen?
Edit
I am using this Github project for the menu.
The view I want to update is in a UINavigation controller, one level deep. I can get the current instance of it - however, the delegate method doesn't trigger.
It seems to me that you are going with something like this. Even if not, look at the example. Here RootViewController is always alive and you move one viewcontroller to parent view controller and remove other one.
I have two ways to fix it:
If you are removing first view from parent view controller. Don't remove it. So the controller is still live and use delegates to trigger the event.
Remove first view controller then use Root view controller to get the updates and once the previous view controller loads back take updates from root view controller and update this one.
Hope it can atleast give you an idea.

UITextField focus before navigation view push?

I have a UITextField set up in a UITableViewCell, for a control mimicking that in Apple's own Contacts app, when you go to edit a field. This is all mostly working fine, except for a little UI bug.
The UITableView is part of a UIViewController created and loaded from a XIB, but the text field is being created programmatically (and becoming first responder) in tableView:cellForRowAtIndexPath:, so that it can be added to the cell.
This results in a slight keyboard lag, where the view controller is pushed onto the stack, with the keyboard coming soon after.
The Contacts app, however, pushes it all as one.
How can I correct this lag? I've tried moving the text field creation and first responder-ing to viewDidLoad, and this didn't help. I even tried creating a layoutSubviews and calling it from outside the view controller, before it was pushed to the stack.
Unfortunately, it doesn't seem as though the text field actually becomes the first responder until it is part of the cell—well after the view has been pushed.
You have to let the UITextField become the first responder in viewWillAppear.
I have created an example project here:
https://github.com/lukaswuerzburger/pushed-keyboard

Resources