ios 9 swift not showing initial controller - ios

I have my app with a custom splash screen to load some data from internet. In iOS 8 I can see this ViewController, but in iOS9 I only see it in the first launch of the app the rest of the launches iphone pauses on springboard and then shows the list of data that should be visible after the custom splash screen.
I don't know if there's some bug with ios9 related to this topic :(
Here's is my code, hope anyone can help me.
class SplashScreenVC: UIViewController {
#IBOutlet weak var spinner: UIActivityIndicatorView!
#IBOutlet weak var splashImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "rotated", name: UIDeviceOrientationDidChangeNotification, object: nil)
}
func rotated() {
if(UIDeviceOrientationIsLandscape(UIDevice.currentDevice().orientation)) {
splashImageView.image = UIImage(named:"eva_splash_landscape_")
}
if(UIDeviceOrientationIsPortrait(UIDevice.currentDevice().orientation)) {
splashImageView.image = UIImage(named:"eva_splash_portrait_")
}
}
func startActivityIndicator() {
self.spinner.activityIndicatorViewStyle = .WhiteLarge
self.spinner.center = self.view.center
self.spinner.hidesWhenStopped = true
self.spinner.frame.size.height = 50
self.spinner.frame.size.width = 50
self.parentViewController?.view.addSubview(spinner)
self.spinner.startAnimating()
}
}

Sounds like your Storyboard files could be disconnect from your build target. Make sure Main Interface is your Main.Storyboard file and Launch Screen File is your Custom storyboard file

Related

Lottie animation stopped when i tap on different tab bar item

Im using Lottie animation in my app and im trying to keep the animation running in the background when i exit the app and open it again (not force close) ..
I was able to do so successfully, but the problem is the animation stops when i select different tab bar item and go back to the tab bar item that has the animation view.
this is my code.
import UIKit
import Lottie
import UserNotifications
import NotificationCenter
class HomeViewController: UIViewController {
#IBOutlet weak var animationView: UIView!
var animation : AnimationView?
override func viewDidLoad() {
super.viewDidLoad()
setupAnimation()
NotificationCenter.default.addObserver(self, selector: #selector(applicationEnterInForground), name: UIApplication.willEnterForegroundNotification, object: nil)
}
func setupAnimation() {
animation = AnimationView(name: "cong")
animation?.frame = self.animationView.bounds
self.animationView.addSubview(animation!)
animation?.loopMode = .loop
animation?.contentMode = .scaleAspectFit
animation?.play()
}
#objc func applicationEnterInForground() {
if animation != nil {
if !(self.animation?.isAnimationPlaying)! {self.animation?.play()}}
}
}
Swift 5
There is a property, that can be set & it will restore your Lottie animation:
yourAnimationView.backgroundBehavior = .pauseAndRestore
By default, this property is set to .pause
Better, use viewWillAppear/viewDidAppear to start the animation again and remove observing the willEnterForegroundNotification.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if self.animation?.isAnimationPlaying == false {
self.animation?.play()
}
}

How can I update battery level charge with a Text variable to show battery level as it updates? [duplicate]

This question already has answers here:
Check Battery Level iOS Swift [closed]
(2 answers)
Closed 3 years ago.
I have been trying several methods but none have worked.
I've been trying to use some of the codes to get battery level
in Xcode5 but none have worked.
I required the reading to change every time the level of the battery updates.
class ViewController: UIViewController {
#IBOutlet weak var level_Battery: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
UIDevice.current.isBatteryMonitoringEnabled = true
let level = UIDevice.current.batteryLevel
let battery_Level = Int(level * 100)
level_Battery.text = "\(battery_Level)%"
}
}
I expect that the text variable always shows an updated battery level reading. so whatever the phone battery level charge is I would like to show that inside of the app.
Create your battery level as a computed property to get battery level.
class ViewController: UIViewController {
#IBOutlet weak var level_Battery: UILabel!
var batteryLevel: Float {
return UIDevice.current.batteryLevel
}
override func viewDidLoad() {
super.viewDidLoad()
UIDevice.current.isBatteryMonitoringEnabled = true
level_Battery.text = "\(batteryLevel * 100)%)"
}
}
If you want to continuosly monitoring battery level, you need to add observer of battery state changing provided by iOS
NotificationCenter.default.addObserver(self, selector: #selector(batteryLevelDidChange), name: UIDevice.batteryLevelDidChangeNotification, object: nil)
#objc func batteryLevelDidChange(_ notification: Notification) {
print(batteryLevel)
}
Code:
class ViewController: UIViewController {
#IBOutlet weak var level_Battery: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
level_Battery.text = "\(UIDevice.current.batteryLevel)"
NotificationCenter.default.addObserver(self, selector: #selector(batteryLevelDidChange(notification:)), name: UIDevice.batteryLevelDidChangeNotification, object: nil)
}
#objc func batteryLevelDidChange(notification: NSNotification){
level_Battery.text = "\(UIDevice.current.batteryLevel)"
}
}
Note:
Maybe it will give unpredictable value with simulator, So I suggest test it on real device

YouTubePlayer pod crashes when loading video ID

