Disable window offset when keyboard appears for ios app - ios

Disable window offset when keyboard appears for ios app
I would like to disable the window offset when the keyboard appears for the ios app. For an android app, this is done via AndroidManifest.xml:
<activity ... android:windowSoftInputMode="adjustResize">
When the keyboard appears, the components do not move from their places.
Is it possible to get this behavior for ios?

Found the solution here in the comments:
iOS Make window-scrolling optional for Items
https://bugreports.qt.io/browse/QTBUG-80790
(this workaround works well for me)
========================
Adrian Eddy added a comment - 11 Apr '20 01:44 - edited
I found a workaround that works with QML . The idea is to install an event filter on QQuickItem and listen for a QEvent::InputMethodQuery with Qt::InputMethodQuery::ImCursorRectangle. Then we set its value to empty QRectF and Qt will no longer scroll the view to show that text field.
in C++ prepare a class and expose it to QML:
class Api : public QObject {
Q_OBJECT
....
public:
Q_INVOKABLE void setupImEventFilter(QQuickItem *item) {
static thread_local ImFixer imf;
item->installEventFilter(&imf);
}
}
// somewhere in main():
view.rootContext()->setContextProperty("api", new Api());
We'll need the actual event filter too:
class ImFixer :
public QObject {
Q_OBJECT
protected:
bool eventFilter(QObject *obj, QEvent *event) override {
if (event->type() == QEvent::InputMethodQuery) {
QInputMethodQueryEvent *imEvt = static_cast<QInputMethodQueryEvent *>(event);
if (imEvt->queries() == Qt::InputMethodQuery::ImCursorRectangle) {
imEvt->setValue(Qt::InputMethodQuery::ImCursorRectangle, QRectF());
return true;
}
}
return QObject::eventFilter(obj, event);
}
};
Finally in QML add:
TextField {
id: tf;
...
Component.onCompleted: api.setupImEventFilter(tf);
}

Related

How can I Get Xamarin iOS Application to Automatically Sense Light and Dark Changes?

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());

How to hide keyboard in iOS mobile automation using Appium

