Reputation: 640
Is it possible to call a method when a new UIViewController
is selected in a UITabBarController
? Or is it possible to wait loading the whole UIViewController
until the view is selecte?
I have a UITabBarController
that looks like:
public sealed class VisualizationViewController : UITabBarController
{
private UIViewController tabVand, tabVarme, tabEl;
private UIToolbar toolbar;
public VisualizationViewController()
{
toolbar = new UIToolbar(new RectangleF(0, 0, (float)View.Frame.Width, 60));
toolbar.AutoresizingMask = UIViewAutoresizing.FlexibleWidth;
View.AddSubview(toolbar);
tabVand = new WaterVisualizationViewController();
tabVand.Title = "Vand";
tabVand.TabBarItem = new UITabBarItem("Vand", UIImage.FromFile("Images/Water.png"), 0); // Tag == initial order
tabVand.TabBarItem.SetFinishedImages( UIImage.FromFile("Images/Water.png"), UIImage.FromFile("Images/Water.png"));
tabVand.View.BackgroundColor = UIColor.LightGray;
tabVarme = new TemperatureViewController();
tabVarme.Title = "Varme";
tabVarme.TabBarItem = new UITabBarItem("Varme", UIImage.FromFile("Images/Heat.png"), 1); // Tag == initial order
tabVarme.TabBarItem.SetFinishedImages(UIImage.FromFile("Images/Heat.png"), UIImage.FromFile("Images/Heat.png"));
tabVarme.View.BackgroundColor = UIColor.LightGray;
tabEl = new ElVisualizationViewController();
tabEl.Title = "EL";
tabEl.TabBarItem = new UITabBarItem("EL", UIImage.FromFile("Images/Power.png"), 2); // Tag == initial order
tabEl.TabBarItem.SetFinishedImages(UIImage.FromFile("Images/Power.png"), UIImage.FromFile("Images/Power.png"));
tabEl.View.BackgroundColor = UIColor.LightGray;
var tabs = new[]
{
tabVand, tabVarme, tabEl
};
ViewControllers = tabs;
SelectedViewController = tabVand;
}
And right now, it loads all the Views, which is going to be an expensive call, when I move from dummy data to the real data each view should load. So I want to only make a data call when the view is selected in the UITabBarController
.
Upvotes: 1
Views: 631
Reputation: 938
So what's happening is that your ViewDidLoad() method is firing (assuming you're calling your webservice there) for each tab view controller in your constructor. Each View Did Load is firing because you're calling View.Background, which will load the view into memory. You don't want to do that here, but in the ViewDidLoad() method of each individual tab View Controller:
public sealed class VisualizationViewController : UITabBarController
{
private UIViewController tabVand, tabVarme, tabEl;
private UIToolbar toolbar;
public VisualizationViewController()
{
base.ViewDidLoad();
toolbar = new UIToolbar(new RectangleF(0, 0, (float)View.Frame.Width, 60));
toolbar.AutoresizingMask = UIViewAutoresizing.FlexibleWidth;
View.AddSubview(toolbar);
tabVand = new WaterVisualizationViewController();
tabVand.Title = "Vand";
tabVand.TabBarItem = new UITabBarItem("Vand", UIImage.FromFile("Images/Water.png"), 0); // Tag == initial order
tabVand.TabBarItem.SetFinishedImages( UIImage.FromFile("Images/Water.png"), UIImage.FromFile("Images/Water.png"));
//Don't do this, it will make its ViewDidLoad fire
//and you don't want that.
//tabVand.View.BackgroundColor = UIColor.LightGray;
tabVarme = new TemperatureViewController();
tabVarme.Title = "Varme";
tabVarme.TabBarItem = new UITabBarItem("Varme", UIImage.FromFile("Images/Heat.png"), 1); // Tag == initial order
tabVarme.TabBarItem.SetFinishedImages(UIImage.FromFile("Images/Heat.png"), UIImage.FromFile("Images/Heat.png"));
//tabVarme.View.BackgroundColor = UIColor.LightGray;
tabEl = new ElVisualizationViewController();
tabEl.Title = "EL";
tabEl.TabBarItem = new UITabBarItem("EL", UIImage.FromFile("Images/Power.png"), 2); // Tag == initial order
tabEl.TabBarItem.SetFinishedImages(UIImage.FromFile("Images/Power.png"), UIImage.FromFile("Images/Power.png"));
//tabEl.View.BackgroundColor = UIColor.LightGray;
var tabs = new[]
{
tabVand, tabVarme, tabEl
};
ViewControllers = tabs;
SelectedViewController = tabVand;
}
Then in each individual tab (UIViewController) implementation, call your web service in it's ViewDidLoad()
method, and not in the constructor. Example:
public class WaterVisualizationViewController : UIViewController
{
public WaterVisualizationViewController()
{
//Don't call your web service here
}
public override ViewDidLoad()
{
//Set your background color here
//Call your web service
//Populate your UI with data
}
}
Now if your web service calls are expensive, you might see a little lag when tapping the tabs. For that you should consider using UIActivityIndicatorView to display a "Loading Data" type of indicator so that the user has feedback your app is doing something and not frozen. Alternatively, you can use BTProgressHUD from the Xamarin Component Store, which is really easy to use
Upvotes: 2