Split view equally Master Detail iOS13 - swift

Apparently I'll go full Ubuntu by the end of the week and bin my iPhone.
iOS13 has come to my Xcode and I can't find a way to split screen equally Master and Detail view. All tutorials and guides refers to a previous iOS.
The code I tried in my AppDelegate is:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
if let split = window?.rootViewController as? UISplitViewController {
split.delegate = self
split.preferredDisplayMode = .allVisible
split.maximumPrimaryColumnWidth = .greatestFiniteMagnitude
split.preferredPrimaryColumnWidthFraction = 0.5
}
return true
}
but the screen is still splitted 30-70 or whatever the default is.

Figure out in iOS13 is SceneDelegate responsible for UIWindow so the code above should go in the sceneDidBecomeActive function in the SceneDelegate.

Related

How to get the systems Battery Percentage in Swift 5?

I'm trying to include a battery feature to my widget, but I can't seem to get the mobile's battery percentage...
I tried:
import UIKit
struct BatteryControl {
static func getBatteryPercent() -> Int {
UIDevice.current.isBatteryMonitoringEnabled = true
print("BATTERY : \(UIDevice.current.batteryLevel)")
return Int(UIDevice.current.batteryLevel * 100)
}
}
It just keeps showing that the battery is -1.0
EDIT
SOLUTION: Simulator always showing the batter as -1.0, but whem testing it on a real deivce, it showed the correct value.
The battery monitoring must be enabled in the method didFinishLaunchingWithOptions of the AppDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
UIDevice.current.isBatteryMonitoringEnabled = true
return true
}

iOS 13/Facebook SDK error "Unable to find a valid UIWindow"

(To forestall well-intended suggestions, yes I posted this question last week on Facebook's developer forum. No responses yet.)
TL;DR
Facebook SDK 5.8 complains at startup FBSDKLog: Unable to find a valid UIWindow.
The Main Story
In a from-scratch, one-view Xcode 11/iOS 13 project, there is no longer a default UIWindow member associated with the application. (The window per se is still around; you can see it, contained in a UIWindowScene, using the View Hierarchy Debugger in Xcode, or the Reveal app.)
FBSDK 5.8 does seem to be iOS-13-aware, and looks around for it. The relevant code is at line 498 of
https://github.com/facebook/facebook-ios-sdk/blob/master/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m.
Facebook's code iterates over the application's connectedScenes member, which for me is an empty set. How do I modify my code so that FBSDK finds the window?
Some Hacking
I tried adding the following to scene(_:willConnectTo:options:) but it seems to be too late — the FBSDKLog message has already appeared by then. (So I'm flailing...)
guard let s = (scene as? UIWindowScene) else { return }
self.window = UIWindow(windowScene: s)
The following also failed, but it was just a shot in the dark:
guard let s = (scene as? UIWindowScene) else { return }
self.window = UIWindow(frame: s.coordinateSpace.bounds)
self.window?.windowScene = s
self.window?.rootViewController = ViewController(nibName: nil, bundle: nil)
self.window?.makeKeyAndVisible()
If you don't use the new behaviour and don't mind reverting to the old way, you can try the following
Delete Application Scene Manifest key from Info.plist
Delete SceneDelegate.swift
Add var window: UIWindow?to AppDelegate.swift
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow? // <-- Here
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
// window!.makeKeyAndVisible()
return true
}
}
Add window variable to AppDelegate class
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
Assign UIWindow inside didFinishLaunchingWithOptions
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
if let window = window {
window.makeKeyAndVisible()
self.window = window
}
ApplicationDelegate.shared.application(
application,
didFinishLaunchingWithOptions: launchOptions
)
return true
}

Using Document Browser View Controller with Mac Catalyst

