Translucent Status Bar with No Navigation Bar - swift

Goal: To have a table view scroll so that it shows semitransparent under the status bar while not displaying a navigation bar.
Right now, I have my tableView set to the top anchor (so technically underneath the status bar). This sets the status bar to a solid looking color as you scroll up on the table view. I've set the navigationAppearance's barTintColor and translucent to YES with no luck.
Any ideas? The view is instantiated in a storyboard

Your question is hard to guess without any code.I believe you trying to achieve a translucent status bar when tableview content scroll like you mentioned in Apple Music app.
Try below code inside your viewdidLoad method.
Step 1: To hide navigation bar. If your controller embedded with navigationController.
navigationController?.navigationBar.isHidden = true
Step 2: Place a statusBar size UIView to your controller to act as a translucent status Bar with adjusting alpha value.
let statusBarView = UIView(frame: CGRect(x:0, y:0, width:view.frame.size.width, height: UIApplication.shared.statusBarFrame.height))
statusBarView.backgroundColor=UIColor.white
statusBarView.alpha = 0.8 // set any value between 0 to 1
view.addSubview(statusBarView)
Above code will produce the following output.Let me know the code works for you.
For more information how to set tableView frame and contentView take a look at my answer in the following link.
Update:
Improved Answer:
You can use UIBlurEffectView to achieve better translucent effect.
let statusBarView = UIView(frame: CGRect(x:0, y:0, width:view.frame.size.width, height: UIApplication.shared.statusBarFrame.height))
let blurEffect = UIBlurEffect(style: .extraLight) // Set any style you want(.light or .dark) to achieve different effect.
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = statusBarView.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
statusBarView.addSubview(blurEffectView)
view.addSubview(statusBarView)
Output:

As you described, your UITableView is right underneath the status bar. When you scroll down, the tableView's frame remains the same size and origin and won't go underneath the status bar. What you want to do is to set the constraint for your tableView to the top of the superview (not the Top Layout Guide) which means it would sit right under the status bar.
Because the status bar now hides the top 20px of your tableView you want to make a content offset:
tableView.contentInset = UIEdgeInsetsMake(top: 20, left: 0, bottom: 0, right: 0)
To make the scroll indicator start right under the status bar you also want to set an offset for it:
tableView.scrollIndicatorInsets = UIEdgeInsets(top: 20, left: 0, bottom: 0, right: 0)

Related

How to make UINavigationBar shadowImage fixed?

I have a reversed UITableView:
tableView.transform = CGAffineTransform(rotationAngle: -(CGFloat)(Double.pi))
NavigationBar setup:
navigationBar.shadowImage = UIImage()
navigationBar.layer.masksToBounds = false
navigationBar.layer.shadowColor = Assets.Colors.black.color.withAlphaComponent(0.2).cgColor
navigationBar.layer.shadowOpacity = 0.7
navigationBar.layer.shadowOffset = CGSize(width: 0, height: 2.0)
navigationBar.layer.shadowRadius = 5
navigationBar.isTranslucent = false
view.backgroundColor = color
Whenever I scroll to the bottom of my TableView (to the top when inverted), shadow disappears. I want it to be constant (like at the second screenshot).
Is it possible to make UINavigationBar shadow static regardless of TableView scrolling?
How it looks now:
No shadow
How it should be:
With shadow
In iOS15/Xcode13, there is a common problem with the navigation bar's appearance. You can read more here and apply the fixes.

Is there a way to move a SwiftUI view contained within a UIHostingController into the NavBar Space

My current implementation appends the UIHostingController below the NavBar. But I want the UIhostingController to begin at the end of the status bar (the gray area below the notch). Here is the code and resulting image:
self.reviewHomePage = ReviewHomePage(reviewDict: reviewDict)
let hostingController = UIHostingController(rootView: self.reviewHomePage)
self.addChild(hostingController)
hostingController.view.frame = self.view.frame
view.addSubview(hostingController.view)
hostingController.didMove(toParent: self)
I have tried to hide the NavBar using the various techniques discussed here: Storyboard - Hiding top bar of navigation controller programmatically. But after hiding the NavBar, the space the NavBar occupies is still reserved for the NavBar (the background color is just changed to gray). I have tried to adjust the frame to start within the navBar space with the following code:
let navHeight = self.navigationController!.navigationBar.frame.minY
let topFullView = ((self.navigationController?.view.frame.minY)!) + (navHeight)
let reviewFrame = CGRect(x: (self.navigationController?.view.frame.minX)!,
y: (topFullView),
width: self.navigationController!.view.frame.width,
height: self.navigationController!.view.frame.height - topFullView)
But the UIHostingController is moved up behind the NavBar as shown in the image below.
Is it possible to completely remove the NavBar or append the view on top of the NavBar while maintaining the TabBar at the bottom of the screen? I appreciate the help!

How to set an image as title in all navigation bars in swift?

