Detect and Remove blank tableViewCell in Swift - swift

I have two tableView running in my project.I have successfully passed data between two tableView and saved it as a tableView array into my second tableView using segue.I have another function to connect my second tableview using tabBar button. Everytime, when I press the tabBar button it creates a blank tableViewCell at indexPath:0. I can understand why is happening but I am not sure how to stop. My code below
AppDelegate:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let defaultValues = ["NewArray": [String]()]
UserDefaults.standard.register(defaults: defaultValues)
return true
}
MY Second VC
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let defaults = UserDefaults.standard
newArray = defaults.array(forKey: "NewArray") as! [String]
// newArray.append(newItem)
newArray.insert(newItem, at: 0)
defaults.set(newArray, forKey: "NewArray")
self.favTableView?.reloadData()
}
Thanks in Advance...

Actually the easiest solution is to check if newItem is not empty, because if the view is presented from the segue a (non-empty) string is passed to the newItem property.
override func viewDidLoad() {
super.viewDidLoad()
let defaults = UserDefaults.standard
newArray = defaults.array(forKey: "NewArray") as! [String]
// newArray.append(newItem)
if !newItem.isEmpty {
newArray.insert(newItem, at: 0)
defaults.set(newArray, forKey: "NewArray")
}
self.favTableView?.reloadData()
}

Related

Access ViewController in didFinishLaunchingWithOptions

I want to access the initial view controller through
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
return true
}
I happen to be using a navigation controller - but that doesn't matter really.
I've tried the following:
UIApplication.shared.keyWindow!.rootViewController
UIApplication.shared.delegate?.window
application.windows[0].rootViewController
self.window?.rootViewController
application.keyWindow
and all are nil.
I want to use the storyboard and inject my dependency here. I don't want to instantiate a view controller here, I still want to use the initial view from the storyboard.
How can I access the view in didFinishLaunchingWithOptions - I want this for iOS12?
If I understand your question you want to access the TopMost ViewController presented, if so you can try to use this function in your AppDelegate
func topMostController() -> UIViewController? {
if var topController = UIApplication.shared.keyWindow?.rootViewController {
while let presentedViewController = topController.presentedViewController {
topController = presentedViewController
}
return topController
}
return nil
}
To use this:
if let vc = self.topMostController() {
// Your code to use vc instance of topMostController
}

How can I show loading button (SVProgressHUD) in MainviewController while data is loading in the appDelegate?

I have a welcomeViewController with 1 button, when click the button I load a TableView with some data.
This data is loaded from array, and this array is filled when I initialize my app on appDelegate->application -> didFinishLaunchingWithOptions
The problem is that if i click this button before the data is loaded, the tableView appears empty.
What I need is show loading button (like SVProgressHUD) in the MainviewController while data is loading in the appDelegate.
Is it possible ?
ths.
#appDelegate.swift
var wodsArray : [Wod] = []
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FirebaseApp.configure()
ApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)
getWodsFromDataBase()
return true
}
func getWodsFromDataBase () {
let wodDb = Database.database().reference().child("wods")
let db = Database.database().reference();
let recentPostsQuery = (db.child("wods").queryLimited(toFirst: 2))
var exercises_temp : [Exercise] = []
wodDb.observe(.childAdded) { (snapshot) in let snapValue = snapshot.value as! Dictionary<String, AnyObject>
let Bear_crawl = snapValue["Bear_crawl"]!
let Romanian_deadlift = snapValue["Romanian_deadlift"]!
let wod = Wod(
Bear_crawl: Bear_crawl as! Int,
Romanian_deadlift: Romanian_deadlift as! Int,
)
self.wodsArray.append(wod)
}

iOS firebase: FIRAuthUIDelegate.authUI not being called

I am trying to launch google login from AppDelegate.swift and then launch my app's main screen upon login success.
I am able to
show the google login button as shown above
the user is sent to google to sign in
the user is sent back to original (step 1)
After step 3. I'd like to send the user to my app's main page.
My code is below. The problem I'm having is that authUI is not being called.
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, FIRAuthUIDelegate {
var window: UIWindow?
var authUI: FIRAuthUI?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
FIRApp.configure()
authUI = FIRAuthUI.defaultAuthUI()
authUI?.delegate = self
let providers: [FIRAuthProviderUI] = [FIRGoogleAuthUI()]
authUI?.providers = providers
// show google login button
let authViewController = authUI?.authViewController()
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
self.window?.rootViewController = authViewController
self.window?.makeKeyAndVisible()
return true
}
func application(application: UIApplication, openURL url: NSURL, options: [String: AnyObject]) -> Bool {
return GIDSignIn.sharedInstance().handleURL(url, sourceApplication: options[UIApplicationOpenURLOptionsSourceApplicationKey] as? String, annotation: options[UIApplicationOpenURLOptionsAnnotationKey])
}
func authUI(authUI: FIRAuthUI, didSignInWithUser user: FIRUser?, error: NSError?) {
// launch main view controller
}
}
EDIT: This appears to be a duplicate of another question. The other question's title is quite general and only gets to the details a few lines deep. In any case, I believe Chris's answer is more thorough than the one there. I think both the question and answers here are clearer, more pointed and more thorough so it would be a mistake to just direct people here to go there as would happen if this was marked as a duplicate.
I think your problem lies here, in the - (void)signInWithProviderUI:(id<FIRAuthProviderUI>)providerUI method.
The delegate method is called in the dismissViewControllerAnimated:completion: completion block.
[self.navigationController dismissViewControllerAnimated:YES completion:^{
[self.authUI invokeResultCallbackWithUser:user error:error];
}];
As you can see from the Apple docs, this method is expected to be called on a modally presented viewController. You are displaying it as a root view controller. Try displaying it with a modal from a UIViewController, and things should work out. To debug this try and set a breakpoint at line 193 to see that it won't get hit. I would be very surprised if this doesn't work when you display the authController modally.
To come up with a possible solution to your problem (I am assuming you want to ensure a user is signed in before using your app). The below is a simplification of what I am using in an app currently.
EDIT: Updated for the new 1.0.0 FirebaseUI syntax.
class MainTabController: UITabBarController, FIRAuthUIDelegate {
let authUI: FUIAuth? = FUIAuth.defaultAuthUI()
override func viewDidLoad() {
super.viewDidLoad()
var authProviders = [FUIFacebookAuth(), FUIGoogleAuth()]
authUI.delegate = self
authUI.providers = authProviders
//I use this method for signing out when I'm developing
//try! FIRAuth.auth()?.signOut()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if !isUserSignedIn() {
showLoginView()
}
}
private func isUserSignedIn() -> Bool {
guard FIRAuth.auth()?.currentUser != nil else { return false }
return true
}
private func showLoginView() {
if let authVC = FUIAuth.defaultAuthUI()?.authViewController() {
present(authVC, animated: true, completion: nil)
}
}
func authUI(_ authUI: FUIAuth, didSignInWith user: FIRUser?, error: Error?) {
guard let user = user else {
print(error)
return
}
...
}
It must be a problem of reference.
class AppDelegate: UIResponder, UIApplicationDelegate, FIRAuthUIDelegate {
var window: UIWindow?
let authUI = FIRAuthUI.defaultAuthUI()
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
FIRApp.configure()
authUI.delegate = self
let providers: [FIRAuthProviderUI] = [FIRGoogleAuthUI()]
authUI.providers = providers
// show google login button
let authViewController = authUI.authViewController()
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
self.window?.rootViewController = authViewController
self.window?.makeKeyAndVisible()
return true
}
}
Try this. AppDelegate will hold the reference of authUI and its delegate.

