How to animate Navigationbar like AppStore App Detail Page? - ios

Navigationbar like AppStore
Transparent Navigation bar first and when app scroll up Navigation bar become visible.
Please check the effect in Gif File added with this question

First setup the navigation bar transparent like below
// Makes the navigation bar transparent
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
navigationController?.navigationBar.shadowImage = UIImage()
navigationController?.navigationBar.isTranslucent = true
navigationController?.view.backgroundColor = UIColor.clear
Now uses the UIScrollViewDelegate method scrollViewDidScroll to detect the percentage of the the scroll view and based on that change the alpha
// MARK: UIScrollViewDelegate
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
super.scrollViewDidScroll(scrollView)
let maximumVerticalOffset = scrollView.contentSize.height - scrollView.frame.height
let currentVerticalOffset = scrollView.contentOffset.y
let percentageVerticalOffset = currentVerticalOffset / maximumVerticalOffset
let color = UIColor.init(red: 255/255.0, green: 255/255.0, blue: 255/255.0, alpha: percentageVerticalOffset)
navigationController?.navigationBar.backgroundColor = color
}
Hope it is helpful to you

If you wants to make Navigation bar same like App Store I suggest you to remove the default navigation bar & create a custom Topbar by taking UIView & set up its frame as a Topbar.
The main reason is the default navigation bar is not look wise & behaviour wise looks good on iPhone X & such phones.
Another most important thing is may be you will be able to achieve it by default Navigation bar but Apple always keeps modifying the navigation system & due to that you can see deprecated methods specially in navigation.
So I better suggest if you create custom navigation it will be easily controllable & there will be no chances of the deprecated methods & all.
Hope this helps to you.

Related

How to create App Store Style Navigation Bar

I'm trying to recreate the App Store navigation bar animation. What I'm currently doing is adjusting the alpha of the navigation bar based on the scroll position.
The issue is that when you slide back the navigation bar does not appear in the previous view so I set the alpha back to one in viewWillDissapear (which doesn't work the best as seen in the gif).
With regards to the back button, if you change the alpha of the navigation bar the back button is also affected. Apple has a different back button (the circle with the arrow) when the navigation bar is not visible and this button disappears with an animation as the navigation bar appears and the default back button appears. I'm not sure if they're just overlaying a new one.
This question has been asked before but the accepted answer was to make the navigation bar transparent then change it's opacity as you scroll. This doesn't create the same effect as the default navigation bar isn't white but translucent and you also lose the border line at the bottom.
Swift 5
override func viewWillDisappear(_ animated: Bool) {
navigationController?.navigationBar.alpha = 1
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let currentVerticalOffset = scrollView.contentOffset.y
var percentageVerticalOffset = CGFloat() //currentVerticalOffset / maximumVerticalOffset
if currentVerticalOffset > collectionView.frame.size.height {
percentageVerticalOffset = currentVerticalOffset / currentVerticalOffset
self.title = "The Barn Owl"
//self.navigationItem.setHidesBackButton(false, animated: true)
} else {
percentageVerticalOffset = currentVerticalOffset / collectionView.frame.size.height
//self.navigationItem.setHidesBackButton(true, animated: true)
self.title = ""
}
// let color = UIColor.init(red: 255/255.0, green: 255/255.0, blue: 255/255.0, alpha: percentageVerticalOffset)
// navigationController?.navigationBar.backgroundColor = color
navigationController?.navigationBar.alpha = percentageVerticalOffset
}

Swift 5 custom navigation bar cover title and buttons

After seeking a lot and trying many solutions, nope fixed my problem.
In my app I customized the UINavigationController in order to have blur effect:
import UIKit
class CustomNavigationController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
let visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .regular))
visualEffectView.frame = (self.navigationBar.bounds.insetBy(dx: 0, dy: -40).offsetBy(dx: 0, dy: -40))
self.navigationBar.isTranslucent = true
self.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationBar.addSubview(visualEffectView)
self.navigationBar.sendSubviewToBack(visualEffectView)
}
}
Then in Main.storyboard I selected the customized class for the navigation controller item.
The blur effect works properly, the status icons are correctly visible, but not the standard navigation bar items: left button, title and right button.
For a moment they appears but soon after the customized navigation bar covers them.
I'm using Xcode 12.4 and I'm running the app on iPhone Xr.
How can I show the navigation bar elements again?
Thanks a lot in advance.
Translucent navigation bars in iOS already blur the content behind the bar, so you shouldn't need to add a UIVisualEffectView nor set a backgroundImage.
If you modify your code to just:
override func viewDidLoad()
{
super.viewDidLoad()
self.navigationBar.isTranslucent = true
}
does this not achieve the visual effect you're looking for?
If not, please try the following adjustment to your methodology:
override func viewDidLoad()
{
super.viewDidLoad()
self.navigationBar.isTranslucent = true
// create a UIImageView
let backgroundImage: UIImageView = UIImageView()
backgroundImage.autoresizingMask = [.flexibleWidth, .flexibleHeight]
backgroundImage.image = UIImage()
// add a blur effect to the ImageView
let visualEffectView: UIVisualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .regular))
visualEffectView.frame = (self.navigationBar.bounds.insetBy(dx: 0, dy: -40).offsetBy(dx: 0, dy: -40))
backgroundImage.addSubview (visualEffectView)
// and set that as your backgroundImage on the navigationBar
self.navigationBar.setBackgroundImage(backgroundImage.image, for: .default)
}
this adds the blur effect to the backgroundImage. This seems to work for me, but the visual effect is no different than just using my first suggestion, likely because backgroundImage.image == nil.
This is certainly an improved approach in that it doesn't add unexpected subviews into the UINavigationBar view hierarchy, and I observed both methods did not affect the visibility of the bar controls.