I am trying to do something very basic, I have an outlet that is assigned with the YouTubePlayerView class and once loading an ID, it crashes.
Why is it crashing?
I checked that the outlet is connected properly and the debugger shows that videoId is defined correctly.
code:
import UIKit
import YouTubePlayer
class InfoViewController: UIViewController {
var videoId = "Bgh9u7x8i4Y"
#IBOutlet var youtubePlayer: YouTubePlayerView!
override func viewDidLoad() {
super.viewDidLoad()
self.youtubePlayer.loadVideoID(videoId)
}
#IBAction func exit(_ sender: UIButton) {
performSegue(withIdentifier: "unwindToMainFromInfo", sender: self)
}
}
Well, I am still not sure what causes the crash, I believe it is something related to the framework, and choosing the type of a UIView (and setting it as a YouTubePlayerView through the identity inspector) added in Storyboard caused a crash when trying to load the videoId.
The work around was to add the player programatically. I used a plain view in storyboard to make it easy to give my player a frame when initializing it. But otherwise programatically works smoothly.
code:
#IBOutlet weak var viewForPlayer: UIView!
override func viewDidLoad() {
super.viewDidLoad()
let frameForPlayer = viewForPlayer.frame
let player = YouTubePlayerView(frame: frameForPlayer)
player.loadVideoID(InstructionsVideoId)
player.play()
self.view.addSubview(player)
}

Swift 3 - UIView does not always display its content

I have a UIViewController (Main Menu) that is displayed after my other UIViewController (Loading Screen) finishes downloading/syncing data from the web. My Main Menu is having problems as it doesn't always display all the UIButtons that are on the view when it shows up! There is an inconsistancy, 1 out of every 10 times the Main Menu loads, all the UIButtons will appear.
Here's how the view should look:
Here's how the view usually shows up:
I can put my finger where the UIButtons should be and move my finger away and they'll appear. I can also tap where they should be and my segues will still trigger, but the UIButtons dont just automatically show up. It looks like
I attempted to add a MainMenuView.setNeedsDisplay() to the ViewDidLoad function and it didn't help. I also created a test UIButton on the view that triggers a MainMenuView.setNeedsDisplay() command but the hidden UIButtons remain hidden.
If I leave the screen idle for 30 or so seconds, all the UIButtons will randomly appear without me having to manually make them appear.
The Main Menu view is normal and all UIButtons are visible if I segue to it from any part of the app aside from my Loading Screen.
Edit: Main Menu Code - (references are Strong)
import UIKit
import CoreData
class MainMenuViewController: UIViewController {
// MARK: References
#IBOutlet var btnGasManifolds: UIButton!
#IBOutlet var btnAirCompressors: UIButton!
#IBOutlet var btnVacuumPumps: UIButton!
#IBOutlet var btnUnitConversion: UIButton!
#IBOutlet var btnCFMCalculator: UIButton!
#IBOutlet var mainMenuView: UIView!
var userData = [NSManagedObject]()
// MARK: Functions
override func viewDidLoad() {
var name = String()
for duserData in userData {
name = duserData.value(forKey: "nameFull") as! String
}
print("Main Menu\n->\(name)")
backgroundSetup()
}
override func viewDidAppear(_ animated: Bool) {
mainMenuView.setNeedsDisplay()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func btnTest(_ sender: Any) {
mainMenuView.setNeedsDisplay()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any!) {
if segue.identifier == "settingsSegue" {
let destination = segue.destination as! SettingsViewController
destination.userData = userData
}
}
// Background Setup
func backgroundSetup() {
let background = UIImage(named: "Data Screens")
var imageView : UIImageView!
imageView = UIImageView(frame: view.bounds)
imageView.contentMode = UIViewContentMode.scaleAspectFill
imageView.clipsToBounds = true
imageView.image = background
imageView.center = view.center
view.addSubview(imageView)
self.view.sendSubview(toBack: imageView)
}
}
The code which creates and shows the buttons after fetching the data from server needs to run on Main UI thread. If the code is running the background thread it will not properly display the UI elements and will take some time or manual scroll before showing the controls.
Run the code on Dispatch main queue.
dispatch_async(dispatch_get_main_queue(),{
//do some work
})
OR
Override one of the methods from ViewWillLayoutSubviews and ViewDidLayoutSubviews accordingly and run your code in these methods.

iOS 8.4 - iboutlet not populating in programmatically created view controllers

When loading a UIViewController programmatically in iOS 8.4 I am consistently seeing the IBOutlets registering as nil. This is causing crashes on any iOS 8.4 device. The exact same code runs smoothly on iOS 9 and 9.0.1. For reference, this is a snippet of the view controller
class B8AVPermissionsViewController: B8BaseViewController {
#IBOutlet weak var closeButton: UIButton!
#IBOutlet weak var cameraButton: UIButton!
#IBOutlet weak var microphoneButton: UIButton!
var delegate: B8PermissionRequestingDelegate? = nil;
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated);
NSLog("cameraButton: \(cameraButton)")
}
That prints out cameraButton: nil
The code that creates this looks like:
self.permissionViewController = B8AVPermissionsViewController()
self.permissionViewController!.delegate = self
dispatch_async(dispatch_get_main_queue(), {
self.presentViewController(self.permissionViewController!, animated: true, completion: nil)
})
What am I doing wrong?
The problem is that there's bug in iOS 8. Saying B8AVPermissionsViewController() in iOS 8 does not automatically load the associated nib. You need to work around this; for example, you could call init(nibName:bundle:) explicitly and tell it where the nib is.
The bug is fixed in iOS 9, which is why you're not seeing the same problem there.

Resources