What is similar to ViewWillAppear of objective-c for React-Native? - react-native

I'm using Navigation.startTabBasedApp and for each tab, componentDidMount() only calls one on app start. I want to trigger some method when user taps on particular tab. Even componentWillReceiveProps() is not getting called.

Related

How to add analytics code in React Native lifecycle

I have a TabBarIOS which contains five navigators. I need to track each view on screen for google analytics, but ReactNative doesn't provide a lifecycle for that.
I'v tried to track in the componentDidMount of those views, but it will be only called once in its lifecycle for each view. Switching between tabs will not trigger componentDidMount again.
Furthermore, when I push()/pop() a view into/from a navigator, I need a callback to find which component will be shown.
Is there any callback method or delegate method which would be called when a component is going to show (like -viewDidAppear: in iOS)?
TabBarIOS.Item has a property named onPress() that gets called when the item is pressed. You can use this callback to update analytics.

Modal UINavigationController hides although not dismisses

Okay, so I'm building an universal iOS app with an initial login view (view controller named LoginVC), just a plain simple UIViewController. If the login is successful the app segues to an navigation controller (MainNavigationVC). I created this segue through the storyboard gui of XCode, so no programmatic creation of the nav controller is done. The nav controller is presented modally in fullscreen, so the rest of the app is run atop the login view, with this nav controller as the centerpiece of everything.
The navigation controller contains a view (with a view controller named UserStartPageVC), and in its navigation bar is a logout button. This button sends an target action to UserStartPageVC, with the goal of dismissing the nav controller thus bringing the user back to the login view.
So far everything works fine. I can login and use the app as intended. But! When I log out and then re-login XCode tells me this:
Warning! Attempt to present <MainNavigationVC: 0x753110> on
<LoginVC: 0x756fcf0> while a presentation is in progress!
I suppose this means that the login view is trying to modally display a MainNavigationVC navigation controller, but another one is already displayed, right? But how? Can a view be presented without showing?
And how can I get rid of the old nav controller when logging out? I've tried several ways of dismissing the modal view, for instance:
from within UserStartpageVC running
[x dismissViewControllerAnimated:YES completion:NULL]
[x dismissModalViewControllerAnimated:YES]
where x is either self, self.parentViewController or self.presentingViewController.
setting the LoginVC as a property in UserStartpageVC and running
[self.loginVC dismissViewControllerAnimated:YES completion:NULL]
and so on.
All of the tested calls actually brings me back to the login screen, so it's kind of working.
Any ideas? Relevant code samples can be provided if necessary, I just couldn't figure out which pieces that were of interest. The seguing to the navigation controller has no code (except for a performSegueWithIdentifier:sender:), and the code for dismissing it is the part I cannot seem to get straight.
As a sidenote. So far this isn't a REAL problem; the app runs, and it IS possible to logout and re-login without any other side-effects than an error message in XCode. But I suppose this will be a memory leak if users logout and login multiple times, and I'm not in the mood of an unnecessary rejection from Apple.
I discovered another way to get the exact same error message. Lucky me!
If you created a segue at one point and had it tied to a button (click button -> new view) and then later give that segue a name and invoke it directly using
[self performSegueWithIdentifier:#"identifierName" sender:self];
then you can get this error because you can effectively trigger the segue twice. I thought making the button invoke an IBAction would turn off the segue I had set up in the first place, but apparently not. Hitting the button triggered the segue twice, but after I deleted the segue and re-created it as a manual segue on the view with the same identifier then I was able to invoke it via the above code and not get the warning message.
Hoopla! My bad.
Seemed I had set up the notification observing from the login API call in a stupid way. For every time the user triggered a login (or re-login), it added itself as an observer for the notification; the result was that it performed one more segue for every time a login was done.
And doing multiple segues at the same time, is... well, obviously bad.

What method is called when user taps outside a popover

A quickie...what (if any) method is called when the user dismisses a UIPopover by tapping outside of it? If I want something to happen at this point, where is my hook?
In UIPopoverControllerDelegate we have delegate method called popoverControllerDidDismissPopover: Read : Doc for greater understanding about how to use it.

Best way to delay REST call until after user enters login info to modal view

My app has a login screen before a user goes into the main view. I will do a presentModalViewController: if a user hasn't logged in. In my main view's viewDidLoad: I have a call to a REST API which requires the username and password of the user. Now, if the user has logged in then this is fine.
The problem is that even when the login view is shown, this main view behind the login view is still making a call to the REST API, although it's not supposed to until the modal view is dismissed. So what is the best way to resolve this? Putting the API call into viewWillAppear:? A delegate?
Go the delegate route. Implementing the code in viewWillAppear: will cause it to be executed multiple times, whereas if you use a delegate your code will be called just once.
viewWillAppear and viewDidAppear will however get called after viewDidLoad.
You can use delegates. The login controller can give a call back to its delegate something like -(void) loginController:(LoginViewController *) controller didLogin
And here you can make your call to REST API.

A function called from different class does not work properly

I have a tabbar iPhone application in which tabbar is the root controller and each of the tabs is launching a separate webview window. Each time user taps one of the tabs I intercept the tap in AppDelegate and perform actions, one of which is displaying loading screen (an image in the tabbar view, with display toggled TRUE/FALSE).
My problem is, the loading screen is only displayed when all operations in AppDelegate are finished, which pretty much defeats the purpose of it. My guess is that I did some fundamental error designing this solution, but being a very inexperienced in iPhone programing I don't know how to fix it.
I'm accessing the function showLoading through iboutlets defined in AppDelegate:
[hv showLoading];
And this is what it does:
- (void) showLoading
{
loadingView.hidden = FALSE;
wheelHome.hidden = FALSE;
[wheelHome startAnimating];
NSLog(#"showLoad 1");
}
I'm seeing the "showLoad 1" immediately after bar is tapped, but loading image is only displayed when didSelectViewController exits.
My question - how can I make loading screen appear from AppDelegate OR is there a better way to display loading screen?
The problem is, that the UI is only updated when the event handling code returns to the run loop. You have two options:
Prepare for your long-running task (setup the UI) and then start the task by [myDownloader persormSelector:#selector(download) withObject:nil afterDelay:0];. The benefit of using performSelector:withObject:afterDelay: is that your code returns to the run loop, gets time to update the UI, and then immediately starts the task.
Design your long running tasks (downloading, ...) so that they perform in the background.
First of all, your tabbar should be controller by a UITabBarController and not the app delegate. See the Xcode TabBar template for implementation details.
Secondly, it sounds like you want an Application Startup Image. That is a static image that works like a splash screen if you app takes a little while to startup.