How to change background color of page indicator in UIPageViewController

I use a UIPageViewController in storyboard, and write a class inherit from UIPageViewController.
After I finished code, I found the background color of page indicator is black, which I don't know how to change.
I search the internet, and found many people will use UIViewController+UIPageControl to do custom page indicator.
Is it possible to change the background color in UIPageViewController?
Thanks!
by adding:
let pageControl = UIPageControl.init(frame: CGRectMake(0, UIScreen.mainScreen().bounds.size.height*14/15, UIScreen.mainScreen().bounds.size.width, UIScreen.mainScreen().bounds.size.height))
pageControl.backgroundColor = UIColor.init(red: 0, green: 147/255, blue: 229/255, alpha: 1)
view.addSubview(pageControl)
I've changed the color successfully.
But I've another question.
Although I've set the imageView to fill the full screen, the page control will cover the button of the image, how could I avoid page control cover the image, and only show the dots?
I struggled with this for over two hours. Here's what I did in Swift 4
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
for view in self.view.subviews{
if view is UIPageControl{
(view as! UIPageControl).currentPageIndicatorTintColor = .yellow
}
}
}
Once you have the UIPageControl in this block, you should be able to customize its indicator colours

Remove border between View and Search Bar

So in Xcode I'm trying to create a seamless search bar. So I'm trying to replicate something like this
Note how the status bar is the same color as the search bar. Now here's the result to my approach.
What I did was add a View to cover up the default status bar with the blue background. Then I added a search bar and changed it's background to blue. For some reason I end up getting a black border between the two, which ruins the "seamless" design. Any ideas on how I can remove the black border in Swift?
For iOS 7+:
searchBar.backgroundImage = UIImage()
Otherwise this will work on all iOS versions:
searchBar.layer.borderWidth = 1
searchBar.layer.borderColor = thatBlueColor.CGColor
Swift 4
searchBar.barTintColor = UIColor.white
searchBar.setBackgroundImage(UIImage.init(), for: UIBarPosition.any, barMetrics: UIBarMetrics.default)
Sample image
Upate Sample code for navigation bar and search bar background color:
Navigation bar color
self.navigationController?.navigationBar.barTintColor = .blue
Search bar color
searchBarProperty.backgroundColor = self.navigationController?.navigationBar.barTintColor
Note : Navigation bar and search bar color must be same.
Sample image with blue navigation bar and blue search bar
In Xcode 8.3 and Swift 3
Create an outlet from your search bar to your ViewController (I called mine searchBarOutlet for this example).
Below viewDidLoad insert the following.
self.searchBarOutlet.backgroundImage = UIImage()
You should have the following:
override func viewDidLoad() {
super.viewDidLoad()
self.searchBarOutlet.backgroundImage = UIImage()
When you run your app the lines will be gone (they will still be visible on storyboard).
In my case, beyond the edge of search bar needed to take the edge off also the navigation bar.
C# code:
NavigationController.NavigationBar.ShadowImage = new UIImage();
NavigationController.NavigationBar.SetBackgroundImage (new UIImage (), UIBarMetrics.Default);
Swift code:
self.navigationController.navigationBar.shadowImage = UIImage()
self.navigationController.navigationBar.setBackgroundImage(UIImage(), forBarMetrics: .Default)
The best solution to remove top and bottom default borders is:
To set a new empty searchBar background layout in viewDidLoad for example:
searchBar.backgroundImage = UIImage()
I found these answers to be more complicated than they needed to be. You can just modify the constraint that is binding the searchBar view and the other view to -1pts so that it overlaps exactly by the height of the searchBar's margin.
I encountered the same situation when I set the statusBar and searchBar translucent.
In this situation, I couldn't resolve with the answers written here however I could solve by the following approach.
put UIVisualEffectView on self.view (view of your VC)
make custom class of searchBar, which background is transparent
(also let statusBar transparent)
(swift4 code)
class TransparentSearchBar: UISearchBar {
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
makeTransparentBackground()
}
private func makeTransparentBackground() {
for view in self.subviews {
view.backgroundColor = UIColor.clear
for subview in view.subviews {
if let imageview = subview as? UIImageView {
imageview.image = nil
}
}
}
}
}
somewhere in viewDidLoad (statusBar)
let statusWindow = UIApplication.shared.value(forKey:"statusBarWindow") as! UIView
let statusBar = statusWindow.subviews[0] as UIView
statusBar.backgroundColor = UIColor.clear
in Xcode 13
select the search bar and change the search Style to Minimal

