I have installed Aritchie userdialogs version 5 and I'm using Xamarin.Forms Version 2.2.
When I use UserDialogs.Instance.ShowSuccess or UserDialogs.Instance.ShowError, on Android a dark backgroud is displayed, on iOS is NOT displayed which makes this alert message pretty unreadable when the page behind is mostly white.
On iOS I just get the message and the icon in the center of the screen but no dark background.
Example code on iOS:
UserDialogs.Instance.ShowSuccess("Data saved correctly");
How can I solve it ?
Without and With ForceiOS6LookAndFeel:
In your iOS native app:
Add the Nuget BTProgressHUD
In your: AppDelegate (AppDelegate.cs):
add the using clause: using BigTed;
add the code BTProgressHUD.ForceiOS6LookAndFeel = true; in FinishedLaunching method
All done :-)
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
BTProgressHUD.ForceiOS6LookAndFeel = true;
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App());
return base.FinishedLaunching(app, options);
}
Any calls within your Xamarin.Forms based code to ShowSuccess (or any other BTProgressHud dependent code) will default to 'older' style.
Is it possible to use a Toast instead? As you can set the background like so:
ToastConfig.SuccessBackgroundColor = System.Drawing.Color.BurlyWood;
create it like so:
Toast(ToastEvent.Success)
Either that or you are going to have to change the BTProgressHud settings that Acr.UserDialogs uses. I managed it by setting these values in Acr.UserDialogs.iOS UserDialogsImpl.cs:
public override void ShowSuccess(string message, int timeoutMillis)
{
UIApplication.SharedApplication.InvokeOnMainThread(() =>
{
BTProgressHUD.ForceiOS6LookAndFeel = true; // This is the line you need
BTProgressHUD.ShowSuccessWithStatus(message, timeoutMillis);
});
}
And it looks like this:
Related
I have xamarin forms app and need to prevent user from take screen shot or record screen
these implemented for android using these:
Window.SetFlags(WindowManagerFlags.Secure, WindowManagerFlags.Secure);
is there any we to do these for ios
Thanks
Like Jason said, you could find more information in Google. You could try the code below for ios to blur or hide the screenshot taken, to hide sensitive information. I hope this would be helpful for you.
A easy way is to set a blur when the AppDelegate calls OnResignActivation.
UIVisualEffectView _blurWindow = null;
public override void OnActivated(UIApplication application)
{
base.OnActivated(application);
_blurWindow?.RemoveFromSuperview();
_blurWindow?.Dispose();
_blurWindow = null;
}
public override void OnResignActivation(UIApplication application)
{
base.OnResignActivation(application);
using (var blurEffect = UIBlurEffect.FromStyle(UIBlurEffectStyle.Dark))
{
_blurWindow = new UIVisualEffectView(blurEffect)
{
Frame = UIApplication.SharedApplication.KeyWindow.RootViewController.View.Bounds
};
UIApplication.SharedApplication.KeyWindow.RootViewController.View.AddSubview(_blurWindow);
}
}
I use Dark here. You could change the blur effect to Light, Regular or any of the other options listed.
Someone here (thanks sushihangover!) helped me get my application to read the iOS Settings Dark or Light theme on command. I'm using Xamarin (not Forms). I also need the following (just for iOS):
iOS Settings Theme is Light
App is set to Automatic, so it uses current the iOS Settings Theme (Light)
App launched is Light
Home button press
Change iOS Settings to Dark
Bring app to foreground
App still look Light, but it should look Dark.
I realize the AppDelegate has a WillEnterForeground method, but I don't know how to wire that up so the App looks Dark when it comes to the foreground. I'm using MvvmCross. The following link looks promising.
https://forums.xamarin.com/discussion/181648/best-approach-to-handle-dark-theme
I don't understand how to apply the link's contents to my MvvmCross architecture.
Your help is appreciated!
Thanks!
Larry
The best way to react on application changes while using the MVVM pattern would be to implement a IThemeService interface as shown in your link.
xamarin forms iOS
But I think it's not possible to react to configuration changes in Xamarin.Forms.iOS plattform while using MvvmCross. I looked into the source code of the MvvmCross.Forms.iOS project and couldn't find any equivalent to the MvvmCross.Forms.Android setup methods like OnConfigurationChanged.
On Android you can easily refresh the app-theme while change the system theme in the MainActivity.
public class MainActivity : MvxFormsAppCompatActivity
{
public override void OnConfigurationChanged(Configuration newConfig)
{
base.OnConfigurationChanged(newConfig);
this.UpdateTheme(newConfig);
}
protected override void OnResume()
{
base.OnResume();
UpdateTheme(Resources.Configuration);
}
protected override void OnStart()
{
base.OnStart();
this.UpdateTheme(Resources.Configuration);
}
private void UpdateTheme(Configuration newConfig)
{
if (Build.VERSION.SdkInt >= BuildVersionCodes.Froyo)
{
var uiModeFlags = newConfig.UiMode & UiMode.NightMask;
switch (uiModeFlags)
{
case UiMode.NightYes:
Mvx.IoCProvider.Resolve<IThemeService>().UpdateTheme(BaseTheme.Dark);
break;
case UiMode.NightNo:
Mvx.IoCProvider.Resolve<IThemeService>().UpdateTheme(BaseTheme.Light);
break;
default:
throw new NotSupportedException($"UiMode {uiModeFlags} not supported");
}
}
}
}
But in the AppDelegate on the iOS plattform, you don't have any of these functionalitys to override.
public class AppDelegate : MvxFormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
return base.FinishedLaunching(application, launchOptions);
}
}
I copied this code from this project.
native xamarin iOS
When you are using native iOS you could override the TraitCollectionDidChange method. It's the equivalent to the android OnConfigurationChanged function.
Maybee look here for more details. I adapted the android version to iOS for you. At First, you have to create a custom view controller.
// your supported theme versions
public enum BaseTheme
{
Inherit = 0,
Light = 1,
Dark = 2
}
public class MyViewController : UIViewController
{
public override void TraitCollectionDidChange(UITraitCollection previousTraitCollection)
{
base.TraitCollectionDidChange(previousTraitCollection);
if (TraitCollection.UserInterfaceStyle != previousTraitCollection.UserInterfaceStyle)
{
UpdateTheme(TraitCollection.UserInterfaceStyle);
}
}
private void UpdateTheme(UIUserInterfaceStyle newConfig)
{
switch(newConfig)
{
case UIUserInterfaceStyle.Dark:
Mvx.IoCProvider.Resolve<IThemeService>().UpdateTheme(BaseTheme.Dark);
break;
case UIUserInterfaceStyle.Light:
Mvx.IoCProvider.Resolve<IThemeService>().UpdateTheme(BaseTheme.Light);
break;
default:
throw new NotSupportedException($"UiMode {uiModeFlags} not supported");
}
}
}
I uploaded a project where I simplify coded an implementation for native IOS and android here. Complete and improve some things and it will work. Also look at the StarWars and TipCalc Project in the mvvmcross sample repo.
mvvmcross ioc
your interface structure could look like so;
IThemeService (base project) - ThemeService (base project) - ThemeService(iOS project)
And you have to register the interface of course.
Mvx.IoCProvider.RegisterSingleton<IThemeService>(() => new ThemeService());
I would like my app to be notified of a change in one of the settings in the settings bundle. Or if that's not possible, of any change (and I will then check if it was that specific setting).
How would I achieve that in Xamarin iOS?
It seems like one of those options is addressed in these answers one and two. But I can't figure out how to do that in Xamarin/C#.
Just translate the Objective-C code to C# and if you read the document here, you will find there are some examples:
// Lambda style
NSNotificationCenter.DefaultCenter.AddObserver(
NSValueTransformer.UserDefaultsDidChangeNotification, (notification) => { Console.WriteLine("Received the notification NSValueTransformer", notification); }
);
//Method style
void Callback(NSNotification notification)
{
Console.WriteLine("Received a notification NSValueTransformer", notification);
}
void Setup()
{
NSNotificationCenter.DefaultCenter.AddObserver(NSValueTransformer.UserDefaultsDidChangeNotification, Callback);
}
Refer: userdefaultsdidchangenotification
I'm just trying to make my first app with MvvmCross but I already encounter a problem for my app and can't find anything on the web for that. I want to open a specific page as a modal dialog on supported devices (eg. iPads). For my non MvvmCross applications I do this with Rg.Plugin.Popup but I do not want it this way this time. I found a few solutions on how it can be done with native and MvvmCross but nothing about how it is done with Xamarin.Forms in combination to MvvmCross. Did I need to implement a own presenter and filter on the type of my page (because this page should always be modal on supported devices)? And if I do so, is there any example for this?
Using MvvmCross 5.2.0, the following worked for me (on iOS at least; haven't tested on Android):
var bundle = new MvxBundle(new Dictionary<string, string>{ { MvxFormsPagePresenter.ModalPresentationParameter, "true" } });
await _navService.Navigate<MyViewModel>(bundle);
This uses the stock-standard MvxFormsPagePresenter, so you don't have to create your own presenter.
I'm using MVVMCross 7.1.2 here, this was tested on Android only.
In your Views code behind implement IMvxOverridePresentationAttribute with code similar to this.
public MvxBasePresentationAttribute PresentationAttribute(MvxViewModelRequest request)
{
if (request.PresentationValues == null) return null;
if (request.PresentationValues.ContainsKey("NavigationMode") &&
request.PresentationValues["NavigationMode"] == "Modal")
{
return new MvxModalPresentationAttribute
{
WrapInNavigationPage = true,
Animated = false,
NoHistory = true
};
}
return null;
}
All you need to do now, is when Navigating to the view model is just pass a key value pair as the parameter like this
await NavigationService.Navigate<MainViewModel>(new MvxBundle(new Dictionary<string, string> { { "NavigationMode", "Modal" } }));
That's it... easy as that !
I recently received a support ticket that some of our web app's functionality is crashing safari on the iPad. This functionality had no problems prior to the latest iOS 7.0.6 update. We have a few GWT ValueListBoxes that change the DOM when their values are changed. Prior to making the changes, we present the user with a Window.confirm() message to inform them of the effects the changes will have and ask whether or not they would still like to proceed. Since the update, the confirm choices do nothing and Safari crashes. This is only happening on the iPad. The functionality works fine on the desktop browsers (IE, Chrome, Firefox, Safari and the Chrome mobile emulator), but crashes safari on the iPad. Is anyone else having this issue?
Here's a screenshot of the crash:
And here's a sample of the code:
this._view.isPrimaryFoodGen().addValueChangeHandler(new ValueChangeHandler<Boolean>()
{
#Override
public void onValueChange(final ValueChangeEvent<Boolean> event)
{
#SuppressWarnings("unchecked")
ValueListBoxWithOldValue<Boolean> vlb = (ValueListBoxWithOldValue<Boolean>)event.getSource();
if (confirmQuestionChange() ){
changeGroupAndQuestions(CONSTANTS.PRIMARY_FOOD, event.getValue());
}
else {
vlb.setValue(vlb.getOldValue());
}
}
});
public boolean confirmQuestionChange()
{
if (!this._view.isImageCriteriaQuestionsVisible())
{ //questions aren't currently visible
return true;
}
boolean confirmed = Window.confirm("Changing this response will delete image data already collected. Do you wish to proceed?");
return confirmed;
}
Any help on a solution for preventing the crash on the iPad would be greatly appreciated. I have tried focusing on another element prior to calling Window.confirm() in hopes that the overlay and the ValueListBox choices would be removed to stop any JS conflicts, but it hasn't worked.
Am I at the mercy of Apple until the next update fixes this?
Or is there a viable solution?
OK, so it turns out that since I couldn't find a fix to continue using Window.confirm(), I had to implement a solution by changing the onValueChange() and confirmQuestionChange() methods to use a manually created DialogBox instead of Window.confirm(). It isn't the optimal solution, but Safari does not crash on the iPad anymore and users can get their work done. Here are the code changes:
this._view.isPrimaryFoodGen().addValueChangeHandler(new ValueChangeHandler<Boolean>()
{
#Override
public void onValueChange(final ValueChangeEvent<Boolean> event)
{
confirmQuestionChange(CONSTANTS.PRIMARY_FOOD, event);
}
});
public void confirmQuestionChange(final String question, ValueChangeEvent<Boolean> event)
{
final ValueListBoxWithOldValue<Boolean> vlb = (ValueListBoxWithOldValue<Boolean>)event.getSource();
if (!this._view.isImageCriteriaQuestionsVisible()) //questions aren't currently visible, can change them no problem
{
changeGroupAndQuestions(question, vlb.getValue());
}
else{
//the following fix was put in place for issues with Safari on the iPad OPS-76
final DialogBox dialogBox = new DialogBox();
dialogBox.setHTML("<center>Changing this response will delete<br />image data already collected.<br />Do you wish to proceed?</center>");
dialogBox.setAnimationEnabled(true);
Button yesButton = new Button("YES");
Button noButton = new Button("NO");
HorizontalPanel dialogHPanel = new HorizontalPanel();
dialogHPanel.setWidth("100%");
dialogHPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
dialogHPanel.add(noButton);
dialogHPanel.add(yesButton);
noButton.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
vlb.setValue(vlb.getOldValue());
dialogBox.hide();
}
});
yesButton.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
changeGroupAndQuestions(question, vlb.getValue());
dialogBox.hide();
}
});
// Set the contents of the Widget
dialogBox.setWidget(dialogHPanel);
dialogBox.setPopupPosition(180, 425);
dialogBox.show();
}
}
Here's a screenshot:
As you can see, the ValueListBox options close before the DialogBox appears and the screen no longer locks.