I am running 2015 Visual Studio with Xamarin. When I launch the iOS Simulator, it is showing a black screen on the simulator. I am using a Storyboard with a Navigation Controller.
I have the Main Interface set to the my storyboard.
Size Class - Any / Any
I have restarted the simulator, ran "Reset Content and Settings"
AppDelegate code (only method with contents.):
public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
// create a new window instance based on the screen size
Window = new UIWindow(UIScreen.MainScreen.Bounds);
// If you have defined a root view controller, set it here:
Window.RootViewController = new Controllers.RegistrationController();
// make the window visible
Window.MakeKeyAndVisible();
return true;
}
You could try something like :
public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
// create a new window instance based on the screen size
Window = new UIWindow(UIScreen.MainScreen.Bounds);
string storyboardName = "Main";
UIStoryboard storyboard = UIStoryboard.FromName(storyboardName, null);
// if it is the first viewcontroller
UIViewController vc = storyboard.InstantiateInitialViewController();
// If you have defined a root view controller, set it here:
Window.RootViewController = vc;
// make the window visible
Window.MakeKeyAndVisible();
return true;
}
if your storyboard is called Main.stroyboard try using this:
public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
return true;
}
I tested both of these options and both should work when your Storyboard is called Main
You need to have a segue from your UINavigationController to an UIViewController with the content in it. If you don't have a segue then your app is going to show a black screen since the app doesn't think it has any content.
If I understand you correctly, your storyboard may look like this: Storyboard 1
And you need to create a segue between the two view controllers so that your storyboard looks like this with the segue-arrow between the two view controllers: Storyboard 2
Related
I am creating an application using xamarin.ios. I have some pages in my storyboard and I have set "Is initial View Controller" for one of the pages as the first page.
Users see that page as the first page if they already logged in otherwise I want to show the login page. To do that I added this code:
[Export ("application:didFinishLaunchingWithOptions:")]
public bool FinishedLaunching (UIApplication application, NSDictionary launchOptions)
{
this.Window = new UIWindow(UIScreen.MainScreen.Bounds);
LoginViewController yourViewController = UIStoryboard.FromName("Main", NSBundle.MainBundle).InstantiateViewController("LoginViewController") as LoginViewController;
this.Window.RootViewController = yourViewController;
this.Window.MakeKeyAndVisible();
return true;
}
The problem is, this code cannot change the first page at all. It seems my application always ignore this code and shows the page with "Is Initial View controller" equals true on storyboard. It means when I change first page on storyboard I see the change but no change when I set it in my code.
The app delegate’s role changes from iOS 12 to iOS 13, the SceneDelegate is responsible for setting up the scenes of your app :
[Export ("scene:willConnectToSession:options:")]
public void WillConnect (UIScene scene, UISceneSession session, UISceneConnectionOptions connectionOptions)
{
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see UIApplicationDelegate `GetConfiguration` instead).
UIWindowScene myScene = scene as UIWindowScene;
Window = new UIWindow(myScene);
UIViewController viewController = new UIViewController();
UINavigationController navigationMain = new UINavigationController(viewController );
Window.RootViewController = navigationMain;
Window.MakeKeyAndVisible();
}
Here are some threads about this question in swift: set-rootviewcontroller-ios-13 and ios-13-swift-set-application-root-view
And articles: accessing-root-view-controller-ios13-scenedelegate and scene-delegate-app-delegate-xcode-11-ios-13
I have a problem with my personal project.
This is my architecture :
Then, my MainViewController can push to TabBarController or another single Controller.
The problem is when I push to the TabBarController, it displays me 2 navigationBar in my 1st controller (from the tabbar)
I can hide the MainController navigation bar to display only the navigation bar from the tabbar but I dont think this is the best practice.
How can I do this ?
Thanks for help.
I think the best solution is that change the Window.RootViewController in AppDelegate , so that you don't need to deal with multiple navigation bars.
Set NavigationController with MainViewController first in AppDelegate
public partial class AppDelegate : UIApplicationDelegate
{
UIWindow window;
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
window = new UIWindow (UIScreen.MainScreen.Bounds);
window.RootViewController = new UINavigationController(new MainViewController());
window.MakeKeyAndVisible();
return true;
}
public void changeRootVC()
{
window.RootViewController = new TabController();
}
}
Change RootViewController instead of pushing to TabbarController in MainViewController
AppDelegate app = UIApplication.SharedApplication.Delegate as AppDelegate;
app.changeRootVC();
While using Typhoon I came across this issue, but first some background.
I'm using a storyboard.
The storyboard starts in a home screen, then flows to login, then to the main screen (UITabBarController). I use navigation controller as root controller.
If the user is already logged in I want to show the main screen without showing the home or login screens. This could be done in the home screen viewDidLoad (other suggestions welcome).
The few things i've tried are:
Using a segue from the home to the tabController but the home screen can be seen and the transition is animated (don't want this).
Instantiating the tab controller (as below) from the storyboard but the dependencies are not injected. I understand that this is because the Typhoon storyboard is not used.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *vc1 = [storyboard instantiateViewControllerWithIdentifier:#"MyAuth"];
I also tried using factory with Typhoon for the storyboard.
public dynamic func storyboard() -> AnyObject {
return TyphoonDefinition.withClass(TyphoonStoryboard.self){
(definition) in
definition.useInitializer("storyboardWithName:factory:bundle:"){
(initializer) in
initializer.injectParameterWith("Main")
initializer.injectParameterWith(self)
initializer.injectParameterWith( NSBundle.mainBundle() )
}
definition.scope = TyphoonScope.Singleton; //Let's make this a singleton
}
}
///Injection for tabbar controller
public dynamic func tabBarViewController() -> AnyObject {
return TyphoonDefinition.withClass(TabBarViewController.self){
(definition) in
}
}
On the viewDidLoad I push the tabBarViewController (using the injected assembly) to the navigation controller but it doesn't have the tabs as specified on the storyboard.
func viewDidLoad() {
super.viewDidLoad()
if(userLoggedIn){
self.navigationController?.pushViewController(self.injectedAssembly.storyboard().tabBarController(), animated: false)
}
}
Thanks,
ad 1. You can disable animations on segues you created in a storyboard by selecting the segue in the storyboard editor, switching to the attributes inspector of the segue and disabling the "Animates" checkbox.
ad 2. If the UIViewController which contains the code you posted was instantiated within a Typhoon injected UIViewController (for instance if you have this code within the home viewcontroller, you use plist integration, and the home viewcontroller is set as the initial viewcontroller in your storyboard), then you can access self.storyboard in the UIViewController. This storyboard will be a TyphoonStoryboard, therefore it will work.
ad 3. Just because you give Typhoon instructions on how to create your MainStoryboards and TabBarViewControllers, it doesn't mean Typhoon knows it should combine one with the other. Try using one of the withFactory: methods provided by TyphoonDefinition to instantiate your UIViewController using the correct storyboard (sorry for Obj-C instead of Swift)
- (MYViewController *)myViewController {
return [TyphoonDefinition
withFactory:[self storyboard]
selector:#selector(instantiateViewControllerWithIdentifier:)
parameters:^(TyphoonMethod *factoryMethod) {
[factoryMethod injectParameterWith:#"MYViewControllerIdentifier"];
}
configuration:^(TyphoonFactoryDefinition *definition) {
definition.classOrProtocolForAutoInjection = [MYViewController class];
}];
}
I have this application which uses internally a UISplitViewControler to display the main interface. The problem I have is that on IOS7 I don't see the button on the left to open the master panel.
The theory says that I have to set the delegate and the button will appear. In practice - my delegate is not called in IOS7. It does on IOS8.
First try:
I am following the normal double navigation controller scheme (described here: http://whoisryannystrom.com/2014/11/17/UISplitViewController-iOS-7/)
Code is swift :)
As I need my app to work on IOS7 phones, in am not creating the split view controller in code, but using the one in the storyboard:
(somewhere in app delegate):
UIStoryboard *board = [UIStoryboard storyboardWithName:#"Storyboard" bundle:nil];
UIViewController *newController = [board instantiateViewControllerWithIdentifier:#"LoginViewController2"];
self.window.rootViewController = newController;
The delegate is created in the master, and assigned to master. This works on IOS8.
Code in the master
override func akaweFromNib() {
super.awakeFromNib()
if let splitViewController = self.splitViewController {
let navigationController = splitViewController.viewControllers[splitViewController.viewControllers.count-1] as UINavigationController
if (splitViewController.respondsToSelector(Selector("displayModeButtonItem"))) {
navigationController.topViewController.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem()
}
splitViewController.delegate = self
}
}
This works, but I have to open the drawer and choose something on the master view (create a new segue) in order to see the button.
Second try
As this did not work - I created a new UISplitViewController and set the split view controller on the storyboard to this new class. Move the onWakeFromNib to this new class (and set the delegate as before). New code works on IOS8, but under IOS7 (at least on the IPad Emulator) the new class is not used for the split view controller - I don't hit a breakpoint in the new code.
What am I doing wrong?
Edit:
While copying code here, I forgot to mention that I am doing:
navigationItem.leftItemsSupplementBackButton = true
navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem()
But - this is only available in IOS8. What can I do in IOS7?
2015-02-12 10:37:55.987 OlympiaTracking[92551:607] -[UISplitViewController displayModeButtonItem]: unrecognized selector sent to instance 0x7b67f1c0
Edit 2:
I also followed ios7 no displayModeButtonItem or targetDisplayModeForActionInSplitViewController which works, but only after the first segue. When the controller is first displayed, the button is not visible.
Open this link and move to the iPad part. Where it says
Notice that when the iPad app is first opened up, there is no indication that this is a split view controller at all! To trigger the Master view controller, the user has to magically know to swipe left to right.
Even when the navigation controller is in place, the UI is not that
much better at first glance (although seeing a title is definitely an
improvement):
I am creating a master detail application using monotouch for iPad. In the master view I added, a custom UIViewController. This UIViewController has a tool bar at the top and 2 UITableView. I can only see the first UITableView. I cant see the tool bar and the other UItableView at the bottom.
I am not sure if I need to turn on anything or configure anything to enable the visibility.
I created outlet for each of the table views and toolbar.
I would appreciate if anyone could shed some lights on this.
Please see the image.
Thanks
Balan Sinniah
UPDATE : I have AppDelegate code as below
[Register ("AppDelegate")]
public partial class AppDelegate : UIApplicationDelegate
{
// class-level declarations
UIWindow window;
UISplitViewController splitViewController;
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
// create a new window instance based on the screen size
window = new UIWindow (UIScreen.MainScreen.Bounds);
var controller = new RootViewController ();
var navigationController = new UITabbedViewController();
var detailViewController = new UIDetailViewTabbedBarController();
splitViewController = new UISplitViewController ();
splitViewController.WeakDelegate = detailViewController;
splitViewController.ViewControllers = new UIViewController[] {
navigationController,
detailViewController
};
window.RootViewController = splitViewController;
navigationController.DetailViewController = detailViewController;
// make the window visible
window.MakeKeyAndVisible ();
return true;
}
}
My Navigation Controller is UITabbedView Controller which has 2 UIViewController. I am adding the toolbar and 2 Table Views in one of the UIViewController.
I got it working by adjusting the autosizing section in interface builder, mark the left, right and upper red lines and unmark the bottom red line, then everything looks fine to me.
I did the same for the UITableView , I umarked the red line in top.
For the toolbar, try once to implement this on your uiviewcontroller
(it can be the other way round to (so false in the first and true in the second)
public override void ViewWillAppear (bool animated) {
base.ViewWillAppear (animated);
this.NavigationController.SetNavigationBarHidden (true, animated);
}
public override void ViewWillDisappear (bool animated) {
base.ViewWillAppear (animated);
this.NavigationController.SetNavigationBarHidden (false, animated);
}
For the table, are the 2 tableview listed underneath each other?
(in the viewbuilder make the first tableview less high, it will adapt to the amount of data automatically when you run the application )