In the first project I have a UIButton. When I touch it, will be open other UIViewController from another project. But I have a problem:
Here's is my code to the first project, I will use it to call other UIViewcontroller from another project
public partial class SomeSoluctionViewController : UIViewController
{
public SomeSoluctionViewController (IntPtr handle) : base (handle)
{
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
PushedClassController pushedclass = PushedClass.AppDelegate.Storyboard.InstantiateViewController ("PushedClass") as PushedClassController;
CallButton.TouchUpInside += (object sender, EventArgs e) => {
this.NavigationController.PushViewController (pushedclass, true);
};
// Perform any additional setup after loading the view, typically from a nib.
}
}
I use PushViewController as Xamarin's site instructed
I instanciate the second class with the identifier.
On PushedClassController’s AppDelegate:
public static UIStoryboard Storyboard = UIStoryboard.FromName ("MainStoryboard", null);
I use it above.
Here's is the pushedView from the second project:
namespace PushedClass
{
** [Register ("PushedClass")]**
public partial class PushedClassController : UIViewController
{
public PushedClassController (IntPtr handle) : base (handle)
{
}
}
}
Registred with "PushedClass"
The log: Objective-C exception thrown. Name: NSInvalidArgumentException Reason: Storyboard () doesn't contain a view controller with identifier 'PushedClass'
Open the pushed project in xamarin.
Select the view controller you want to display by clicking on the black bar at the bottom.
In the designers property pad under identity specify a unique ID for Storyboard ID and Restoration ID to PushedClass.
Related
I'm starting learning MVVM cross, In the android app, I have a splash screen class:
[Activity(MainLauncher = true,
Label = "#string/app_name",
Theme = "#style/Theme.Splash",
NoHistory = true,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation,
ScreenOrientation = ScreenOrientation.Portrait)]
public class SplashScreen : MvxSplashScreenActivity
{
public SplashScreen() : base(Resource.Layout.SplashScreen)
{
}
}
and this is the Setup class:
public class Setup : MvxAndroidSetup
{
protected Setup(Context applicationContext) : base(applicationContext)
{
}
protected override IMvxApplication CreateApp()
{
return null;
}
}
the problem is that the debugger doesn't hit the constructor of the Setup Class, instead I get "An unhandled exception" after the constructor of the splash screen
EDIT
I've already defined the App class in the PCL project:
public class App : MvxApplication
{
public override void Initialize()
{
base.Initialize();
}
also defined the AppStart:
public class AppStart : MvxNavigatingObject, IMvxAppStart
{
public async void Start(object hint = null)
{
//hardcoded login for this demo
//var userService = Mvx.Resolve<IUserDataService>();
//await userService.Login("gillcleeren", "123456");
ShowViewModel<MainViewModel>();
}
}
The main reason behind this project is to understand the sequence of code required and executed by MVVM Cross, so I provide the minimum code till it runs successfully without runtime errors.
Update
I have read your code again more thoroughly and I can see the issue now. You defined the constructor of the Setup class as protected, which makes it invisible for activation.
On MvvmCross for Android the magic happens inside MvxAndroidSetupSingleton class (see the source code here) which searches for the Setup type you defined. The FindSetupType method looks for your defined Setup class first and then inside the CreateSetup method Activator.CreateInstance is used to build the Setup instance. The CreateInstance method variant used however searches only for public constructors, which means it doesn't find your protected one. The result is that it cannot build the Setup class and crashes.
Original answer
The reason this happens is that you have no Core libary that would define the MvvmCross App class and would initialize other required setup. I suggest you to start with a simple tutorial or to look into the official sample projects to see what is necessary to make MvvmCross work in a Xamarin.Android app.
I am trying to build a Xamarin Forms Mobile Application using Prism (Unity) Framework - and add a iOS keyboard extension to the Mobile App.
I added the Keyboard Extension Project and added the reference to the iOS application.
I added a ViewController in the Keyboard Extension Project (which created an XIB file as well) as below:
public partial class ViewController1 : UIViewController
{
public ViewController1() : base("ViewController1", null)
{
}
public override void DidReceiveMemoryWarning()
{
base.DidReceiveMemoryWarning();
// Release any cached data, images, etc that aren't in use.
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
// Perform any additional setup after loading the view, typically from a nib.
}
}
When I rebuild and run, and install the keyboard and click on the keyboard icon to switch, the view of the keyboard is not returned.
Here is the code for the App.xaml.cs in main application
public partial class App : PrismApplication
{
public App(IPlatformInitializer initializer = null) : base(initializer)
{
}
protected override void OnInitialized()
{
InitializeComponent();
NavigationService.NavigateAsync("NavigationPage/MainPage?title=Hello%20from%20Xamarin.Forms");
}
protected override void RegisterTypes()
{
Container.RegisterTypeForNavigation<NavigationPage>();
Container.RegisterTypeForNavigation<MainPage>();
}
}
I don't know what's missing...?
I can't find any answers on how to bind the view of the Keyboard by code because I am building this using a Windows PC .. any help would be appreciated.
You have to create an instance of your keyboard view and assign that object to your view controller View property:
public override void ViewDidLoad()
{
base.ViewDidLoad();
//bind view to controller
var viewNib = UINib.FromName("KeyboardView", null);
View = viewNib.Instantiate(this, null)[0] as UIView;
}
Replace "KeyboardView" with name of your .xib file
I am developing an IOS application with Xamarin using MvvmCross.
I want to use a tab bar to navigate between my Views. I want to have only 1 storyboard per View and want to navigate and call my views from code.
I've overridden the MvxStoryboardViewsContainer Method CreateViewOfTyp() like the following:
protected override IMvxTouchView CreateViewOfType(Type viewType,
MvxViewModelRequest request)
{
var storyboardAttribute = viewType.GetCustomAttribute<FromStoryboardAttribute>();
if (storyboardAttribute == null) {
return base.CreateViewOfType(viewType, request);
}
string storyboardName = storyboardAttribute.StoryboardName ?? viewType.Name;
return
(IMvxTouchView)
UIStoryboard.FromName(storyboardName, NSBundle.MainBundle).InstantiateInitialViewController();
}
Evrytime I try creating my tab bar I call this Method a try to create a View from my model.
The Problem I am encountering here is that UIStoryboard I instantiate is of type UIViewController and not MvxViewController (therefor the app crashes when it tries to cast).
The actual Controller in question however, should be an MvxViewController!
[FromStoryboard("WorklistView")]
public partial class WorklistViewController :
MvxViewController<WorklistViewModel>
{
public WorklistViewController (IntPtr handle) : base (handle)
{
}
}
I'm not sure what i'm missing? Why is the Controller i get a UIViewController and not the MvxViewController it should be?
Thing is I found a lot about what i am trying to do but i can't figure out what i'm doing different.
I found my mistake and it was quite a stupid one.
My designer class had a different namespace then my controller; god knows why...
Well, it's solved now.
I seem to be getting this issue whenever I run my iOS app within Xamarin.
MonoTouch.Foundation.MonoTouchException has been thrown
Objective-C exception thrown. Name: NSInternalInconsistencyException Reason: Could not load NIB in bundle: ’NSBundle ... (loaded)' with name ‘RouteMeViewController'
I am trying to replace a GoogleMapsViewController with a RouteMeViewController using the Objective C library and Binder in an app that I was given to work on. My AppDelegate looks like this:
namespace ExampleApp.iOS
{
[Register ("AppDelegate")]
public partial class AppDelegate : UIApplicationDelegate
{
UIWindow window;
RouteMeViewController viewController;
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
window = new UIWindow (UIScreen.MainScreen.Bounds);
viewController = new RouteMeViewController ();
window.RootViewController = viewController;
window.MakeKeyAndVisible ();
return true;
}
}
RouteMeViewController
namespace ExampleApp.iOS
{
public partial class RouteMeViewController : UIViewController
{
RMMapView MapView { get; set; }
public RouteMeViewController () : base ("RouteMeViewController", null)
{
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
MapView = new RMMapView(View.Frame, new RMOpenStreetMapSource().Handle);
MapView.AutoresizingMask = UIViewAutoresizing.FlexibleDimensions;
if (UIScreen.MainScreen.Scale > 1.0)
MapView.AdjustTilesForRetinaDisplay = true;
Add (MapView);
}
}
}
Any help or direction is much appreciated, thank you!
It seems you're missing a designer file in the resources of your solution. Even if you programmatically create controls and views, you need a designer file where they need to be drawn in, even if it's just an empty designer file. For IOS, you can use XCode for that. You can create files with the .xib extension. They will be compiled on your device, and the resulting file has the extension .nib. Make sure the target of the .xib file is the correct viewController of your project, else you'll still get the error.
I hope this helps. Good luck!
It is 2023 and this problem still appease for xamarion.IOS
and working fine for xamarion.Android
I'm using the last xamarin forms version 5.0.0.2545
this answer solves my problem
I put a lot of codes after InitializeComponent();
to solve the problem just put MainPage = new MainPage(); directly after InitializeComponent(); in your App.xaml.cs
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new MainPage());
}
The problem now it will directly go to the page without reading the other codes
so to solve this move your code to another page,empty page or splash screen page and put your code in it like
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new MySplashScreenPage());
}
I am having some problems with WPFs.
I have a project that has multiple windows, so to control this windows, I have created a controller class. This controller will have a instance of each windows:
this.mainWindow = new MainWindow();
this.loginWindow = new LoginWindow();
this.registerWindow = new RegisterWindow();
The problem comes when I callback from any of the windows to the controller class and from this controller I want to update the information of the window (for example update the value of a property), the information is not being updated
// In controller
public void login(String email, String pass)
{
....
this.loginWindow.showErrorInPassword();
}
// In LoginWindow
public void showErrorInPassword()
{
this.emailErrorImage.Visibility = System.Windows.Visibility.Visible;
}
... but if I send from the LoginWindow a reference of itself to the login function on the controller, the emailErrorImage will be shown
public void login(String email, String pass, LoginWindow lw)
{
....
lw.showErrorInPassword();
}
Seems that the instance that I have in the controller is not the same as the one that is being displayed when I do this.loginWindow.show()
Can someone tell me what am I doing wrong?
You are going to need to bind the UI objects to a MVVM class to update each window.
Use events to call back to the controller.
Here is a brief example. First create a class to contain event args. Doesn't really have to contain anything. It just differentiates between different delegates. Make it its own class in the namespace so everything has access to it.
public class SomeEventArgs: EventArgs
{
}
Inside the window class:
public event EventHandler<SomeEventArgs> CallBackToController;
protected virtual void OnCallBackEvent(object sender, SomeEventArgse)
{
EventHandler<SomeEventArgs> handle = CallBackToController;
if (handle != null)
{
handle(this, e);
}
}
In the controller class, after instantiating the window assign the event to a method.
this.loginWindow = new LoginWindow();
this.loginWindow.CallBackToController += new EventHandler<SomeEventArgs>(MethodToHandleEvent);
Then the Method must have the same form as expected:
private void MethodToHandleEvent(object sender, SomeEventArgs e)
{
// Do something in response.
}
Now anytime you call OnCallBackEvent(this, new SomeEventArgs()) from the window class, the controller class will catch the event and execute MethodToHandleEvent
For instance:
private void LoginWindowBtn_Click(object sender, RoutedEventArgs e)
{
// Logged in ok, let the controller know.
OnCallBackEvent(this, new SomeEventArgs ());
}
There are a ton of tutorials on this, I think this is a better approach to passing references of windows from window to window.