We have the following layout in our ViewController
As you see, it is a UIView containing a TableView, and over the tableview, a custom view that displays a message if there is nothing to display, also when the tableview is empty.
This controller reacts to the content of a local database, by using an event system. The idea is that, if the user does the gesture to refresh the tableview, the local database is deleted, and the controller receives an empty array of items, and the nothing found view should be displayed. After new info is downloaded, and the database is filled with it, the controller receives again an event with the items for the list, (or maybe again the list is empty, etc).
When debugging the view hierarchy, we can see that when starting the ViewController, the custom view "NothingFound" is there in its place. Then, we hide the NothingFound view, while downloading new contents from the server, with isHidden=true.
If it results that the server responded with an empty list, then we want the NothingFound view to be displayed again, and we set isHidden=false.
But it does not work, the view is not displayed again. Examining the view hierarchy, we can see in the navigator that the view disappeared from the hierarchy (we were expecting the view to be there, but in invisible status, but maybe we are wrong).
Maybe we are missing something, but is isHidden = false not supposed to make the view visible again? Or is there another technique to do this?
Thanks in advance
PS: Things we already tried: we already make sure that we are hiding and showing again the view on the main thread, but this does not solves the problem.
We tried to call layoutIfNeeded() after modifying the property isHidden of the view, without result.
Related
I have a UITableView. When I click on a row, it will push a detail view controller to show detail info.
And, if user clicks the "Done" button on the detail view controller, I need to pop this controller and delete row on tableview controller.
I try write code on detail view's viewWillDisappear:
if let vc = navigationController?.viewControllers[0] as? TodoViewController{
vc.removeTodo(at:todoListIndex)
}
The code work fine, but just a warning:
UITableView was told to layout its visible cells and other contents without being in the view hierarchy (the table view or one of its superviews has not been added to a window). This may cause bugs by forcing views inside the table view to load and perform layout without accurate information (e.g. table view bounds, trait collection, layout margins, safe area insets, etc), and will also cause unnecessary performance overhead due to extra layout passes.
So, What is the correct way to delete row?
As the error message suggests, it is there to remind you to avoid updating the view when it isn't visible. This typically happens when you update a view in a viewWill____ state (in this case viewWillDisappear).
So what you want to do is delete the cell from TableView in viewDid___ (such as viewDidAppear)lifecycle. Then, you will no longer see warning messages.
If needed, you can use help from flag members and observables to guide correct deletion timing.
I have a HomeViewController which is loaded with views. On the top is the map view, so now when I create the table view on the top of it which does not cover the whole screen but little portion of it(actually its a drop down list in the form of tableview), it displays fine with cellForRowAtIndexPath working fine but didSelectRowAtIndexPath is not working at all.. I have tried using break point on it but its not calling this method actually infect it is selecting the view at the back i.e. the map view. Clicking on the table view is actually changing the map view behind..
I am having the table view coming from another class which is inherited by the HomeViewController
I am using some NIDropDown class .. Its working fine if no view is behind it (only superview) but not woking if it has any view behind
Few things to be ensured-
1) As you said your table view is on top of the map view. If this is the case than it's alright.
2) Check if the user interaction is enabled for the table view or not.
3) Check if you have set the delegate of the table view(responsible for detecting events on table view).
4) Check if you have not set the delegate to nil somewhere and still the table view is visible.
I think if you follow the above steps than table view's events should be triggered, otherwise it will be good if you post your code to get some other clue regarding the issue.
That cellForRowAtIndexPath works is an indication that the datasource property (UITableViewDataSource) is properly set.
If didSelectRowAtIndexPath is not firing, you should check if the delegate property (UITableViewDelegate) is properly set, either in Interface Builder or in code.
After read your problem, i strongly believe there will be two issue :
1) Map view issue, if you shows table view as *callout view
Reason:
You supposed to use “MKAnnotationView” callout view for show drop down over map.
if you do so then make sure MKAnnotationView view height would be exact same of your drop down view’s(NIDropdown view’s) height.
Table view not able to get touch, that's why it would not send message of didSelectRowAtIndexPath to it's deletegte.
In your case might be Map view getting touch, which did not suppose to get until table view is at screen.
2) Table view rest out of bound on super view
Reason:
in such case table view display normally but actually its bound goes out of own super view bound.
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.
I am wondering what happens if a single instance of a UIView object gets added as a subview of multiple other views simultaneously.
If UIView:removeFromSubview: gets called then does it get removed from all superviews or just the currently displayed one?
For background:
I have a status-bar like view object that needs to be displayed within several different other views (each other view is managed by its own view controller).
[i.e. a) the user is in one view, b) something happens to make the status-bar-like view appear, c) the user switches to another view d)the status bar is still visible in the new view e) the status bar expires after a time and disappears from site. And so on]
Initially I implemented this by adding/removing it as required as a subview of the window, and this was managed by a singleton.
However due to some complications with some animations I have instead added it as a subview of each of the main view's for each of the view controllers.
Note that there are not multiple copies
When the view needs to be removed I am calling its removeFromSuperview:, and everything is all working perfectly.
However I am wondering what the situation is regarding the removal of the view, is it being fully removed or is there something else I need to do?
For example the view might get added to N view controller's views by calling addSubview as required (it will only get added to each view controller if that view controller actually launches)
However when it is being removed I am only calling removeFromSuperview: for the view of currently loaded view controller, not all view controllers it might have been added to.
Next time I navigate to one of these other view controllers it displays fine without the view being there, even though I didn't explicitly call removeFromSuperView.
As I said everything is working as it is, however at the back of my mind I feel there might be something missing?
Hope this was understandable.
You can only have it added to one view. Documentation is your friend!
(void)addSubview:(UIView *)view:
Views can have only one superview. If view already has a superview and that view is not the receiver, this method removes the previous superview before making the receiver its new superview.
From my point of view, having to add a same view to different parent views (and more important, from different view controllers) is an indication that something is wrong on the design...
However, if you really (really) need so, I had always thought that a view instance could have one and only one parent view... Moreover, you can access it by [myView superview] message, which gives you a UIView instance instead of an array... It may auto remove from its old parent before adding to a new superview?
About the design, what about creating it each time you need a new one and have a singleton to manage their status/logic?
Good luck with that!
I have a subclass of UITableView that works just fine in one view, but when I try to use it in another view it will load with cells just fine and display them, but it doesn't respond to user input. Does anyone here have any idea as to what might be causing such paralysis?
I would also add that telling the table view to become first responder does nothing, and that it is already set to accept user interaction.
Thanks.
either the containing view has user interaction disabled, or there is a transparent view on top intercepting touches.