I have just started experimenting with Catalyst. My app is a document browser based app.
The stock MacOS Finder dialog is indeed launched when the appropriate button is clicked. The main app window completely disappears when the Finder dialog appears, unless I choose in the IB for the document browser view controller to appear in "Automatic" mode.
Cancelling the operation indeed brings back the main window.
However, selecting a file will yield a blank screen and no results. A little debugging revealed that none of the file selection functions is being called, and I have implemented all of them:
func documentBrowser(_ controller: UIDocumentBrowserViewController, didPickDocumentURLs documentURLs: [URL]) {...}
func documentBrowser(_ controller: UIDocumentBrowserViewController, didImportDocumentAt sourceURL: URL, toDestinationURL destinationURL: URL) {...}
func documentBrowser(_ controller: UIDocumentBrowserViewController, failedToImportDocumentAt documentURL: URL, error: Error?) {...}
Is there another function or handle used in Catalyst? I found nothing in the documentation.
EDIT:
I should clarify that I manipulated the app to present the DocumentViewController before the DocumentBrowserViewController, although Apple requires that the DocumentBrowserViewController is the initial view controller. I did it by changing the app delegate:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
...
// Set the documentViewController to appear first
self.window = UIWindow(frame: UIScreen.main.bounds)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyboard.instantiateViewController(withIdentifier: "main")
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
return true
}
Taking this out still doesn't change anything. And a default project created from the document browser template does seem to work. What could prevent these methods from being called?
I would suggest to implement func documentBrowser(_ controller: UIDocumentBrowserViewController, didPickDocumentsAt documentURLs: [URL]) as well

How to set property in app delegate for tabview controller

I've read several of the suggested posts that were to help with this problem but could not find something for this particular issue.
I need to set a property on my controller, the book is saying to do so in the app delegate. In the previous assignment using a navbar, this worked:
func application(_ application: UIApplication, didFinishLaunchingWithOptions
launchOptions: [UIApplicationLaunchOptionsKey : Any]?) -> Bool {
// Override point for customization after application launch.
// Create an ItemStore to hold list of items
let itemStore = ItemStore()
// Access the ItemsViewController and set its item store
let itemsController = window!.rootViewController as! ItemsViewController
itemsController.itemStore = itemStore
return true
}
However, creating a similar program I need to use tab bar but can't get it to work and keep running into the error stated above, on the let editcontroller = tabcontroller. - line
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
// Create an pindatabase
let pinDataBase = PinDatabase()
// Access the pairsViewController and set its database
let tabController = window!.rootViewController as! UITabBarController
// this edit controller line is where I am stuck
let editController = tabController.tabBar as! EditViewController
editController.pinDataBase = pinDataBase
return true
}
The error is:
fatal error: unexpectedly found nil while unwrapping an Optional value
The controller I'm trying to set the property on is not the root controller but the third tab if that helps.
Your issue is your attempt to cast the UITabBar to your EditViewController. You need to access the array of view controllers from the tab bar controller and access the one that is actually the EditViewController.
let editController = tabController.viewControllers[2] as! EditViewController
This will access the 3rd view controller and cast it as needed.

swift 3 error xcode 8.1 while assigning rootviewcontroller says it is a get-only property

I was migrating my project from swift 2.2 to 3.0, when I reached a point where I get this strange error, which does not allow me to set rootviewcontroller in the app delegate didfinishlaunching.
self.window?.rootViewController = self.container.resolve(DPSlideMenuController.self)!
I guess you're using this library SlideMenuControllerSwift . It would be great if you show the whole code inside the DidFinishLaunching function.
Anyway, try to do the following :
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// create viewController code...
let slideMenuController = SlideMenuController(mainViewController: mainViewController, leftMenuViewController: leftViewController, rightMenuViewController: rightViewController)
self.window?.rootViewController = slideMenuController
self.window?.makeKeyAndVisible()
return true
}
Finally fixed it. The issue was there was a var named rootViewController in one of the protocol extension.
var rootViewController: UIViewController {
return (UIApplication.shared.keyWindow?.rootViewController)!
}
Was working fine with Swift 2.2, but on swift 3 was confusing the compiler. Changed the name and the code got compiled.