nativescript modal dialog transparency - ios

I try to create a custom dialog with nativescript using this link https://docs.nativescript.org/angular/code-samples/modal-page.html
All work great. But I don't know how to make the modal dialog transparent. The property backgroundcolor doesn't works with ios
Any help will be fine

Apple recommends that you don't make modals transparent, see this issue on nativescript's issue tracker: https://github.com/NativeScript/NativeScript/issues/2086#issuecomment-220629191
Nativescript's built-in modal is always fullscreen on iOS and cannot be transparent.
BUT you can workaround that if you (like us) need to.
Here is how we did it with nativescript-angular:
First inject Page in the modal-component.
On iOS override the function _showNativeModalView on the page-object like this:
import { Page } from 'ui/page';
const pageCommon = require('ui/page/page-common').Page;
import { Color } from 'color';
import * as utils from 'utils/utils';
......
in the constructor:
if (page.ios) {
// iOS by default won't let us have a transparent background on a modal
// Ugly workaround from: https://github.com/NativeScript/nativescript/issues/2086#issuecomment-221956483
page.backgroundColor = new Color(50, 0, 0, 0);
(<any>page)._showNativeModalView = function(parent, context, closeCallback, fullscreen) {
pageCommon.prototype._showNativeModalView.call(this, parent, context, closeCallback, fullscreen);
let that = this;
this._modalParent = parent;
if (!parent.ios.view.window) {
throw new Error('Parent page is not part of the window hierarchy. Close the current modal page before showing another one!');
}
if (fullscreen) {
this._ios.modalPresentationStyle = 0;
} else {
this._ios.modalPresentationStyle = 2;
this._UIModalPresentationFormSheet = true;
}
pageCommon.prototype._raiseShowingModallyEvent.call(this);
this._ios.providesPresentationContextTransitionStyle = true;
this._ios.definesPresentationContext = true;
this._ios.modalPresentationStyle = UIModalPresentationOverFullScreen;
this._ios.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
this._ios.view.backgroundColor = UIColor.clearColor;
parent.ios.presentViewControllerAnimatedCompletion(this._ios, utils.ios.MajorVersion >= 9, function completion() {
that._ios.modalPresentationStyle = UIModalPresentationCurrentContext;
that._raiseShownModallyEvent(parent, context, closeCallback);
});
};
}
You could also override that prototype of Page, but I think it's much cleaner to override it on the instance of Page instead.

Related

Xamarin forms Stop screen shot and record in ios

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.

Xamarin Forms: Webview showing slight black line at bottom

I am creating an app using Xamarin Forms using PCL project. In ios, a black line is shown at the bottom of the web view only. I don't experience the same issue in android or windows 10.
As noted in the comments, I dealt with this before. It has to do with the background color of the webview. I have tried several things, the only thing that worked was setting this:
webView.Opaque = false;
webView.BackgroundColor = UIColor.Clear;
In a custom renderer on the UIWebView.
A complete implemented custom renderer would then look like this:
[assembly: ExportRenderer (typeof (WebView), typeof (WebViewRenderer))]
namespace YourApp.iOS.Renderers
{
public class WebViewRenderer : Xamarin.Forms.Platform.iOS.WebViewRenderer
{
protected override void OnElementChanged (VisualElementChangedEventArgs e)
{
base.OnElementChanged (e);
if (NativeView != null) {
var webView = (UIWebView)NativeView;
webView.Opaque = false;
webView.BackgroundColor = UIColor.Clear;
}
}
}
}

Multitouch not working on iOS with robovm and libGDX when displaying banner ads

I'm having a problem with input in libGDX in the iOS backend. It happens when I have Mopub banner ads displayed. When I put my first finger on the screen, I get a touchDown event (pointer = 0) and when it comes to my second finger, nothing is triggered. BUT for some reason it works when I put my second finger near the banner area (I think it's the banner's frame that I'm hitting). When banner ads aren't displayed, everything works fine. Also everything works fine on Android.
I'd really appreciate the help to tackle this problem here.
Thanks in advance.
iOS 8.3;
roboVM 1.2.0;
gdx 1.6.0;
Here's how I load the Banner:
UIApplication application;
String id;
BANNER_SIZE = MPConstants.MOPUB_BANNER_SIZE;
id = BANNER_ID;
rootViewController = application.getKeyWindow().getRootViewController();
banner = new MPAdView(id, BANNER_SIZE);
double bannerWidth = UIScreen.getMainScreen().getBounds().getWidth();
double bannerHeight = bannerWidth / BANNER_SIZE.getWidth() * BANNER_SIZE.getHeight();
banner.setFrame(new CGRect((UIScreen.getMainScreen().getBounds().getWidth() / 2d) - (BANNER_SIZE.getWidth() * .5d), 0, bannerWidth, bannerHeight));
adViewController = new MPAdViewController(banner);
MPAdViewDelegate bannerDelegate = new MPAdViewDelegateAdapter(){
#Override
public UIViewController getViewController() {
return adViewController;
}
};
banner.setDelegate(bannerDelegate);
adViewController.getView().addSubview(banner);
rootViewController.getView().addSubview(adViewController.getView());
if(!isBannerLoaded) {
banner.loadAd();
isBannerLoaded = true;
}
Here's my didFinishLaunching method:
#Override
public boolean didFinishLaunching(UIApplication application, UIApplicationLaunchOptions launchOptions) {
super.didFinishLaunching(application, launchOptions);
//The 0 doesn't do anything. It was something I was trying out.
adController.loadBanner(application, 0);
rootViewController = application.getKeyWindow().getRootViewController();
application.getKeyWindow().setRootViewController(rootViewController);
application.getKeyWindow().addSubview(rootViewController.getView());
application.getKeyWindow().makeKeyAndVisible();
return false;
}
You should add this line to your adViewController
adViewController.getView().setMultipleTouchEnabled(true);

