func clearBackgroundColor(of view: UIView) {
if let effectsView = view as? UIVisualEffectView {
effectsView.removeFromSuperview()
return
}
view.backgroundColor = .clear
view.subviews.forEach { (subview) in
clearBackground(of: subview)
}
}
I have already tried this code and the resulting AlertController's border has removed but the border of buttons inside AlertController is still there.
Related
I am very new to swift and am building a navigation view. Below is what i ran into.
currentView
The navigation bar background color is only partly yellow. How can I also make the section above it also yellow?
section should be yellow
Below is the code that I used in my viewController. I also tried in the navigation controller but it doesn't work.
self.navigationController?.navigationBar.backgroundColor = UIColor.yellow
How to set the height of the navigation bar? The search button (navigationItem.titleView) is right in the middle of the navigation bar and I want to give it more space by setting the navigation bar height. The code below is what I tried but doesn't work :(
self.tabBarController?.tabBar.frame.size.height = 50
Thanks.
you have to changed the status bar color as well. you can done this using below extension of UIApplication
extension UIApplication {
var statusBarView: UIView? {
if responds(to: Selector(("statusBar"))) {
return value(forKey: "statusBar") as? UIView
}
return nil
}
}
use above extension like this :
UIApplication.shared.statusBarView?.backgroundColor = .yellow
for iOS 13 and above
use UINavigationController extension to change status bar color :
extension UINavigationController {
func setStatusBar(backgroundColor: UIColor) {
let statusBarFrame: CGRect
if #available(iOS 13.0, *) {
statusBarFrame = view.window?.windowScene?.statusBarManager?.statusBarFrame ?? CGRect.zero
} else {
statusBarFrame = UIApplication.shared.statusBarFrame
}
let statusBarView = UIView(frame: statusBarFrame)
statusBarView.backgroundColor = backgroundColor
view.addSubview(statusBarView)
}
}
navigationController?.setStatusBar(backgroundColor: .yellow)
So I'm looking for how can I add shadow to NavigationBar and remove the bottom black line from NavigationBar? Also if I have searchBar in NavigationBar then shadow should go below to search bar. I want to make a change globally without making a change in every viewController.
https://imgur.com/a/8ogGRaf.jpg
So I already archive these changes except add a shadow below to search controller.
For Shadow:
self.navigationController?.navigationBar.isTranslucent = false
self.navigationController?.navigationBar.layer.shadowColor = UIColor.black.cgColor
self.navigationController?.navigationBar.layer.shadowOffset = CGSize(width: 0.0, height: 0.0)
self.navigationController?.navigationBar.layer.shadowRadius = 7.0
self.navigationController?.navigationBar.layer.shadowOpacity = 0.2
For Remove a Bottom Bar:
UINavigationBar.appearance().backIndicatorImage = UIImage(named:"normal")
UINavigationBar.appearance().backIndicatorTransitionMaskImage = UIImage(named:"normal")
This is What issue I'm getting with search Bar
https://imgur.com/a/QQ9yrbE
2.hide bottom line
public extension UINavigationBar {
/// Hide line under navigation bar
public func hideBottomHairline() {
let navigationBarImageView = hairlineImageViewInNavigationBar(self)
navigationBarImageView!.isHidden = true
}
/// Show line under navigation bar
public func showBottomHairline() {
let navigationBarImageView = hairlineImageViewInNavigationBar(self)
navigationBarImageView!.isHidden = false
}
fileprivate func hairlineImageViewInNavigationBar(_ view: UIView) -> UIImageView? {
if view.isKind(of: UIImageView.self) && view.bounds.height <= 1.0 {
return (view as! UIImageView)
}
let subviews = (view.subviews as [UIView])
for subview: UIView in subviews {
if let imageView: UIImageView = hairlineImageViewInNavigationBar(subview) {
return imageView
}
}
return nil
}
}
So I am in a mildly complicated situation,
The issue: There is a thin blue line that goes across my Custom UITableViewSectionHeader only when under navigation bar that I do not know where is coming from:
I have:
A tableview nested inside a UIViewController
A GradientView (inherits UIView) directly under my NavigationBar
A TableView that overlaps my GradientView
A Custom TableViewSectionHeader Class (Subclass UITableViewCell)
[
My theory:
That border line is either from:
- The bottom border of navigation bar
- The top border of tableview
- Maybe a separator from the Section header (but seems unlikely)
- A bottom border from the GradientView
Anybody have an idea what could be causing that line?
I have tried to remove it with:
ViewController:
override func viewDidLoad() {
// self.tableview.separatorStyle = .none
// self.tableview.layer.borderWidth = 0
// self.view.layer.borderWidth = 0
}
GradientView:
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.layer.borderWidth = 0
}
SectionHeader:
self.separatorInset.left = 1000
self.layer.borderWidth = 0
Any thoughts?
Navigation bars has an image view with a line which is somewhere between less than or equals to 1px you have to loop through NavigationController navigationBar to find that imageView and set that to hidden.
You can directly loop on navigationBar and find all subViews or if you want to have a reference to the view then here how I would have done it.
var lineImageView: UIImageView? = { [unowned self] in
// guard is great try to use it whenever you can
guard let navigationBar = self.navigationController?.navigationBar else {
return nil
}
return self.findLineImageView(for: navigationBar)
}()
now add this function which loops through till it finds an imageView and return it back to our lineImageView
// remember even **navigationBar** is a UI remember **UINavigationBar**
func findLineImageView(for view: UIView) -> UIImageView? {
// as I said above the line is not more than 1px so we look for a view which is less than or equals to 1px in height
if view is UIImageView && view.bounds.size.height <= 1 {
return (view as! UIImageView)
}
// we loop till we find the line image view and return it
for subview in view.subviews {
if let imageView = findLineImageView(for: subview) {
return imageView
}
}
// if there is no imageView with that height we return nil that's why we return an optional UIImageView
return nil
}
Now the magic part. in viewWillApear set the lineImageView to hidden
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// remember as I said the lineImageView we returned an optional that's why it has question mark which means we are safe
lineImageView?.isHidden = true
}
I tried to modify the color of the UIScrollView indicators. In my case is a table view.
The problem is, in swift 3 I used the code
override func scrollViewDidScroll(_ scrollView: UIScrollView){
let verticalIndicator: UIImageView = (scrollView.subviews[(scrollView.subviews.count - 1)] as! UIImageView)
verticalIndicator.backgroundColor = Color.red
}
It's perfect and it work.
Now the same code in Swift 4 not working.
I tried with
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let color = UIColor.red
guard
let verticalIndicator = scrollView.subviews.last as? UIImageView,
verticalIndicator.backgroundColor != color,
verticalIndicator.image?.renderingMode != .alwaysTemplate
else { return }
verticalIndicator.layer.masksToBounds = true
verticalIndicator.layer.cornerRadius = verticalIndicator.frame.width / 2
verticalIndicator.backgroundColor = color
verticalIndicator.image = verticalIndicator.image?.withRenderingMode(.alwaysTemplate)
verticalIndicator.tintColor = .clear
}
but not working. The scroll indicator exist in my view and is visible with the "Debug View Hierarchy" but is like as background transparent.
Does anybody know is there any way to call status bar tapping programmatically when view appeared? My view is not on the top when appearing.
Thank you!
I'm going to assume that what you want to do is scroll your view to the top, which is what tapping the status bar does. If that's the case then here is a nice little view controller extension to achieve that.
extension UIViewController {
func scrollToTop() {
func scrollToTop(view: UIView?) {
guard let view = view else { return }
switch view {
case let scrollView as UIScrollView:
if scrollView.scrollsToTop == true {
scrollView.setContentOffset(CGPoint(x: 0.0, y: -scrollView.contentInset.top), animated: true)
return
}
default:
break
}
for subView in view.subviews {
scrollToTop(view: subView)
}
}
scrollToTop(view: view)
}
var isScrolledToTop: Bool {
for subView in view.subviews {
if let scrollView = subView as? UIScrollView {
return (scrollView.contentOffset.y == 0)
}
}
return true
}
}
Then in the viewDidAppear of your view controller, you can call
myViewController.scrollToTop()