i want to use a container view in story board project with mono touch and i don't know good objective c have a lot of sample but i couldn't understand.
thanks a lot
i have 4 view controller on my project and one customseque
i don't know how to call first view controller in main view controller
i try to put some codes in container view controller but couldn't success please help me from where i have to call and which code will call it - please xamarin code ..
i solved my problem like this.. thanks by the way who is viewed this question..
public override void PrepareForSegue (UIStoryboardSegue segue, NSObject sender)
{
base.PrepareForSegue (segue, sender);
if (segue.Identifier == SegueIdentifierFirst) {
var a = segue.DestinationViewController as FirstViewController;
firstViewController = a;
}
if (segue.Identifier == SegueIdentifierSecond) {
var b = segue.DestinationViewController as SecondViewController;
secondViewController = b;
}
if (segue.Identifier == SegueIdentifierFirst) {
if (this.ChildViewControllers.Length > 0) {
this.swapFromViewController (this.ChildViewControllers [0], this.firstViewController);
} else {
this.AddChildViewController(firstViewController);
UIView destView = ((UIViewController)firstViewController).View;
destView.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight;
destView.Frame = new RectangleF(0, 0, this.View.Frame.Size.Width, this.View.Frame.Size.Height);
this.View.AddSubview(destView);
(firstViewController).DidMoveToParentViewController (this);
}
} else if (segue.Identifier == SegueIdentifierSecond) {
swapFromViewController (this.ChildViewControllers[0], this.secondViewController);
}
}
Related
My application works portait, ma i want fullscreen video playback even in landscape mode using the plugin mentionend above.
For this purpose I create a customrenderer to take access to native AVPlayerViewController Ios Control.
I tried in many many ways, but seems to be impossible to handle exit fullscreen event. In that method i want to force layout portrait. I have the code for reset orientation already implemented but the problem is to put the code in the right place.
Any other that faced the same issue??
I tried to search for something useful in AVPlayerView(not accessible), AVPlayerVideoController, AVPlayerCurrentItem etc
Any ideas?
Thanks you in advance.
I have translated the OC code to C# in this link for you, see the following codes:
using Foundation;
using CoreGraphics;
playerViewController = new AVPlayerViewController();
playerViewController.ContentOverlayView.AddObserver(this, new NSString("bounds"), NSKeyValueObservingOptions.New | NSKeyValueObservingOptions.Old , IntPtr.Zero);
public override void ObserveValue(NSString keyPath, NSObject ofObject, NSDictionary change, IntPtr context)
{
base.ObserveValue(keyPath, ofObject, change, context);
if(ofObject == playerViewController.ContentOverlayView)
{
if(keyPath == "bounds")
{
NSValue oldRect = change.ValueForKey(new NSString("NSKeyValueChangeOldKey")) as NSValue;
NSValue newRect = change.ValueForKey(new NSString("NSKeyValueChangeNewKey")) as NSValue;
CGRect oldBounds = oldRect.CGRectValue;
CGRect newBounds = newRect.CGRectValue;
bool wasFullscreen = CGRect.Equals(oldBounds, UIScreen.MainScreen.Bounds);
bool isFullscreen = CGRect.Equals(newBounds, UIScreen.MainScreen.Bounds);
if(isFullscreen && !wasFullscreen)
{
if(CGRect.Equals(oldBounds,new CGRect(0,0,newBounds.Size.Height, newBounds.Size.Width)))
{
Console.WriteLine("rotated fullscreen");
}
else
{
Console.WriteLine("entered fullscreen");
}
}
else if(!isFullscreen && wasFullscreen)
{
Console.WriteLine("exited fullscreen");
}
}
}
}
I have a sprite that I can drag around on screen. I want to be able to drag this sprite into an area (box). As it stands now I can only drop the sprite into the box, but when I drag it directly inn, the the program crashes.
*Im developing in FlashDevelop but windows gave me av option to debug in VS.
I debugged in VS and got this ERROR:
Unhandled exception at 0x00ACCEE9 in Proj.exe: 0xC0000005: Access violation reading location 0x00000008.
Relevant code:
class Drag extends FlxGroup {
var mouseJoint:DistanceJoint;
public inline function registerPhysSprite(spr:FlxNapeSprite)
{
MouseEventManager.add(spr, createMouseJoint);
}
function createMouseJoint(spr:FlxSprite)
{
var body:Body = cast(spr, FlxNapeSprite).body;
mouseJoint = new DistanceJoint(FlxNapeState.space.world, body, new Vec2(FlxG.mouse.x, FlxG.mouse.y),
body.worldPointToLocal(new Vec2(FlxG.mouse.x, FlxG.mouse.y)), 0, 0);
mouseJoint.space = FlxNapeState.space;
}
override public function update():Void
{
super.update();
if (mouseJoint != null)
{
mouseJoint.anchor1 = new Vec2(FlxG.mouse.x, FlxG.mouse.y);
if (FlxG.mouse.justReleased)
{
mouseJoint.space = null;
}
}
}
}
class PlayState extends FlxNapeState {
override public function create()
{
super.create();
bgColor = FlxColor.BLACK;
napeDebugEnabled = true;
var light = new Light(10, 10);
var box = new Box(100, 100);
var drag:Drag;
createWalls(1, 1, 1024, 768, 10, new Material(1, 1, 2, 1, 0.001));
add(light);
add(box);
drag = new Drag();
add(drag);
drag.registerPhysSprite(light);
light.body.velocity.y = 200;
FlxNapeState.space.listeners.add(new InteractionListener(
CbEvent.BEGIN,
InteractionType.COLLISION,
Light.CB_TYPE,
Box.CB_TYPE,
collideLightBox));
}
function collideLightBox(callback:InteractionCallback)
{
var light:Light = cast callback.int1.castBody.userData.sprite;
light.kill();
}
}
class Light extends FlxNapeSprite {
public static var CB_TYPE(default, null) = new CbType();
public function new(x:Float, y:Float)
{
super(x, y);
makeGraphic(10, 10, FlxColor.TRANSPARENT);
var radius = 5;
drawCircle(5, 5, radius, FlxColor.WHITE);
createCircularBody(radius);
body.cbTypes.add(CB_TYPE);
body.userData.sprite = this;
}
}
class Box extends FlxNapeSprite {
public static var CB_TYPE(default, null) = new CbType();
public function new(x:Float, y:Float)
{
super(x, y);
makeGraphic(100, 50, FlxColor.GREEN);
createRectangularBody(width, height);
body.cbTypes.add(CB_TYPE);
body.type = BodyType.STATIC;
}
}
If you're possibly accessing a null pointer, consider the answer given in this question:
Why is this Haxe try-catch block still crashing, when using Release mode for C++ target
That way you can turn on null pointer checks in hxcpp so you can get better debug information.
Also, if you're trying to debug hxcpp directly in FlashDevelop (step-through and all that), that feature isn't released yet, but I spoke with the team recently and they're working on it.
How can i access the ViewController in my DependencyService to present a MFMailComposeViewController? I tried using Application.Context but this seems to be only working on Android. Any advice?
You can present a MFMailComposeViewController by doing a window.RootController.PresentViewController (mail controller, true, null);. Depending on your app architecture, the RootViewController might not be an usable ViewController in the hierarchy. In that case you get a
Warning: Attempt to present <MFMailComposeViewController: 0x16302c30> on <Xamarin_Forms_Platform_iOS_PlatformRenderer: 0x14fd1530> whose view is not in the window hierarchy!
In that case, you have to dig for the concrete ViewController, in my case it is:
var rootController = ((AppDelegate)(UIApplication.SharedApplication.Delegate)).Window.RootViewController.ChildViewControllers[0].ChildViewControllers[1].ChildViewControllers[0];
which is a bit wicked, but works (An issue for this have been filed for future fix).
The full solution then looks like:
in your AppDelegate.cs, add this:
public UIWindow Window {
get { return window; }
}
in your PCL project, declare the interface: ISendMailService.cs
public interface ISendMailService
{
void ComposeMail (string[] recipients, string subject, string messagebody = null, Action<bool> completed = null);
}
in your iOS project, implement and register the interface: SendMailService.cs
[assembly: DependencyAttribute(typeof(SendMailService))]
public class SendMailService : ISendMailService
{
public void ComposeMail (string[] recipients, string subject, string messagebody = null, Action<bool> completed = null)
{
var controller = new MFMailComposeViewController ();
controller.SetToRecipients (recipients);
controller.SetSubject (subject);
if (!string.IsNullOrEmpty (messagebody))
controller.SetMessageBody (messagebody, false);
controller.Finished += (object sender, MFComposeResultEventArgs e) => {
if (completed != null)
completed (e.Result == MFMailComposeResult.Sent);
e.Controller.DismissViewController (true, null);
};
//Adapt this to your app structure
var rootController = ((AppDelegate)(UIApplication.SharedApplication.Delegate)).Window.RootViewController.ChildViewControllers[0].ChildViewControllers[1].ChildViewControllers[0];
var navcontroller = rootController as UINavigationController;
if (navcontroller != null)
rootController = navcontroller.VisibleViewController;
rootController.PresentViewController (controller, true, null);
}
}
And you can now consume it from your Xamarin.Forms PCL project:
new Button {
Font = Font.SystemFontOfSize (NamedSize.Medium),
Text = "Contact us",
TextColor = Color.White,
BackgroundColor = ColorsAndStyles.LightBlue,
BorderRadius = 0,
Command = new Command (()=>{
var mailservice = DependencyService.Get<ISendMailService> ();
if (mailservice == null)
return;
mailservice.ComposeMail (new [] {"foo#example.com"}, "Test", "Hello, World");
})
}
Use: UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(controller, true, null);
I would like to add an additional answer based off of the KeyWindow not always being the main window. (this occurs when you are presenting your controller after the user has interacted with an action sheet or alert dialog)
public static UIViewController GetCurrentUIController()
{
UIViewController viewController;
var window = UIApplication.SharedApplication.KeyWindow;
if (window == null)
{
throw new InvalidOperationException("There's no current active window");
}
if (window.RootViewController.PresentedViewController == null)
{
window = UIApplication.SharedApplication.Windows
.First(i => i.RootViewController != null &&
i.RootViewController.GetType().FullName
.Contains(typeof(Xamarin.Forms.Platform.iOS.Platform).FullName));
}
viewController = window.RootViewController;
while (viewController.PresentedViewController != null)
{
viewController = viewController.PresentedViewController;
}
return viewController;
}
This will guarantee that you get the Xamarin Forms platform renderer window, then find the foremost presented ViewController and return it for use presenting whatever UI or view controller you need to present.
UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(controller, true, null);
This only works in above all solutions
Just for a reference. It took me some time to figure it out how to launch it from modal window.
Here comes the solution:
var rootController = ((AppDelegate)(UIApplication.SharedApplication.Delegate)).Window.RootViewController.PresentedViewController;
var navcontroller = rootController as UINavigationController;
if (navcontroller != null)
rootController = navcontroller.VisibleViewController;
rootController.PresentViewController (controller, true, null);
I have the following in a Section:
_favElement = new StyledStringElement (string.Empty);
_favElement.Alignment = UITextAlignment.Center;
if (_room.IsFavourite) {
_favElement.Image = UIImage.FromBundle ("Images/thumbs_up.png");
_favElement.Caption = "Unmark as Favourite";
} else {
_favElement.Image = null;
_favElement.Caption = "Mark as Favourite";
}
_favElement.Tapped += favElement_Tapped;
Then when I press the element I want the following to happen:
private void favElement_Tapped ()
{
if (_room.IsFavourite) {
_favElement.Image = null;
_favElement.Caption = "Mark as Favourite";
} else {
_favElement.Image = UIImage.FromBundle ("Images/thumbs_up.png");
_favElement.Caption = "Unmark as Favourite";
}
_room.IsFavourite = !_room.IsFavourite;
}
However the image and text does not change in the actual element when the element is tapped. Is there a refresh method or something that must be called? I've also tried changing the Accessory on Tapped as well and nothing changes. The properties behind do reflect the correct values though.
An alternative to reloading the UITableView is to reload the Element using code like this (copied from Touch.Unit):
if (GetContainerTableView () != null) {
var root = GetImmediateRootElement ();
root.Reload (this, UITableViewRowAnimation.Fade);
}
assuming that your code is in DialogViewController,add this
this.ReloadData();
but in your case I recommend you to use BooleanImageElement
I have problem that I don't seem to be able to solve. I have a created a test project, using MEF and Prism4. I've created a test project where I have 2 views and each of them register themselves inside a region, and also a button in another region. When the button is clicked, I want the view of change to the correct view. The code I think is wrong is below, anyone have any ideas what I am doing wrong here ?
public void Initialize()
{
regionManager.RegisterViewWithRegion(RegionNames.MainRegion, typeof(Views.Module1View));
Button button = new Button() { Content = "Module1" };
button.Click += (o, i) =>
{
var region = this.regionManager.Regions[RegionNames.MainRegion];
if (region != null)
{
region.Activate(typeof(Views.Module1View));
}
};
regionManager.AddToRegion(RegionNames.NavigationRegion, button);
}
I get the following error ...
The region does not contain the specified view.
Parameter name: view
Solved it - amazing what a good nights sleep will do! I had to get the view from the ServiceLocator.
public void Initialize()
{
regionManager.RegisterViewWithRegion(RegionNames.MainRegion, () =>
ServiceLocator.Current.GetInstance<Views.Module2View>());
Button button = new Button() { Content = "Module2" };
button.Click += (o, i) =>
{
var view = ServiceLocator.Current.GetInstance<Views.Module2View>();
var region = this.regionManager.Regions[RegionNames.MainRegion];
if (region != null)
{
region.Activate(view);
}
};
regionManager.AddToRegion(RegionNames.NavigationRegion, button);
}