iOS stop status bar from disappearing during animation - ios

I am segueing from a ViewController with a status bar to one without.
During the animation I'm seeing the status bar quickly slide up on the old ViewController as the new ViewController is sliding on top.
Any suggestions why this is happening and how to fix this?
The new ViewController has no status bar due to:
override var prefersStatusBarHidden: Bool {
return true
}
Presentation style is
modalPresentationStyle="overCurrentContext"
NEW:
Created a test XCode project with the issue:
https://github.com/paul301/TestSlideUp

To make the new ViewController stay on top of the old status bar, you need to create a new UIWindow and do the animation manually.
Sample code:
var window = UIWindow()
//to show new view controller
func showWindow() {
let vc = NewViewController()
self.window.rootViewController = vc
self.window.backgroundColor = UIColor.clear
self.window.windowLevel = UIWindowLevelStatusBar
self.window.frame = CGRect(x: 0, y: UIScreen.main.bounds.height, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
self.window.isHidden = false
UIView.animate(withDuration: 0.5) {
self.window.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
}
}

Related

How to show view in statusbar in iOS?

I want to show view in statusbar which should be visible to my all View Controller
Example: I need to show "No Internet Connection" in status bar and it will hide after we get connectivity of internet?
You can add a view directly to the status bar:
// get the status bar
let statusBar = UIApplication.shared.value(forKey: "statusBarWindow") as? UIWindow
// create a subview & add it to the status bar
let subview = UIView(frame: CGRect(x: 20, y: 0, width: 20, height: 10))
subview.backgroundColor = .red
statusBar?.addSubview(subview)
statusBar?.bringSubview(toFront: subview)
If you declare the statusBar and the noNetworkConnectionView globally, you can access it from anywhere to show or hide it dynamically.
Result:
Disclaimer: I am not sure whether Apple will approve apps that modify the status bar in this way.
Create a view
let statusView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 40))
statusView.tag = 1101 //used to get view whenever required
statusView.backgroundColor = UIColor.red.withAlphaComponent(0.6)
//set other properties
Show view on window
//show on window, will be visible in all view controller
UIApplication.shared.delegate?.window??.addSubview(statusView)
UIApplication.shared.delegate?.window??.bringSubview(toFront: statusView)
Hide View
//to hide that view
UIApplication.shared.delegate?.window??.viewWithTag(1101)?.removeFromSuperview()

UIViewController hidden behind UINavigationController but should be placed below

I'm working on a app where I've got a NavigationBar at the top and added a UIViewController as an RootViewController.
Now my plan was to add a new Subview to this UIViewController. The new Subview extended also of UIViewController. I added de view (Gray Rect) of the controller to the UIViewController but it is placed behind the NavigationBar. I don't want that.. So I searched for a solution and found something interesting..:
When I just add a UIView() (Green Rect) to the UIViewController, the placing of the view works perfectly, as I would love see it from the other UIViewController-View.
My code looks like following:
class DashboardController: UIViewController {
var ccview:ContactCircleController!
override func viewDidLoad() {
super.viewDidLoad()
edgesForExtendedLayout = []
self.view.backgroundColor = .white
let test = UIView()
test.backgroundColor = .green
test.frame = CGRect(x: self.view.frame.width - 200, y: 0, width: self.view.frame.width / 2, height: self.view.frame.width / 2)
self.view.addSubview(test)
setup()
}
func setup(){
ccview = ContactCircleController()
ccview.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.width / 2, height: self.view.frame.width / 2)
ccview.edgesForExtendedLayout = UIRectEdge.top
self.view.addSubview(ccview.view)
}}
I've already unchecked the "Extend Edges" - toggle of the navigationcontroller on the storyboard. I also added edgesForExtendedLayout = [] to the UIViewController and for the UIView it worked fine. But for the view of another UIViewController... it didn't worked.
Thank you!
If you use Debug View Hierarchy, you will see that your gray ccview.view is not behind the navigation bar, but rather it is not keeping the height of self.view.frame.width / 2.
This is because the .view of a UIViewController instantiated from Storyboard has by default an .autoresizingMask = [], whereas the .view of a UIViewController instantiated without a storyboard has a default .autoresizingMask = [.flexibleWidth, .flexibleHeight].
You can correct this by changing setup() to:
func setup(){
ccview = ContactCircleController()
ccview.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.width / 2, height: self.view.frame.width / 2)
// remove this line
//ccview.edgesForExtendedLayout = UIRectEdge.top
// add this line
ccview.view.autoresizingMask = []
self.view.addSubview(ccview.view)
}

How to prevent status bar disappearing before UIImagePickerController covers the whole screen?

