StackLayout stackLayout = new StackLayout()
{
BackgroundColor = Color.Transparent
};
var touchEffect = new TouchTracking.Forms.TouchEffect() { Capture = true };
touchEffect.TouchAction += TouchEffect_TouchAction;
stackLayout.Effects.Add(touchEffect);
Content=stackLayout;
When I touch the simulator it not work. why?
This is an existing issue of the plugin . Add the following line to AppDelegate.cs in iOS project
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App());
var _ = new TouchTracking.Forms.iOS.TouchEffect();
return base.FinishedLaunching(app, options);
}
Related
Using xamarin forms and we are adding ability to switch between Dark-Light mode. All is good however the first page of the app in android whatever I do the status bar color wont change.
I guess that in the android project I have to call SetTheme(...) before OnCreate.
Or Am I missing something here?
Question
How do you set the status bar color depending on theme? code below does not change once the android has loaded
public void SetStatusBarColor(System.Drawing.Color color, bool darkStatusBarTint)
{
var activity = Platform.CurrentActivity;
var window = activity.Window;
window?.AddFlags(WindowManagerFlags.DrawsSystemBarBackgrounds);
window?.ClearFlags(WindowManagerFlags.TranslucentStatus);
window?.SetStatusBarColor(color.ToPlatformColor());
var flag = (StatusBarVisibility)SystemUiFlags.LightStatusBar;
if (window != null)
{
window.DecorView.SystemUiVisibility = darkStatusBarTint ? flag : 0;
}
}
Suggestions?
thanks
Try this:
private void SetStatusBarColor(System.Drawing.Color color, bool darkStatusBarTint)
{
var activity = Platform.CurrentActivity;
var window = activity.Window;
if (window != null)
{
window.AddFlags(WindowManagerFlags.DrawsSystemBarBackgrounds);
window.ClearFlags(WindowManagerFlags.TranslucentStatus);
window.SetStatusBarColor(color.ToPlatformColor());
StatusBarVisibility flags = default;
if (darkStatusBarTint)
flags |= (StatusBarVisibility)SystemUiFlags.LightStatusBar;
else
flags &= ~(StatusBarVisibility)SystemUiFlags.LightStatusBar;
window.DecorView.SystemUiVisibility = flags;
}
}
Or
private void SetStatusBarColor(System.Drawing.Color color, bool darkStatusBarTint)
{
var activity = Platform.CurrentActivity;
var window = activity.Window;
if (window != null)
{
window.AddFlags(WindowManagerFlags.DrawsSystemBarBackgrounds);
window.ClearFlags(WindowManagerFlags.TranslucentStatus);
window.SetStatusBarColor(color.ToPlatformColor());
window.DecorView.SystemUiVisibility = darkStatusBarTint
? (StatusBarVisibility)SystemUiFlags.LightStatusBar
: StatusBarVisibility.Visible;
}
}
Both functions work.
You can update the StatusBar color in the MainActivity.OnCreate method and also listen to the App.Current.RequestedThemeChanged event.
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
ApplyStatusBarColor(App.Current.RequestedTheme);
App.Current.RequestedThemeChanged += (s, e) => ApplyStatusBarColor(e.RequestedTheme);
}
private void ApplyStatusBarColor(Xamarin.Forms.OSAppTheme osAppTheme)
{
if (osAppTheme == Xamarin.Forms.OSAppTheme.Dark)
SetStatusBarColor(Xamarin.Forms.Color.Blue, false);
else
SetStatusBarColor(Xamarin.Forms.Color.Yellow, true);
}
}
My goal is to add an OK button on iOS numeric keyboard; I can achieve that very easily with a custom renderer :
public class ExtendedEntryRenderer : EntryRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (Element == null)
{
return;
}
// Check only for Numeric keyboard
if (this.Element.Keyboard == Keyboard.Numeric)
{
this.AddDoneButton();
}
}
/// <summary>
/// <para>Add toolbar with Done button</para>
/// </summary>
protected void AddDoneButton()
{
var toolbar = new UIToolbar(new RectangleF(0.0f, 0.0f, 50.0f, 44.0f));
var doneButton = new UIBarButtonItem(UIBarButtonSystemItem.Done, delegate
{
this.Control.ResignFirstResponder();
var baseEntry = this.Element.GetType();
((IEntryController)Element).SendCompleted();
});
toolbar.Items = new UIBarButtonItem[] {
new UIBarButtonItem (UIBarButtonSystemItem.FlexibleSpace),
doneButton
};
this.Control.InputAccessoryView = toolbar;
}
}
but my question is how can we add this keyboard behavior on a Xamarin prompt dialog.
await DisplayPromptAsync("Title", "Content", keyboard: Keyboard.Numeric);
If you want to customize the Keyboard of AlertView in iOS , you could implement it by using DependencyService
in Forms
create a Interface
public interface IDisplayPrompt
{
void DisplayPrompt(string Title,string Content,Keyboard keyboard,Action<string> SubmitAction,Action CancelAction);
}
in iOS
using System;
using app55;
using app55.iOS;
using Xamarin.Forms;
using UIKit;
using System.Drawing;
[assembly: Dependency(typeof(DisplayPromptImplement))]
namespace app55.iOS
{
public class DisplayPromptImplement:IDisplayPrompt
{
public DisplayPromptImplement()
{
}
public void DisplayPrompt(string Title, string Content, Keyboard keyboard, Action<string> SubmitAction, Action CancelAction)
{
UIAlertController alertController = UIAlertController.Create(Title,Content,UIAlertControllerStyle.Alert);
UIAlertAction OKAction = UIAlertAction.Create("OK",UIAlertActionStyle.Default,(action)=> {
//click OK Button
var content = alertController.TextFields[0].Text;
SubmitAction.Invoke(content);
});
UIAlertAction DismissAction = UIAlertAction.Create("Cancel", UIAlertActionStyle.Cancel, (action) => {
//click Cancel Button
CancelAction.Invoke();
});
alertController.AddTextField((field)=> {
if (keyboard == Keyboard.Numeric)
field.KeyboardType = UIKeyboardType.NumberPad;
AddDoneButton(field);
});
alertController.AddAction(OKAction);
alertController.AddAction(DismissAction);
UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(alertController,true,null);
}
protected void AddDoneButton(UITextField field)
{
var toolbar = new UIToolbar(new RectangleF(0.0f, 0.0f, 50.0f, 44.0f));
var doneButton = new UIBarButtonItem(UIBarButtonSystemItem.Done, delegate
{
field.ResignFirstResponder();
});
toolbar.Items = new UIBarButtonItem[] {
new UIBarButtonItem (UIBarButtonSystemItem.FlexibleSpace),
doneButton
};
field.InputAccessoryView = toolbar;
}
}
}
Now in Forms we could invoked it like following
void Button_Clicked(System.Object sender, System.EventArgs e)
{
if(Device.RuntimePlatform=="iOS")
{
DependencyService.Get<IDisplayPrompt>().DisplayPrompt("Title", "Please Input Message", Keyboard.Numeric, (content) =>
{
/// get the content that you input
label.Text = content.ToString();
}, null);
}
else
{
// other platform
//...await DisplayPromptAsync
}
}
Screen Shot
This post shows how to set the status bar color for iOS. However, I have HasNavigationBar=false on my pages, so how can I set the color for when you aren't using a nav bar?
My page...
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
NavigationPage.HasNavigationBar="false">
You could add code to the FinishedLaunching method of your AppDelegate class within your iOS project. For example to set status bars color to some shade of green
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
// set status bar color to green
UIView statusBar = UIApplication.SharedApplication.ValueForKey(new NSString("statusBar")) as UIView;
statusBar.BackgroundColor = UIColor.FromRGB(61, 205, 88);
// the usual suspects follow
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App());
return base.FinishedLaunching(app, options);
}
Hope this helps.
This AppDelegate code changes the status bar color for both iOS 13 and older iOS versions.
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
int red = 11;
int green = 22;
int blue = 33;
// the usual Xamarin.Forms code
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App());
bool canLoadUrl = base.FinishedLaunching(app, options);
// get status bar and set color
UIView statusBar;
if (UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
{
const int tag = 999;
var window = UIApplication.SharedApplication.Delegate.GetWindow();
if (window is null) return null;
statusBar = window.ViewWithTag(tag) ?? new UIView(UIApplication.SharedApplication.StatusBarFrame)
{
Tag = tag
};
window.AddSubview(statusBar);
}
else
{
statusBar = UIApplication.SharedApplication.ValueForKey(new NSString("statusBar")) as UIView;
}
if (!(statusBar is null))
{
statusBar.BackgroundColor = UIColor.FromRGB(red, green, blue);
}
return canLoadUrl;
}
I am working with xamarin forms. In Xamarin Android I received the notification when app not in foregroud/backgroud (i.e killed the app). When clicking on the notification I need to navigate to specific page.
protected override void OnNewIntent(Intent intent)
{
base.OnNewIntent(intent);
string notificationMessage = intent.GetStringExtra(Constants.MESSAGE);
string notificationThreadId = intent.GetStringExtra(Constants.MESSAGE_THREAD_ID);
bool isFromNotificaion = true;
PushNotificationLog notificationLog = new PushNotificationLog(notificationMessage, notificationThreadId, isFromNotificaion);
ConferenceMobileApp.App app = new App(notificationLog);
LoadApplication(app);
}
The OnNewIntent is called when app in foreground or background , not when app is killed.
And my notification send code is below
void SendNotification(RemoteMessage message)
{
string messageBody = "";
string messageThreadId = "";
message.Data.TryGetValue(MESSAGE,out messageBody);
message.Data.TryGetValue(MESSAGE_THREAD_ID, out messageThreadId);
string messageLogId = "0";//message.Data.TryGetValue(MESSAGE_LOG_ID);
var intent = new Intent(this, typeof(MainActivity));
intent.AddFlags(ActivityFlags.ClearTop);
intent.AddFlags(ActivityFlags.SingleTop);
intent.PutExtra(MESSAGE, messageBody);
intent.PutExtra(MESSAGE_THREAD_ID, messageThreadId);
//intent.PutExtra(MESSAGE_LOG_ID, messageLogId);
var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot);
var notificationBuilder = new Notification.Builder(this).SetSmallIcon(Resource.Drawable.common_google_signin_btn_icon_dark)
.SetContentTitle("PKConf")
.SetContentText(messageBody)
.SetAutoCancel(true)
.SetContentIntent(pendingIntent);
var notificationManager = NotificationManager.FromContext(this);
//setting notification id
int notificaionId = Convert.ToInt32(messageLogId);
notificationManager.Notify(notificaionId, notificationBuilder.Build());
}
How could I achieve this when app is not in foreground/background?
Please try with below events in your mainactivity.cs
protected override void OnResume()
{
base.OnResume(); // Always call the superclass first.
}
protected override void OnPause()
{
base.OnPause(); // Always call the superclass first
}
You can try overriding OnResume
protected async override void OnResume()
{
base.OnResume();
// Your Code. I would guess same code as you have in OnNewIntent
}
So ive been working on an app that uses a MasterDetail page and its going fine but Im just a little bit confused on how its suppose to navigate through pages.
At the moment i have the menu items opening some pages in the app and that parts working great, the side menu stays. The thing im confused with is how to handle having buttons on the main page being displayed. My buttons at the moment just open up a new page but the side menu of the MasterDetail page just disappears into the regular NavigationPage.
I will give my button code below.
btnSocial.GestureRecognizers.Add(new TapGestureRecognizer
{
Command = new Command(() =>
{
Navigation.PushAsync(new SocialPage());
})
});
Is this just how a MasterDetail page navigates or do you think im doing something wrong?
** EDITED **
Just incase this helps, i will attach my menuopage and launchpage code:
MenuPage.cs
public class MenuPage : ContentPage
{
public Action<ContentPage> OnMenuSelect { get; set; }
public MenuPage()
{
Title = "Menu";
Icon = "ic_menu.png";
BackgroundColor = ProjectVariables.PRIMARY_COLOR;
var items = new List<MenuItems>()
{
new MenuItems("Social", () => new SocialPage()),
new MenuItems("Career", () => null),
new MenuItems("MySchedule", () => null),
new MenuItems("Videos", () => null),
new MenuItems("Contact", () => null),
new MenuItems("Sign in", () => null)
};
var dataTemplate = new DataTemplate(typeof(TextCell));
dataTemplate.SetValue(TextCell.TextColorProperty, Color.White);
dataTemplate.SetBinding(TextCell.TextProperty, "Name");
var listview = new ListView()
{
ItemsSource = items,
ItemTemplate = dataTemplate
};
listview.BackgroundColor = ProjectVariables.PRIMARY_COLOR;
listview.ItemSelected += (object sender, SelectedItemChangedEventArgs e) =>
{
if(OnMenuSelect != null)
{
var item = (MenuItems)e.SelectedItem;
var itemPage = item.PageFn();
OnMenuSelect(itemPage);
}
};
Content = new StackLayout
{
Orientation = StackOrientation.Vertical,
Children =
{
listview
}
};
}
}
LaunchPage.cs
public class LaunchPage : MasterDetailPage
{
public LaunchPage()
{
var menuPage = new MenuPage();
menuPage.OnMenuSelect = (categoryPage) =>
{
Detail = new NavigationPage(categoryPage);
//Detail.Navigation.PushAsync(categoryPage);
IsPresented = false;
};
Master = menuPage;
Detail = new NavigationPage(new MainPage())
{
BarTextColor = Color.White,
BarBackgroundColor = ProjectVariables.PRIMARY_COLOR
};
MasterBehavior = MasterBehavior.Split;
}
}
Have a look at this documentation page from Xamarin.
It looks like you do not use the navigation service for this. You need a reference to your master page and set the Detail property for it.
Look at this section in particular.
public partial class MainPage : MasterDetailPage
{
public MainPage ()
{
...
masterPage.ListView.ItemSelected += OnItemSelected;
}
void OnItemSelected (object sender, SelectedItemChangedEventArgs e)
{
var item = e.SelectedItem as MasterPageItem;
if (item != null) {
Detail = new NavigationPage ((Page)Activator.CreateInstance (item.TargetType));
masterPage.ListView.SelectedItem = null;
IsPresented = false;
}
}
}
On the selection of a ListView item they set the Detail property and it will do the navigation for you.