iOS non blocking status bar - swift

I'm trying to place an image behind the status bar.
I'm able to turn it transparent but It's still blocking the image from appearing behind it.
Does anybody know how to make the status bar apart of the editable screen and/or safe area? I don't want to delete it, just want to put stuff behind it.
Here's what IB looks like
Code
override func viewWillAppear(_ animated: Bool) {
setNeedsStatusBarAppearanceUpdate()
}
override func viewDidLoad() {
super.viewDidLoad()
venueInfoTableView.dataSource = self
venueInfoTableView.delegate = self
// Do any additional setup after loading the view, typically from a nib.
venueInfoTableView.separatorStyle = .none
}
override var preferredStatusBarStyle : UIStatusBarStyle {
return UIStatusBarStyle.lightContent
//return UIStatusBarStyle.default // Make dark again
}
And here's the result

You should disable automaticallyAdjustsScrollViewInsets
if #available(iOS 11.0, *) {
self.venueInfoTableView.contentInsetAdjustmentBehavior = .never
} else {
self.automaticallyAdjustsScrollViewInsets = false
}
contentInsetAdjustmentBehavior This property specifies how the safe
area insets are used to modify the content area of the scroll view.
The default value of this property is automatic.

Related

UISearchController setActive does nothing

I'm trying to present a search controller in response to a button, by setting its isActive property, but it doesn't appear.
lazy var searchController: UISeachController = {
let searchController = UISearchController(searchResultsController: nil)
searchController.delegate = self
return searchController
}()
override func viewDidLoad() {
super.viewDidLoad()
definesPresentationContext = true
}
// Called when a button on the navbar is tapped
#obcj private func searchTapped() {
// The doc says you can force the search controller to appear by setting isActive,
// but nothing happens
searchController.isActive = true
// Calling present does show it, but the search bar appears behind the navbar.
// And the delegate methods are still not called
//present(searchController, animated: true)
}
func willPresentSearchController(_ searchController: UISearchController) {
// Not called, even when calling 'present'
}
It seems isActive only works if the search bar is in the view hierarchy.
// This will place the search bar in the title view, allowing you to
// have other buttons on the right of the search bar.
navigationItem.titleView = searchController.searchBar
Or
// This takes up a whole other row under title row.
navigationItem.searchController = searchController
But if you go this route, you don't need to set isActive yourself - the search controller automatically comes up when the user interacts with the search bar. I still don't understand how isActive is supposed to be used, but it does answer the original question.

Animation segue bug on the navigation bar with large title

My bug:
If navigate from a view controller with large titles enabled to a view controller with large titles disabled i see same bug. Height navigation bar changes not smoothy.
I want animation change height navBar during segue on another viewController like this
Common propertyes for navBar set up in BaseNavigationController
class BaseNavigationController: UINavigationController {
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
override func viewDidLoad() {
super.viewDidLoad()
setNavBarTitlesPropertyes()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
}
private func setNavBarTitlesPropertyes() {
navigationBar.tintColor = .white
navigationBar.titleTextAttributes = [
.foregroundColor: UIColor.white
]
if #available(iOS 11.0, *) {
navigationBar.prefersLargeTitles = true
navigationBar.largeTitleTextAttributes = [
.foregroundColor: UIColor.white
]
}
}
And my setting navbar in the storyboard:
I found solution for this trouble. UINavigationBar
property translucent should be true, and also bottom and top constraint for tableView in UIViewController should be equal Superview.Top and Superview.Bottom accordingly.

Swift - Adding a navigation bar that overrides the existing one

I have multiple VC's embedded in one NavigationController.
I have one VC, lets name it VCNotTransparent, that I want the bar to be not transparent, and on other VC's I want it to be transparent.
So in the main VC, I added these lines for making the bar transparent:
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationController?.navigationBar.shadowImage = UIImage()
navigationController?.navigationBar.isTranslucent = true
So now all of my bars are transparent in the app.
How can I make VCNotTransparent not transparent without it changing all of the other VC's? one solution I thought of is to add a new navigation bar only in VCNotTransparent, but I do not know how to do that.
EDIT
I also tried embedding VCNotTransparent in its own NavigationController, which works almost, but the issue is that I have navigation from it to some other VC's and they become not transparent as well, since they are sub navigation of the VCNotTransparent.
Handle this by enum -
Do below within your MainVC -
public enum NavigationType: Int {
case transparent = 1
case notTransparent = 2
}
var currentNavigationType: NavigationType?
override func viewDidLoad() {
super.viewDidLoad()
self.currentNavigationType = .transparent // default
self.setupNavigationControllerStyle()
}
func setupNavigationControllerStyle (){
switch self.currentNavigationType! {
case .transparent:
//do code here for transparent
case .notTransparent:
//do code here for not transparent
default:
break
}
}
default it will show transparent bar. in which controller you don't want transparent bar just update the currentNavigationType property from there like below -
class VCNotTransparent: MainVC {
override func viewWillAppear(_ animated: Bool) {
self.currentNavigationType = .notTransparent
super.viewWillAppear(animated)
}
}

