Top Safe Area Constraint Animation - ios11

Setup
A simple view controller with a UISearchController set in the navigation item to use iOS 11's search functionality in the search bar.
Any view with it's top constrained to the SafeArea.Top
Problem
When presenting the search controller, the navigation bar is animated because of it's size change, but the constraint to top area does not follow the animation.
If anyone have an idea of what I can do (right now I guess my only choice is to disable the hidesNavigationBarDuringPresentation to avoid the animation at all)
See example below where I activated the slow animations for easier understanding:

You could animate the constraint change with UIView.animate. Since your constraint is based on the view's safe area, the viewSafeAreaInsetsDidChange method could alert you of changes in the constraint value :
override func viewSafeAreaInsetsDidChange() {
UIView.animate(withDuration: 1) {
self.view.layoutIfNeeded()
}
}

I faced the same issue on iOS 13.3.
This code fixed it.
override func viewDidAppear(_ animated: Bool) {
     super.viewDidAppear(animated)
     navigationController?.view.backgroundColor = .white
     navigationController?.navigationBar.isTranslucent = false
}
If you disable isTranslucent on viewDidLoad, searchBar would be hidden when the view appears.
You can also utilize navigationItem.hideSearchBarWhenScrolling to avoid putting the code in viewDidAppear.

Related

codename one how to add a badge to the sideMenu Icon in toolbar

how can I add a budge to that SideMenu Icon
mainToolbar.addComponentToSideMenu(avatarBox);
mainToolbar.addMaterialCommandToSideMenu(" Home", FontImage.MATERIAL_HOME, e -> {
ManagementDashboard mdas = new ManagementDashboard(this);
mdas.Home();
});
The questions is a bit vague and I am not sure that i understand what you are asking, but in my experience, the only way to customize the toolbar to do anything beyond what the out-of-the-box toolbars methods offer is to use setTitleComponent and add your own custom container to your toolbar. The downside of this is that you will have to redesing a lot of your toolbars as you will be basically creating them again from scratch. You can center a new container with setTitleComponent, override its calcPreferredSize to stretch it across the entire toolbar horizontally, and stick stuff in it as you would in any Container (use any Layout, etc)
Another way of achieving your goal would be to extend the Toolbar class and manually change things within it. But the Toolbar class is quite heavy and you might spend much more time trying to figure out what to change than by using the first method
Method #1 sample code:
//stick stuff in this container to create your own toolbar
Container titleContainer = new Container(new BorderLayout()) {
#Override
protected Dimension calcPreferredSize() {
Dimension original = super.calcPreferredSize();
return new Dimension(Display.getInstance().getDisplayWidth(), original.getHeight());
}
};
form.getToolbar().setTitleComponent(titleContainer);
Here is an example of what could be achieved if you go this route (pretty much anything):

How to fix UISearchBar flick animation while transitioning view controllers?

From iOS 11 (and above) i try to incorporate large titles (with UISearchController). One of my screen doesn't have a UITableView as first child on the hierarchy (but rather UIPageViewController, this cause that the navigationBar is not collapsed because the scrollView is not the first child.. but due to structure design can't.. anyway that's not an issue).
When another screen is pushed (and that screen has navigationItem's largeTitleDisplayMode set to never), the transition animation looks weird (the UISearchBar is closed from the center and is not in sync with the navigationBar animation).
Note: If the controller that is pushed has largeTitleDisplayMode set to .automatic (or always) the transition is ok.
Background
When the prefersLargeTitle is enabled, navigationItem's searchController is set and the first view on the hierarchy is not a tableView (or i guess scrollView descendent), the navigationBar shows the searchBar open.
Options Tried
I tried modifying the translucent property of the UINavigationBar and UISearchBar. Also set the UINavigationBar's clipToBounds.
Code
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.prefersLargeTitles = true
self.navigationItem.largeTitleDisplayMode = .always
navigationItem.searchController = UISearchController(searchResultsController: nil)
}
}
class SecondViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.largeTitleDisplayMode = .never
}
}

UINavigationItem 'searchController' Bug(?)

I’m using the new UINavigationItem 'searchController' property and it’s working great except for one issue.
Here's a screen shot of my view controller with the search bar in use:
The problem occurs when I select an item and then push a view controller that does not display the navigation bar onto the navigation stack. Here's the result:
All of a sudden I have all this space at the top of the screen.
 