Monotouch - UIImagePickerController with an iPad App

I have an iPad only application that I'm trying to allow users to select images from their PhotoLibrary, near as I can tell I have to use the UIImagePickerController in a UIPopOverController. I have attempted many different ways to do this but I can get anything to work. I've seen a lot of code snippets but I can't seem to get them working under Monotouch.
Could somebody point me at the correct way to do this? I greatly appreciate it.
I had to call the code that creates the image picker and the code that reacts to the image being picked from the main thread to get it to work:
partial void OnImport (UIButton s)
{
BeginInvokeOnMainThread(delegate
{
UIImagePickerController picker = new UIImagePickerController();
picker.ContentSizeForViewInPopover = new System.Drawing.SizeF(320,480);
UIPopoverController popover = new UIPopoverController(picker);
picker.FinishedPickingImage += delegate(object sender, UIImagePickerImagePickedEventArgs e)
{
BeginInvokeOnMainThread(delegate
{
UIImage image = (UIImage)info.ObjectForKey(new NSString("UIImagePickerControllerOriginalImage"));
picker.DismissModalViewControllerAnimated(true);
// do something with image
});
};
picker.SourceType = UIImagePickerControllerSourceType.PhotoLibrary;
popover.PresentFromRect(s.Frame, this.View, UIPopoverArrowDirection.Left, true);
});
}
Here is code that I've used in an app - this should serve as a good start for you to get it working.
UIImagePickerController imagePicker;
UIPopoverController popOver;
void AttachImageBtnTouched(object sender, EventArgs e)
{
if (popOver == null || popOver.ContentViewController == null)
{
imagePicker = new UIImagePickerController();
popOver = new UIPopoverController(imagePicker);
ImagePickerDelegate imgDel = new ImagePickerDelegate();
imagePicker.Delegate = imgDel;
imagePicker.SourceType = UIImagePickerControllerSourceType.PhotoLibrary;
}
if (popOver.PopoverVisible)
{
popOver.Dismiss(true);
imagePicker.Dispose();
popOver.Dispose();
return;
}
else
{
popOver.PresentFromRect(btnAttachment.Frame, this.View, UIPopoverArrowDirection.Any, true);
}
}
// The Delegate class looks something like
public class ImagePickerDelegate : UIImagePickerControllerDelegate
{
public ImagePickerDelegate()
{}
public override void FinishedPickingMedia(UIImagePickerController picker, NSDictionary info)
{
UIImage image = (UIImage)info.ObjectForKey(new NSString("UIImagePickerControllerOriginalImage"));
// do whatever else you'd like to with the image
}
}

xpcom/jetpack observe all document loads

I write a Mozilla Jetpack based add-on that has to run whenever a document is loaded. For "toplevel documents" this mostly works using this code (OserverService = require('observer-service')):
this.endDocumentLoadCallback = function (subject, data) {
console.log('loaded: '+subject.location);
try {
server.onEndDocumentLoad(subject);
}
catch (e) {
console.error(formatTraceback(e));
}
};
ObserverService.add("EndDocumentLoad", this.endDocumentLoadCallback);
But the callback doesn't get called when the user opens a new tab using middle click or (more importantly!) for frames. And even this topic I only got through reading the source of another extension and not through the documentation.
So how do I register a callback that really gets called every time a document is loaded?
Edit: This seems to do what I want:
function callback (event) {
// this is the content document of the loaded page.
var doc = event.originalTarget;
if (doc instanceof Ci.nsIDOMNSHTMLDocument) {
// is this an inner frame?
if (doc.defaultView.frameElement) {
// Frame within a tab was loaded.
console.log('!!! loaded frame:',doc.location.href);
}
else {
console.log('!!! loaded top level document:',doc.location.href);
}
}
}
var wm = Cc["#mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
var mainWindow = wm.getMostRecentWindow("navigator:browser");
mainWindow.gBrowser.addEventListener("load", callback, true);
Got it partially from here: https://developer.mozilla.org/en/XUL_School/Intercepting_Page_Loads
#kizzx2 you are better served with #jetpack
To the original question: why don't you use tab-browser module. Something like this:
var browser = require("tab-browser");
exports.main = function main(options, callbacks) {
initialize(function (config) {
browser.whenContentLoaded(
function(window) {
// something to do with the window
// e.g., if (window.locations.href === "something")
}
);
});
Much cleaner than what you do IMHO and (until we have official pageMods module) the supported way how to do this.
As of Addon SDK 1.0, the proper way to do this is to use the page-mod module.
(Under the hood it's implemented using the document-element-inserted observer service notification, you can use it in a regular extension or if page-mod doesn't suit you.)

Resources