I'm using Swift 4 with xcode 9.1. This question is somewhat confusing, so I've included images to hopefully help out.
Here is my setup:
When I navigate from VC1 to subVC1, then tab over to VC2 and into subVC2, then tab back to subVC1, everything works perfectly.
When I do the above after having typed something into the search bar in VC1, I get view A (below, black screen).
When I set definesPresentationContext = true for VC1, this solves the black screen problem but creates a new problem. Normally when you segue back from subCV1 to VC1 with something typed in the searcher, it looks like view B (below, middle panel). With definesPresentationContext = true, VC1 ends up looking like view C (below, right panel) after segueing back from subVC1. Everything is shifted up and hidden by the searchbar.
This also happens for the unnamed VC above that also navigates to subVC1.
How might I figure out why the content is being shifted up and how to fix it?
I came across this post several times while investigating a similar problem, so I wanted to post my findings here.
My UITableViewHeaderFooterView was "popping" onto the top of my search results - located in a UITableView - a split second after navigating back from a ViewController to my UISearchController.
"Under top bars" was checked in my Storyboard file as above, but I had declared definesPresentationContext in my code.
I found out that I needed to add an additional line so that the header wouldn't jump anymore:
extendedLayoutIncludesOpaqueBars = true
definesPresentationContext = true
It prevented both the "black screen" issue and the content shifting problem.
After testing out quite a lot of solutions (setting content y position, confirming proper constraints), I found the issue.
Whereas previously, my setup necessitated unchecking Extend edges under top bars, the new setup requires that it be checked. See new working setup below, which fixes all visual glitches in my original question. Hope this helps someone!
Related
No matter what I do, the segue kind is always present modally (one vc on top an other). This is even when it is not set to it. At the moment my segue is set to "Show" but even still, the bar at the top of the view controller is still there and when I run the app it does the present modally over the top animation.
I don't know where to go from here!!
Reseting my computer.
Reinstalling Xcode.
Different ways of showing the vc.
This is what I mean by white bar at top
Update: I have seen your screenshot update to the question and I would like to point out that the issue that you are trying to solve has nothing to do with modal presentations. The content of the ‘view’ of a ‘UIViewController’ does not fill the screen because it’s constrained either to the Safe Area or the margins of the its superview.
Initial answer:
Lol but that’s a feature and not a bug. The “Show” setting that you are talking about only controlls the animation. In order to discard all instantiated modal presentation contexts you have to swap out the ‘rootViewController’ of the ‘UIWindow’ in which this contexts exist.
Please note that storyboard segues feature no support for this in UIKit.
Please note that usage of storyboard segues is an ill practice and should be considered deprecated. The primary reason for this is that it prevents programmer from establishing a proper routing layer in the application leading to a rapidly increasing technical debt.
The reason is that Show has a complex meaning. It means:
"If our parent is a UINavigationController, push. Otherwise, present modally."
Well, your parent is not a UINavigationController. There is no UINavigationController anywhere around! So Show ends up meaning exactly the same thing as Present / Modal.
I am at a loss with what is potentially a simple fix.
I have a basic ViewController with a UINavigationController, and a UISearchBar embedded.
Basic view layout
When I PUSH a new UIViewController onto the Nav - I get a brief animation issue where a black background appears, and also the cancel button doesn't disappear.
Animation glitch
It's only brief, but annoying enough.
When I return back using the back button, the search bar reverts to white, and then switches to red.
Back display issue
I wondered if I had configured something wrong, so I created a fresh project and left everything with the defaults. Yet I get the same issue.
Stripped back and the same issue
I'm using xCode 9.3 - with swift 4.1
Any ideas?
Check the extendedLayout settings of your view controllers (these can be set in code or in the storyboard editor). They need to be the same for both view controllers or you'll get this animation glitch.
In your case the problem might be the embedded search bar. It seems to be present only for one of the view controllers. You've got navigation bars with two different heights because of that. The framework doesn't respond well to that...
I tried to update one of my IOS6 app to IOS7 using Xcode 5 GM which was just released couple of days ago.
One of the main problem I met is that some of the table views (UITableViewController) cannot be shown correctly anymore after being recompiled by IOS7 SDK:
Some of them cannot shown the last cells completely: You can see half of the last cell right there, but cannot scroll down to see full of it; some others cannot show the first cells completely: half of the cells was hide and you need to draw down the table view to see it.
BTW, those problematic tableViewControllers are all embedded in tab bar controllers.
Could anybody help me with this? Thanks.
UPDATE:
I tried several ways, and here's my solution:
Delete the tab bar controllers, and add them back through editor->embed in->tab bar controller (I tried to drag out a tab bar controller from the object library directly, but that didn't fix the problem. Don't know why).
Re-link other view controllers to this new tab bar controller and run the app. Now, you probably see the first cell still cannot be show completely as I described before, but the last one can be shown correctly.
Go back to storyboard, select the tab bar controller and deselect "under top bars" in the attributes inspector. Run it again, everything works fine, at least for me.
I think it's not a bug but rather a UI design as intended. As you can see the overlap of Tabbar still have some see through effect.
As I dont want to resize my table view to fit specific above the Tabbar.
Workaround with last cell bottom padding or add in extra last cell with same height as Tabbar?
Before Starting I want to make sure one thing whether we can make the ViewController transparent (alpha), as far my knowledge it is NO.
I have a ViewController which consists of 8 UIButton objects over it. Whenever I press Button1, Button2 I am loading a ViewController. Since the ViewController cannot be made transparent, I just moved that View to my HomeViewController.xib and I am loading the view using -addSubView:. And I am changing the alpha value to make it as transparent.
But the thing is in Button1 View and Button2 View, in both views I am having table view. When I bring everything to the same HomeViewController class , I am having too much of code in a single class.
Is there any way to do this?? Adding many Views in the same ViewController not a problem, but it increases the code too. Which looks ugly. Please help me out.
If I have confused about my question here I am giving a short description of what I would like to do
Whenever I press a Button in ViewController, I want to load a View/ViewController Transparently.
Before Starting I want to make sure one thing whether we can make the
ViewController transparent (alpha), as far my knowledge it is NO.
You can't adjust a view controllers alpha directly. You can adjust a view controllers view properties alpha, ex: myViewController.view.alpha, and you can do this for any view that you want except for your root view (the bottom of the view stack). Lowering your root views alpha would allow the user to see the springboard through your app.
But the thing is , In Button1 View and Button2 View , in both views I
am having table view. When I bring everything to the same
HomeViewController class , I am having too much of code in a single
class.
Is there any way to do this ?? Adding Many Views in the same
ViewController not a problem, but it increases the code too. Which
looks ugly. Please help me out.
I'm not sure I understand the problem here. As long as you format your code correctly and keep well organized this isn't a problem. I personally have used view controllers in excess of 15k lines of code and never had a problem, and I'm sure there are developers that have used way more.
If I have confused about my question here I am giving a short
description of what I would like to do Whenever I press a Button in
ViewController , I want to load a View/ViewController Transparently.
Continue the way you have been describing. (adding alpha adjusted UIView's as subviews) There is nothing wrong with this approach.
I have a UIViewController that is pushed onto a UINavigationController and is currently displayed. When I go to start some asynchronous task inside the view controller, I can set hidesBackButton on self.navigationItem to YES, and the back button is hidden correctly.
As soon as the task is finished, and I set hidesBackButton back to NO (on the UI thread, I might add, I've made sure of this), nothing happens. The back button remains hidden.
Has anyone seen this before? What drives me especially crazy is that in my application (the same application), in a different UINavigationController hierarchy, the exact same code works correctly!
Are you calling hidesBackButton = NO from a thread? All UI operations should be done on the main thread, otherwise they won't have any effect.
i have not been able to replicate your problem on my machine. however, i faced a similar issue with tableviews even when i was updating my ui on the main thread. but calling setNeedsDisplay fixed that issue.
Can you try this and see if this works:
[self.navigationController.navigationBar setNeedsDisplay];
I guess this should work, you need to do the same, BUT ON THE NAVIGATIONBAR instead. please let me know if this worked - as i cannot test my solution because i never get this problem :-)
Have you tried forcing the view to refresh by calling setNeedsDisplay?
Maybe the OS is not picking up the changes instantly and you need to force it.
Have you tried using the setHidesBackButton:animated: method instead? Perhaps that has a slightly different behavior.
In my case I simply had to give a title to the view, as in:
self.navigationItem.title = #"Menu";
Marinus
I have had a similar issue recently. I tried literally everything I found in SO and other forums- nothing worked.
In my case there was a modally shown UINavigationController with a simple root controller which would push one of two view controllers (A and B) on top of the controller stack when the button A or B was pressed, respectively. Controller B was the one which was not supposed to show the back button. But still, sometimes it did, sometimes it didn't.
After hours of debugging, I managed to track it down. Controller A was a UITableViewController. Each time I selected a cell in this controller, the delegate would pop Controller A off the stack. BUT. I made use of a UISearchDisplayController as well. Turned out that popping the view while the search controller was still active messed up something in the navigation controller that made it impossible to hide the back button in Controller B afterwards (well, it eventually stayed hidden between viewDidLoad and viewDidAppear: but then it always turned visible).
So the solution (rather workaround) was adding this line to where Controller A was dismissed:
controllerA.searchDisplayController.active = NO;
// ...
// [self.navigationController popViewControllerAnimated:YES];
Hope this spares someone a couple of hours.