'navigationController?.setNavigationBarHidden(true, animated: true)' does not do anything because the nav bar is already hidden on the previous screen.

'searchController.hidesNavigationBarDuringPresentation = false'
will fix the weird space issue, but I don't want the nav bar displayed during a search:
What is the real solution for this? Is this in fact a bug? I think so, yes?

How to stop animation flickering

Are there some generic techniques for stopping the display flickering? I'm guessing that I have two layout animations that are fighting over the controls or something - this seems to happen in a few places in my app (hence the general question).
I'll try and be more specific too:
I have a Box Layout Y Container which contains a list of MultiButtons. The MultiButtons are my own class which inherits MultiButton. It (all the buttons) flicks when I come back to the Form from another form. In the beforeForm function I do this:
for (my loop)
{
MultiButton mb = new MultiButton();
...init code for mb, like setTextLine1();
container.addComponent(mb);
lastMb = mb;
}
container.revalidate();
container.scrollComponentToVisible(lastMb);
The beforeForm method is invoked before the form is shown so there is no need to revalidate at that stage (show implicitly does that).
What's scrollToComponent? If you remove it does it flicker?
To scroll to a component without an animation do:
container.setSmoothScrolling(false);
container.scrollComponentToVisible(cmp);
container.setSmoothScrolling(true);

ExtJS 4.0.7 scrollTo() scrolls but doesn't move scroll bar slider?

I have a tree panel and am trying to do an animated scroll to certain locations. I'm doing something like this:
myTreePanel.getView().getEl().scrollTo('top', yCoord, true /*animate*/);
The view scrolls to the correct location, but the "slider" in the scroll bar doesn't move. Any ideas why?
Some additional info: if I do the following instead, the scrollbar slider moves correctly (but of course scroll() doesn't support animation--I'd prefer to use .scrollTo() so the user can see the scrolling):
myTreePanel.getView().getEl().scroll('down', yDiff);
Thanks for any help/advice!
#MoleculeMan's suggestion of disabling the custom scrollbars (which ExtJS uses in 4.0.x but not in 4.1) does work. After doing this you can call myTreePanel.getView().getEl().scrollTo('top', yCoord, true) and everything works as expected: scrolling is animated and the scrollbar moves. The only problem is that it seems to break the ability for the view to scroll if you use the up/down arrow keys to move through the tree.
It's not very elegant, but the work-around I'm going to use is this:
// Animated scroll of tree view
myTreePanel.getView().getEl().scrollTo('top', yCoord, true);
// Wait 300ms then sync the scroll bar with the tree view
setTimeout(function() {
myTreePanel.setScrollTop(yCoord);
}, 300);
This has the cosmetic disadvantage of the scroll bar "jumping" into place instead of smoothly moving with the animation, but the benefit of not breaking the up/down key scrolling. Also, because it doesn't involve changing config params or overriding the tree view's style, I'm assuming it will still work once we upgrade to ExtJS 4.1 (i.e., the timer call to setScrollTop() will be unnecessary but shouldn't break anything).
Note that calling setScrollTop() moves the scrollbar, but also causes the view to "jump" to that position. You therefore need to ensure that the timer doesn't fire until after the animation finishes. I'm actually using some custom code to poll every 10ms and see if the destination row is visible, then calling setScrollTop(), instead of using a timer that always waits for some hard-coded amount of time:
var scrollToRowNum = 5;
var scrollToEl = getElementForNode(myTreePanel.getRootNode().childNodes[scrollToRowNum]);
var yCoord = scrollToEl.getOffsetsTo(scrollToEl.parent())[1];
// Animated scroll of tree view
myTreePanel.getView().getEl().scrollTo('top', yCoord, true);
// Check every 10ms to see if animation is done, then sync scrollbar
var timerId = setInterval(function() {
if( myTreePanel.isTreeElementWithinVisibleArea(scrollToEl) ) {
clearInterval(timerId);
myTreePanel.setScrollTop(yCoord);
}
}, 10);
The isTreeElementWithinVisibleArea() function just checks to see if element's current Y coordinate (absolute) is between the top and bottom of the tree view box.
Not surprising. They use their own scrollbar. The correct code would be:
myTreePanel.verticalScroller.setScrollTop(yCoord);
However, it doesn't support animation either. So I recommend to get rid of custom scrollbar as I've described here and use your original code.

Resources