Swift : How to change navigation controller's height without adding a toolbar

How to change navigation controller's height without adding a toolbar ?
Here is an example of apple's iBooks app that I want to build.
I've a solution but isn't perfect( adding a toolbar below the nav controller but it is very ugly)
I think this is what you want,
screenshot
You can not change navbar height,but you can put a view under it,and use autolayout and shadow to make it looks like part of navbar.Set it to the class you made
Write a view to act as the extendbar
class ExtendNavView:UIView{
override func willMoveToWindow(newWindow: UIWindow?) {
let scale = UIScreen.mainScreen().scale
self.layer.shadowOffset = CGSizeMake(0, 1.0/scale)
self.layer.shadowRadius = 0;
self.layer.shadowColor = UIColor.blackColor().CGColor
self.layer.shadowOpacity = 0.25
}
}
Drag a UIView and put it under the navBar,then set autolayout to make it always under the nav
Change the navBar property in your viewController
class ViewController: UIViewController {
override func viewDidLoad() {
self.navigationController?.navigationBar.translucent = false
self.navigationController?.navigationBar.shadowImage = UIImage(named: "TransparentPixel")
self.navigationController?.navigationBar.setBackgroundImage(UIImage(named:"Pixel"), forBarMetrics:UIBarMetrics.Default)
}
}
The two image used here(Note:they are Translucent)
Pixel
url= "http://i.stack.imgur.com/gFwyN.png"
TransparentPixel
url = "http://i.stack.imgur.com/zpQw4.png "
You can also look at the Apple example project,you can also find the two images there
https://developer.apple.com/library/ios/samplecode/NavBar/Introduction/Intro.html

Resources