How to make UINavigationBar shadowImage fixed? - swift

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.

Related

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

Swift 4 upgrade issue with imageViews as bar buttons within navigation bar

So I have upgraded to swift 4 and now my left & right uiimageviews set as left/right nav button items are showing as large icons. I have figured out that the Frame setting is not being applied and I am not sure why.
Does anyone know what may cause this?
Here is some code
lazy var leftBarPic: UIImageView = {
let pic = UIImageView(frame: CGRect(x: 0, y: 0, width: 25, height: 25))
pic.clipsToBounds = true
pic.contentMode = .scaleAspectFit
pic.image = myImage.withRenderingMode(.alwaysOriginal)
pic.isUserInteractionEnabled = true
pic.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(postNewsAction)))
pic.backgroundColor = .green
return pic
}()
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.leftBarButtonItem = UIBarButtonItem(customView: leftBarPic)
}
OK I found a fix. For anyone having similar, what I did was add the property (in this instance the left navigator imageView) to the view's subview. Then added the constraints for width and height. It seems that with the upgrade setting the frame for nav items (image views only) inside the property does not work.

Translucent Status Bar with No Navigation Bar

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)

Why I cannot make my UITabBarController blurred?

I have a UITabBar and I want to make it blurred. I wrote the following code:
import UIKit
class TabBarController:UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
let blur = UIBlurEffect(style: UIBlurEffectStyle.Light)
let blurView = UIVisualEffectView(effect: blur)
blurView.frame = self.view.bounds
blurView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
self.view.layer.insertSublayer(blurView, atIndex: 0)
}
}
but somehow the last line throws error:
Cannot convert value of type 'UIVisualEffectView' to expected argument
type 'CALayer'
how can I fix that?
I changed the last line to:
self.tabBar.addSubview(blurView)
but now the whole tabbar is blurred (even with icons and they are not visible). When I changed this line to:
self.tabBar.sendSubviewToBack(blurView)
then the tabbar is visible, but not blurred. I want to achieve effect from accepted answer from here Black background on transparent UITabBar but here it is uitabbar and I'm using uitabbarcontroller... Can you help me with applying blur in my case?
You just add the blur view as a subview:
self.view.addSubview(blurView)
Since you just want to blue the tab bar and this class is a tab bar controller, you can do:
self.tabBar.addSubview(blueView)
You also need to change the frame:
blurView.frame = self.tabBar.bounds
why don't you just use the barTintColor property on your TabBarController?
self.tabBar.translucent = true
self.tabBar.barTintColor = UIColor.blackColor()
You don't even need to subclass UITabBarController. You can call this on any UIViewController.
self.tabBarController?.tabBar.translucent = true
self.tabBarController?.tabBar.barTintColor = UIColor.blackColor()
If I understood correctly from the following comment that you posted, you want to change the UITabBar to be black in colour but still blurred.
And yes, I noticed that the UITabBarController is blurred by default, but I would like to make it blurred with specific style (.Dark).
Doing this since iOS 7 has actually become quite easy. Simply change the barStyle of your UITabBar to .black. Put the following code in your UIViewController's viewDidLoad method (note that UITabBar is translucent by default, so you don't need to specify that again).
tabBarController?.tabBar.barStyle = .black
If you want to set it back to the regular, white barStyle, change it back to .default.
tabBarController?.tabBar.barStyle = .default
You may even do this from within Interface Builder by selecting the Tab Bar in your UITabBarController's hierarchy and changing its Style to Black.
I have a solution, all you need is configure your UITabBar as following:
// next code will make tabBar fully transparent
tabBar.isTranslucent = true
tabBar.backgroundImage = UIImage()
tabBar.shadowImage = UIImage() // add this if you want remove tabBar separator
tabBar.barTintColor = .clear
tabBar.backgroundColor = .black // here is your tabBar color
tabBar.layer.backgroundColor = UIColor.clear.cgColor
If you want to add blur, do this:
let blurEffect = UIBlurEffect(style: .dark) // here you can change blur style
let blurView = UIVisualEffectView(effect: blurEffect)
blurView.frame = tabBar.bounds
blurView.autoresizingMask = .flexibleWidth
tabBar.insertSubview(blurView, at: 0)
As a result:
Attach bottom constraint to the bottom of the view instead of Safe Area
It just might not be a problem with your TabBar but with tableView constraints.
Tab bar is blurred by default.

How to add drop shadow in uicollectionview using swift?

I want to add drop shadow in uicollectionview. CollectionView is just covering half of screen, So want to add drop shadow on bottom.
This will make a drop shadow at the bottom of the UICollectionView
myCollection.layer.shadowColor = UIColor.blackColor().CGColor
myCollection.layer.shadowOffset = CGSizeMake(0, 1)
myCollection.layer.shadowOpacity = 1
myCollection.layer.shadowRadius = 1.0
myCollection.clipsToBounds = false
myCollection.layer.masksToBounds = false
Note that UICollectionView is initialized with the following by default:
clipsToBounds = true
layer.masksToBounds = true
and you must set them to false otherwise the shadow will not be displayed.