how to use 'presentViewController' with cover View and main page

A lots app, they have the cover view, like facebook, wechat...
but when I try to use presentViewController let the cover present to main page, that still in the cover vie. The following is my code:
var window: UIWindow?
var coverVC:CoverView?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
window = UIWindow(frame: UIScreen.mainScreen().bounds)
window?.backgroundColor = UIColor.lightGrayColor()
coverVC = ViewController()
coverVC?.refresh(window!.frame)
window!.makeKeyAndVisible()
return true
}
Coverview
class CoverView: UIViewController {
func refresh(frame:CGRect){
self.view.frame = frame
self.view.backgroundColor = UIColor.whiteColor()
var mainVC:mainView = mainView()
mainVC.refresh(frame)
self.dismissViewControllerAnimated(false, completion: nil)
self.presentViewController(mainVC, animated: false, completion: nil)
}
}
Main view:
class mainView: UIViewController {
func refresh(frame:CGRect){
self.view.frame = frame
self.view.backgroundColor = UIColor.blueColor()
}
}
Maybe can use other easy way to achieve the goal, that's ok.
otherwise, please don't use "UInavigationcontroller", I know that can present view, but I don't want the bar in cover view, thanks.
I find the correct with cover/login view, it is called SplashScreen.
And in xcode 9, you can find at [TARGETS]>[APP icons and Launch Images] (Image).(The past version, you need add "launch image" in plist file.)
Otherwise, If you doesn't want use this view, just delete "LaunchScreen".

Open in same view controller as closed on (swift)

I am making a simple fact app (In swift) and all the facts are in separate view controllers and when the user closes the app, it all goes to the main page and you have to start from fact 1 again.
I want to know how to save what view controller the user was on when they closed it and when they continue through the facts again,it starts on that fact. Thanks:) also if someone makes a video i think it will get enough views to start a YT channel
Updated to Swift 5
You can use UserDefaults which will remember your last ViewController.
First of all, you have to store some integer when you load any view like shown below:
FirstView.swift
override func viewDidLoad() {
super.viewDidLoad()
UserDefaults.standard.setValue(0, forKey: "View")
// Do any additional setup after loading the view, typically from a nib.
}
SecondViewController.swift
override func viewDidLoad() {
super.viewDidLoad()
UserDefaults.standard.setValue(1, forKey: "View")
// Do any additional setup after loading the view.
}
Now In your AppDelegate.swift read that stored values and load the ViewController related to that Integer this way:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let viewCount = UserDefaults.standard.integer(forKey: "View")
var VC = UIViewController()
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
println(viewCount)
if viewCount == 0 {
//FirstView should initiate
VC = storyboard.instantiateViewController(withIdentifier: "First") as! ViewController
} else if viewCount == 1 {
//SecondView should inititate
VC = storyboard.instantiateViewController(withIdentifier: "Second") as! SecondViewController
} else {
//ThirdView Should Initiate
VC = storyboard.instantiateViewController(withIdentifier: "Third") as! ThirdViewController
}
self.window?.makeKeyAndVisible()
self.window?.rootViewController = VC
return true
}
Check out THIS sample project for more Info.