Here's a GIF showing the issue:
When presenting a UIImagePickerController like this:
self.present(imagePicker, animated: true, completion: nil)
the status bar disappears before the image picker is full screen.
The issue I have with this is that as the status bar disappears in a cloud of smoke, the navigation bar jumps up occupying the void left by the status bar. When UIImagePickerController is dismissed, the status bar shows up in its rightful place.
I'm currently not customizing the status bar in any way, all default.
Is there a way to prevent UIStatusBar from disappearing, at the very least until UIImagePickerController animation is complete?
If you want your status bar to stay at the top of your screen, you should create a custom window and apply animations manually. This may help:
var newWindow = UIWindow()
let newController = viewControllerToPresent()
var animationDuration = 0.4 // or whatever you want.
// setting newController as root of new window.
self.window.rootViewController = newController
self.window.windowLevel = UIWindowLevelStatusBar
self.window.backgroundColor = .clear
self.window.frame = CGRect(x: 0, y: UIScreen.main.bounds.height, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
self.window.isHidden = false
UIView.animate(withDuration: animationDuration) {
self.window.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
}

Swift CATransition Between Two Views - Slide over effect previous screen turns white

I am trying to animate between two full screen views (same view controller) in swift using CATransition. Looking to replicate (or get close to) navigation view controller push transition. Running into issue where view2 (the new view to present) is sliding over correctly, but view1 (the view underneath) disappears. Basically the view that is being animated is sliding over a white screen, but I want it to slider over the previous screen.
var pushAnimationEffect = CATransition()
override func viewDidLoad() {
super.viewDidLoad()
pageToUIView[i] = UIView()
view1.frame = CGRect(x: 0, y: 0, width: screenSize.width, height: screenSize.height)
view1.center = CGPointMake(screenSize.width/2, screenSize.height/2)
view2.frame = CGRect(x: 0, y: 0, width: screenSize.width, height: screenSize.height)
view2.center = CGPointMake(screenSize.width/2, screenSize.height/2)
view1.layer.addAnimation(pushAnimationEffect, forKey: nil)
view2.layer.addAnimation(pushAnimationEffect, forKey: nil)
self.view.addSubview(view1)
pushAnimationEffect.delegate = self
pushAnimationEffect.duration = 0.4
pushAnimationEffect.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
}
func nextPage() {
pushAnimationEffect.type = kCATransitionMoveIn
pushAnimationEffect.subtype = kCATransitionFromRight
self.view.addSubview(view2)
view1.removeFromSuperview()
}
func prevPage() {
pushAnimationEffect.type = kCATransitionMoveIn
pushAnimationEffect.subtype = kCATransitionFromLeft
self.view.addSubview(view1)
view2.removeFromSuperview()
}
Simplified the code a bit so its easier to read.
Is there a better way to do this? Is there something wrong with the code?
You need to do the view remove on after the animation completes. Use the animationDidStop:finished: delegate method.

Adding a small UIView to an SKScene

I have a Swift + SpriteKit game in development, in which I would like to insert a small UITableViewController into a small (100 x 200) UIView, and then add that view to my SKScene. I am using this code:
class BugsScene: SKScene {
override func didMoveToView(view: SKView) {
anchorPoint = CGPoint(x: 0.5, y: 0.5)
NSUserDefaults.standardUserDefaults().setObject("bugs", forKey: "lastSceneViewed")
let bugsTableView: BugsTVC = BugsTVC()
let nav = UINavigationController(rootViewController: bugsTableView)
let smallerRect = CGRectMake(0, 0, 100, 200)
let smallerView = UIView(frame: smallerRect)
smallerView.addSubview(nav.view)
self.view.addSubview(smallerView)
}
}
However, in landscape mode (my app only supports landscape left and landscape right, NO portrait), the tableview occupies the entire height of the landscape mode, and has the width of an iPad in portrait.
How do I add a small UIView to a bigger scene in swift/spritekit?
LearnCocos2D definitely deserves credit for this, so if he ever posts an answer I will accept it. Essentially, I was failing to set the frame for the navigation controller's view. Here is my method for adding the smaller view to the scene:
override func didMoveToView(view: SKView) {
anchorPoint = CGPoint(x: 0.5, y: 0.5)
self.name = "Bugs Scene"
backgroundColor = bugsColor
let smallerRect = CGRectMake(400, 24, 600, 720)
let navRect = CGRectMake(0, 0, 600, 720)
let bugsTableView: BugsTVC = BugsTVC()
nav = UINavigationController(rootViewController: bugsTableView)
nav.view.frame = navRect
smallerView = UIView(frame: smallerRect)
smallerView.backgroundColor = UIColor.clearColor()
bugsTableView.view.frame = smallerRect
smallerView.frame = smallerRect
smallerView.addSubview(nav.view)
self.view.addSubview(smallerView)
}
It could probably be refined some but this is working for me. Now if I can only figure out how to remove the view when I transition to another scene!

Resources