Xamarin iOS Prism (Unity) - Keyboard Extension - c#

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

Related

TabbedPage - Call method when certain Tab is active

I have a scenario where I want to call a method when the user of the app navigates to a certain tab of the TabbedPage.
Example: If I navigate to tab no. 3 of my TabbedPage, a certain method shall be called.
How do I achieve that?
By default all tabs of the TabbedPage are loaded when I start the app.
I am writing in Xamarin - C#.
Best regards!
There are two sample ways to achieve that.
One is using OnAppearing method inside the needed item of tab page.
For example, the tab no. 3 of TabbedPage is ItemsPage, then its ItemsPage.xaml.cs code as follows:
public partial class ItemsPage : ContentPage
{
public ItemsPage()
{
InitializeComponent();
}
protected override void OnAppearing()
{
base.OnAppearing();
// Call your needed method here
}
}
The another way is using OnCurrentPageChanged methond inside the tabbedpage.xaml.cs.
For example, the code as follows:
public partial class MainPage : TabbedPage
{
public MainPage()
{
InitializeComponent();
}
protected override void OnCurrentPageChanged()
{
base.OnCurrentPageChanged();
if(CurrentPage.Title == "tab no. 3 title")
{
// call your needed method
}
//Console.WriteLine(CurrentPage.Title);
}
}

How is Setup class instantiated in MVVMCross in Xamarin?

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.

Show alert on press back button

I writing android app on Xamarin(C#)
I need to Show alert with "Yes" and "No" variantes when I tap back button on Activity.
How can I realize this?
I know how to show alert. How I can make it when i press back button
try this , add to your activity
#Override
public void onBackPressed() {
AlertDialog.Builder builder =
new AlertDialog.Builder(this, R.style.AppCompatAlertDialogStyle);
builder.setTitle(getResources().getString(R.string.app_name));
builder.setMessage("" + Message);
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
//write your code
}
});
builder.setNegativeButton("No", null);
builder.setCancelable(false);
builder.show();
}
Xamarin provides wrappers to the native Android Activity classes. So you probably have a MainActivity and maybe other Activity classes in your Xamarin Android project.
In these classes you can override the OnBackPressed method inherited from FormsApplicationActivity and then create and show your Alert from there.
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
public override void OnBackPressed()
{
// show Alert or pass call on to base.OnBackPressed()
}
}
Since Xamarin Forms 1.3.0 pre3, there is a new method:
protected bool OnBackButtonPressed();
You need to override this on your page.
protected override bool OnBackButtonPressed()
{
// If you want to stop the back button and show alert
return true;
// If you want to continue going back
base.OnBackButtonPressed();
return false;
}
Thanks to Xamarin Forums. Refer this link for more info.

Error to push a ViewController from other project

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.

WinRT 8.1 settings in Caliburn.Micro

I'm trying to open a settings view in a Caliburn.Micro WinRT 8.1 app using VS2013 RC, but I keep getting an unhandled exception when opening it with the following message:
Value cannot be null. Parameter name: Could not parse the VisualElements from the app manifest.
I can reproduce the issues with the following steps:
create a new Windows Store app from VS2013 RC using the Blank app template.
add Caliburn.Micro via NuGet.
in App.xaml, change the base class to caliburn:CaliburnApplication (the namespace is declared as xmlns:caliburn="using:Caliburn.Micro").
in App.xaml.cs, change the class like this (for the CM-based settings I follow http://compiledexperience.com/blog/posts/settings-caliburn)
Code below:
public sealed partial class App
{
private WinRTContainer _container;
public App()
{
InitializeComponent();
}
protected override void Configure()
{
_container = new WinRTContainer();
_container.RegisterWinRTServices();
_container.PerRequest<MainViewModel>();
_container.PerRequest<SettingsViewModel>();
ISettingsService settings = _container.RegisterSettingsService();
settings.RegisterCommand<SettingsViewModel>("Test settings");
}
protected override object GetInstance(Type service, string key)
{
var instance = _container.GetInstance(service, key);
if (instance != null) return instance;
throw new Exception("Could not locate any instances.");
}
protected override IEnumerable<object> GetAllInstances(Type service)
{
return _container.GetAllInstances(service);
}
protected override void BuildUp(object instance)
{
_container.BuildUp(instance);
}
protected override void PrepareViewFirst(Frame rootFrame)
{
_container.RegisterNavigationService(rootFrame);
}
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
DisplayRootView<MainView>();
}
}
Finally, create folders for Views and ViewModels in the solution add add to them the required items: MainViewModel, SettingsViewModel, MainView, SettingsView. The views just include a TextBlock with some text. MainViewModel derives from Screen, while SettingsViewModel derives from PropertyChangedBase. There is no relevant code in any of them.
When launching the app, I can see the main view; then I open the charms bar and click settings, and I find the label leading to my app settings; when I click it, I get the exception quoted above. Any hint?
You can find a full repro solution here: http://sdrv.ms/18GIMvB .
If you aren't ready to move to the alpha version of CM, you can update Callisto to 1.4.0 via NuGet. That fixed the error for me.
It seems that the new CM release (alpha 2) fixed the issue, so I'm adding some more information here to help other newcomers like me. Here is what I'm doing now:
In app's Configure I have some bootstrap code like:
...
ResourceLoader loader = ResourceLoader.GetForViewIndependentUse("Resources");
ISettingsService settings = _container.RegisterSettingsService();
settings.RegisterFlyoutCommand<ContentSettingsViewModel>(loader.GetString("SettingsContent"));
The ContentSettingsViewModel is a viewmodel for filtering some contents. The string got from resources is the label which will appear in the settings flyout (be sure there is an entry for this string, as passing an empty or null string triggers an exception). This VM is derived from CM Screen as I'm overriding OnActivate and OnDeactivate to load and save settings when the user opens or dismisses the settings page.

Categories

Resources