I am using iOS version of 10.2 and xcode version is 8.3.
Can anyone let me know how to hide the keyboard in iOS mobile automation using Appium?
programming language used: Java.
I tried driver.hideKeyboard(), but it doesn't work for me.
So, I tried with way:
by pressing the button specified key name and way
inspect key coordinate with appium and perform action. Both ways are work for me.
// way 1
driver.findElementByXPath(String.format("//XCUIElementTypeButton[#name='%s']", "Done")).click();
// way 2
TouchAction touchAction = new TouchAction(driver);
touchAction.tap(new PointOption().withCoordinates(345, 343)).perform();
You could use java_client library methods:
driver.findElementByAccessibilityId("Hide keyboard").click();
driver.hideKeyboard(HideKeyboardStrategy.TAP_OUTSIDE);
driver.hideKeyboard(HideKeyboardStrategy.PRESS_KEY, "Done");
I noticed that "Done" is not part of the keyboard group. So I tried to use the name "Done" as my reference to get the element. I tried this on my end and it works.
driver.findElementByName("Done").click();
The "driver" set declared as IOSDriver.
You can use below code snippet to hide keyboard:
driver.getKeyboard().pressKey(Keys.RETURN);
Solution for Python - 2020:
#staticmethod
def hide_keyboard(platform):
"""
Hides the software keyboard on the device.
"""
if platform == "Android":
driver.hide_keyboard()
elif platform == "iOS":
driver.find_element_by_name("Done").click()
i prefer to tap last key on keyboard for iOS instead of hide:
#HowToUseLocators(iOSXCUITAutomation = LocatorGroupStrategy.CHAIN)
#iOSXCUITFindBy(className = "XCUIElementTypeKeyboard")
#iOSXCUITFindBy(className = "XCUIElementTypeButton")
private List<IOSElement> last_iOSKeyboardKey;
#HowToUseLocators(iOSXCUITAutomation = LocatorGroupStrategy.CHAIN)
#iOSXCUITFindBy(className = "XCUIElementTypeKeyboard")
#iOSXCUITFindBy(iOSNsPredicate = "type == 'XCUIElementTypeButton' AND " +
"(name CONTAINS[cd] 'Done' OR name CONTAINS[cd] 'return' " +
"OR name CONTAINS[cd] 'Next' OR name CONTAINS[cd] 'Go')")
private IOSElement last_iOSKeyboardKey_real;
public boolean tapLastKeyboardKey_iOS() {
System.out.println(" tapLastKeyboardKey_iOS()");
boolean bool = false;
setLookTiming(3);
try {
// one way
//bool = tapElement_XCTest(last_iOSKeyboardKey.get(last_iOSKeyboardKey.size()-1));
// slightly faster way
bool = tapElement_XCTest(last_iOSKeyboardKey_real);
} catch (Exception e) {
System.out.println(" tapLastKeyboardKey_iOS(): looks like keyboard closed!");
System.out.println(driver.getPageSource());
}
setDefaultTiming();
return bool;
}
I tried using all of above method. In some case, it doesn't work perfectly. In my way, it will tap on top left of keyboard.
public void hideKeyboard() {
if (isAndroid()) {
driver.hideKeyboard();
} else {
IOSDriver iosDriver = (IOSDriver) driver;
// TODO: Just work for Text Field
// iosDriver.hideKeyboard();
// TODO: Tap outside of Keyboard
IOSElement element = (IOSElement) iosDriver.findElementByClassName("XCUIElementTypeKeyboard");
Point keyboardPoint = element.getLocation();
TouchAction touchAction = new TouchAction(driver);
touchAction.tap(keyboardPoint.getX() + 2, keyboardPoint.getY() - 2).perform();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Since the IOS device keyboard doesn't have any "Done" or "Enter" buttons anymore so we can't use any of the Appium server utility interface like HideKeyboardStrategy.
I basically used the TouchAction class tap method to tap at top of the screen and dismiss the keyboard.
TouchAction touchAction = new TouchAction(driver);
int topY = driver.manage().window().getSize().height / 8;
int pressX = driver.manage().window().getSize().width / 2;
touchAction.tap(new PointOption().withCoordinates(pressX, topY)).perform();
Quick & simple solution :
I always try to tap anywhere on screen, may be on
Static text
Image
after entering to hide keyboard unless I explicitly has requirement of interacting with keyboard. This works pretty well for me. Try it :)

How to exit the App in Xamarin Forms?

My project is built with master-detail navigation.
There are totally three pages in the list named as Resources, Contacts, and Login.
Everything works fine in iOS, but when the user presses the Droid/WinPhone devices hardware back button, the app should exit.
Is there any app-exit mechanism for Xamarin Forms which will work on all the devices.? (I mean native code not platform dependent)
Thanks in advance.
I did that on this way
In xamarin forms I added interface
public interface INativeHelper
{
void CloseApp();
}
In android project I made implementation of INativeHelper
public class NativeHelper : INativeHelper
{
public void CloseApp()
{
Android.OS.Process.KillProcess(Android.OS.Process.MyPid());
}
}
Implementation of INativeHelper in IOS
public class NativeHelper : INativeHelper
{
public void CloseApp()
{
Process.GetCurrentProcess().CloseMainWindow();
Process.GetCurrentProcess().Close();
}
}
And then just override method OnBackButtonPressed in page in Xamarin.Forms project
protected override bool OnBackButtonPressed()
{
INativeHelper nativeHelper = null;
nativeHelper = DependencyService.Get<INativeHelper>();
if (nativeHelper != null)
{
nativeHelper.CloseApp();
}
return base.OnBackButtonPressed();
}
I didn't made implementation for WinPhone, but it should be similar.
You can use a DepedencyService for closing an app when your physical back button is pressed:
In your UI (PCL), do the following:
protected override bool OnBackButtonPressed()
{
if (Device.OS == TargetPlatform.Android)
DependencyService.Get<IAndroidMethods>().CloseApp();
return base.OnBackButtonPressed();
}
Now implement the Android-specific logic in your Android project:
[assembly: Xamarin.Forms.Dependency(typeof(AndroidMethods))]
namespace Your.Namespace
{
public class AndroidMethods : IAndroidMethods
{
public void CloseApp()
{
Android.OS.Process.KillProcess(Android.OS.Process.MyPid());
}
}
}
Also create an Interface (in your UI PCL):
public interface IAndroidMethods
{
void CloseApp();
}
As far as I know there is no native way to exit the app in Xamarin application.
The only way is to use dependency service. Override OnBackButtonPressed function in your ContentPage and check it is the last page:
protected override bool OnBackButtonPressed()
{
if(navigation.NavigationStack.Count == 1)//navigation is MainPage.Navigation
DependencyService.Get<YourDependencyInterface>().CloseApp();
}
For Android in YourAndroidDependency class:
public void CloseApp()
{
(Xamarin.Forms.Forms.Context as Activity).Finish();
}
As for WinPhone I'm not sure but I believe it can be done in same way - dependency service.
Having experimented with all the above, I found that none of the above worked on a Google Pixel 3a, with latest version of Android
The command that came closest was
Android.OS.Process.KillProcess(Android.OS.Process.MyPid());
However it left the remains of the app still visible in the background.
The following worked for me when called from the Android Main Activity
public void ExitApp()
{
this.FinishAndRemoveTask();
Android.OS.Process.KillProcess(Android.OS.Process.MyPid());
}
The first line FinishAndRemoveTask removes the app from both the foreground and the background, however the Application process is still active, hence the need for the second command.
This is the more easy way found:
public void QuitApp(object sender, EventArgs args)
{
Process.GetCurrentProcess().CloseMainWindow();
Process.GetCurrentProcess().Close();
}
PS: Tested in android
You can use Environment.Exit(0);

GWT Window.confirm() triggered by onchange of ValueListBox crashing Safari on iPad iOS 7.0.6

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.

how to disable(Hide) application icon from SwitchApplication popup screen in blackberry?

i am developing an application which contain alternative entry point.
and i put tick mark in "Do not display in Blackberry Home screen". here it is working fine it does not show icon on the home screen. but my problem is that
when i am click on SwitchApplication from menu(Home screen), the alternative entry point icon is showing on the popup screen like following image. i dont want to show that icon.i want hide that icon programatically.
please help me
You can hide app if it's service. Set system module (systemmodule) to true for bb ant tools. There is similar options for JDE and Eclipse plugin.
just override this method into our application
like following
private static boolean flag=false;
public static void main(String[] args)
{
StartUp startUp;
if(args!=null && args.length>0 && args[0].equals("gui")){
flag=false;
startUp = new StartUp("gui");
startUp.enterEventDispatcher();
}else{
flag=true;
startUp = new StartUp();
startUp.enterEventDispatcher();
}
}
i override this method
protected boolean acceptsForeground() {
return flag;
}
This is the code that I ended up using that worked for me. I had tried putting the acceptsForeground in my main launcher class at first, but then put it in PushListener itself instead to prevent it from appearing in the running tasks menu. Worked fine.
Launcher Class
public static void main(String[] args) {
if (args != null && args.length > 0 && args[0].equals("gui")) {
MyApp app = new MyApp();
app.enterEventDispatcher();
} else {
PushListener.waitForInstance().start();
}
}
PushListener Class
protected boolean acceptsForeground() {
return false; // You could use a variable instead if you wanted.
}
It's quite simple if you use blackberry eclipse plugin.
open "blackberry_description_app.xml", just check this: Don't display the app icon on blackberry home screen.

Resources