How can I use NSVisualEffectView to blend window with background

There seem to be a bunch of questions on this for old versions of Swift/Xcode, but for some reason it hasn't been working with the latest update. I created a NSVisualEffectView, blurryView, and added the subview to my main view:
class ViewController: NSViewController {
#IBOutlet weak var blurryView: NSVisualEffectView!
override func viewDidLoad() {
super.viewDidLoad()
//background styling
blurryView.wantsLayer = true
blurryView.blendingMode = NSVisualEffectBlendingMode.behindWindow
blurryView.material = NSVisualEffectMaterial.dark
blurryView.state = NSVisualEffectState.active
self.view.addSubview(blurryView, positioned: NSWindowOrderingMode.above, relativeTo: nil)
// Do any additional setup after loading the view.
}
...
}
But when I run it, there is no effect on the window. (when I set it to within window, and layer it on top of my other view, the blur works correctly, but I only want the window to blur.) I also tried doing the same thing in my App Delegate class, but I can't connect my window as an outlet, and therefore can't add the blurry view to the window. Here's what the code would look like:
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Insert code here to initialize your application
blurryView.wantsLayer = true
blurryView.blendingMode = NSVisualEffectBlendingMode.withinWindow
blurryView.material = NSVisualEffectMaterial.dark
blurryView.state = NSVisualEffectState.active
self.window.contentView?.addSubview(blurryView)
}
...
}
To get an idea if what I'm looking for: NSVisualEffectView Vibrancy
It works quite easy:
In Interface Builder drag a NSVisualEffectView directly as a subview of the main view of your scene.
In the Properties Inspector set Blending Mode to Behind Window
Add the rest of the views you need as subviews of the NSVisualEffectView
That's it, you're done
Here's an example:
Panel 1 View Controller is my blurred view, Background View is the first (non-blurred) view in my "real"view hierarchy.
Swift 5:
Simply add this to your viewWillAppear and it should work:
override func viewWillAppear() {
super.viewWillAppear()
//Adds transparency to the app
view.window?.isOpaque = false
view.window?.alphaValue = 0.98 //you can remove this line but it adds a nice effect to it
let blurView = NSVisualEffectView(frame: view.bounds)
blurView.blendingMode = .behindWindow
blurView.material = .fullScreenUI
blurView.state = .active
view.window?.contentView?.addSubview(blurView)
}

Ad Banner Moving Out of Position, Showing Out of Order

I have an AdBannerView inside my game, but it keeps showing randomly even though I set it to hidden, it pops from the bottom pushing the view up.
Here's the code I have thus far in GameScene:
var iAd = ADBannerView()
override func didMoveToView(view: SKView) {
iAd.delegate = self
iAd.hidden = true
iAd.autoresizingMask = UIViewAutoresizing.FlexibleTopMargin
view.addSubview(iAd)
}
func bannerViewDidLoadAd(banner: ADBannerView!) {
if (!isStarted){ // <- If game has started
iAd.hidden = false
}
}
func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
print("Ad Fail")
iAd.hidden = true
}
func newGame() {
iAd.hidden = true
}
func gameOver() {
iAd.hidden = false
}
Sometimes the ad shows during gameplay, sometimes it shows at the top, other times at the bottom.
My questions are:
How do I position it at the top?
How do I make it so that it stops appearing during gameplay?
How do I make it stop pushing the view up?
How do I make it stop showing if it failed to load (it currently does show)
MORE INFO: I tried this code in ViewController, but ended up with the same results.
For question 1: You have set the frame property to position the banner ad:
iAd.frame = CGRectMake(0, view.frame.size.height - iAd.frame.size.height, view.frame.size.width, iAd.frame.size.height);
Sounds like you've created an ADBannerView in Interface Builder in addition to including self.canDisplayBannerAds somewhere in your project.
The ADBannerView displaying on the bottom of your devices screen is created by self.canDisplayBannerAds = true. self.canDisplayBannerAds = true can be used for a no hassle way of implementing iAd banners in your application. This will create an ADBannerView for you and show or hide the ADBannerView depending on whether it receives an ad or not from the iAd network.
If you have included self.canDisplayBannerAds = true in your project you need to remove it.
As for hiding the ADBannerView when it fails to receive an advertisement, you need to implement the ADBannerView's delegate methods: ADBannerViewDelegate Protocol Reference. Then, in bannerView(_:didFailToReceiveAdWithError:) you'd set your ADBannerView's alpha property to 0.