I need to know if it is possible to add an image as title on all navigation controllers, this mean, that every controller that had a navigation bar had the same image title.
I used the next code to set an image as title in the navigation bar, but I have to set it on every viewController, the idea its for example set it on AppDelegate as UINavigationBar.appereance() or similar.
let imageView = UIImageView(image: UIImage(named: "my_image.png")!)
imageView.contentMode = .scaleAspectFit
let titleView = UIView(frame: CGRect(x: 0, y: 0, width: 107, height: 30))
imageView.frame = titleView.bounds
titleView.addSubview(imageView)
self.navigationItem.titleView = titleView
So the idea is to set this image as the default title for every controller, that way I will just need to configure it one time.
It is that posible? If not, What possible solution do you think that I can apply ?
The title view is a property of each view controller, not the navigation bar or navigation controller.
So start with a UIViewController subclass whose navigation item has this title view, and make all your other view controllers be subclasses of that.
Please try below code,
let logo = UIImage(named: "logo.png")
let imageView = UIImageView(image:logo)
self.navigationItem.titleView = imageView
if this not works please share the screenshot.

Pull to refresh indicator gets miss placed when adding imageview behind nav bar

I can't figure out why this happens, but when I add a imageview behind my tableview and navigation bar, my navigation bar acts strange:
The navigation bar gets stuck in a static position and dosenĀ“t move while scrolling as it did before
The activity indicator from pull to refresh gets placed between the navigation bar button and the top of the tableview. Instead of staying on top of the navigation bars title as before.
Left picture is the bug without the imageview in the background.
Right picture show how it works perfectly without the imageview.
My code to get the clear navigation bar (Though I don't think this introduces any problem as it works fine when the imageview in the background isn't there):
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.isTranslucent = true self.navigationController?.view.backgroundColor = UIColor.clear
Found a solution.
Set the image as the backgroundview of the tableview and set the tableview to be fullscreen.
let image = UIImage(named: "myphoto")
let iv = UIImageView(image: image)
iv.contentMode = .scaleAspectFill
iv.layer.frame = CGRect(x: 0, y: 0, width: (self.tableView.superview?.frame.size.width)!, height: (self.tableView.superview?.frame.size.height)!)
let tableViewBackgroundView = UIView()
tableViewBackgroundView.addSubview(iv)
self.tableView.backgroundView = tableViewBackgroundView

Header View behind NavigationBar [duplicate]

I have a UICollectionView that is the entire view but it lives inside "view" (it is not UICollectionViewController). Adding a cell to this collection view shows it in the following order in storyboard:
This is how it looks in the emulator:
I don't understand how to get rid of that view. All the insets are at zero in Storyboard Size Inspector for collection view. Just to be sure, I also have the following code:
override func viewWillLayoutSubviews() {
let layout = self.collectionViewProducts.collectionViewLayout as! UICollectionViewFlowLayout
let containerWidth = UIScreen.main.bounds.size.width - 40.0
let itemWidth = (containerWidth / 3.0)
let itemHeight = (itemWidth / 0.75) + 30
layout.sectionInset = UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0)
layout.itemSize = CGSize(width: itemWidth, height: itemHeight)
}
How can I get rid of that top padding?
You can fix top padding issue by considering one of the following method.
Method 1: Natural way to fix your problem by setting up your collectionView dimensions properly from StoryBoard.
Method 2: **Updated**
You can validate collection frame in viewDidLayoutSubviews or viewWillLayoutSubviews
override func viewDidLayoutSubviews() {
collectionView.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height)
}
Method 3: You can Adjust Scroll View Insets from your StoryBoard Attributes Inspector.
Method 4: You can fix this issue programatically by adjusting CollectionView contentInset.
collectionView.contentInset = UIEdgeInsets(top: **Any Value**, left: 0, bottom: 0, right: 0)
Output with top padding 5:
Output with top padding 44:
Output with top padding 64:
I think because this viewController is embedded in a navigationController. Let select this viewController in the storyboard and uncheck Adjust Scroll View Insets:
There is one more way to resolve this issue and that is selecting collectionView -> scrollView Content Insets -> "Automatic" to "Never".
By default scrollView Content Insets value is Automatic. Please check the below image.
For more details check: UIScrollView.ContentInsetAdjustmentBehavior
https://developer.apple.com/documentation/uikit/uiscrollview/2902261-contentinsetadjustmentbehavior
Make your Navigation Controller > NavigationBar translucent by unchecking the Translucent check box in IB > Attribute Inspector, and it will work.
I also had the same problem, and i fixed it with a way totally ridiculous solution.
My collectionView contained several sections which had no title & no item cells.
The top, bottom inset values of the section insets were 10 respectively.
so each empty section charged height of 20 pixels.
I had 4 empty sections, and therefore, 80 top margins in the collection view.
Hope you check this as well if none of the above solutions works.