Add subviews to Custom UIView without using a XIB file - uiview

I am trying to create a view class to work with the flyout navigation component.
As of yet, I have not found a way to create a view and add subview's to itself.
Here is a sample view class that I have created--note, I am not using a XIB file because I would like to avoid XCode--it has been going in and out of sync constantly. This is simply a normal C# file that inherits UIView and attempts to create a view. How do I add subviews to it?
using System;
using System.Drawing;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using FlyoutNavigation;
using MonoTouch.Dialog;
namespace Flyout
{
public class MessagesView : UIView
{
public MessagesView ()
{
var field = new UITextField (new RectangleF(10f, 10f, 300f, 40f));
field.Placeholder = "Test";
field.BorderStyle = UITextBorderStyle.RoundedRect;
// does not work MessagesView.addSubview(field);
var field2 = new UITextField (new RectangleF(10f, 60f, 300f, 40f));
field2.Placeholder = "Test2";
field2.BorderStyle = UITextBorderStyle.RoundedRect;
}
}
}

UIView has an AddSubview() method.
[MonoTouch.Foundation.Export("addSubview:")]
public virtual void AddSubview (UIView view)

Related

MvvmCross: RaisePropertyChanged not updating binding

I am instantiating a view with a ViewModel like this:
var myView = new MyView { DataContext = new MyViewModel() };
I want to make this view accessible from anywhere in the application so I am adding the view to the rootviewcontroller:
window.RootViewController.View.Add(myView.View);
Where ViewModel inherits from MvxViewModel and MyView inherist from MvxViewController
Inside the MyView I am binding a UILabel to a text property like this
this.CreateBinding(myLabel).To<MyViewModel>(vm => vm.MyTextProp).Apply();
The text property is defined inside the ViewModel like this
private string myTextProp;
public string MyTextProp
{
get { return myTextProp; }
set
{
myTextProp = value;
RaisePropertyChanged(() => MyTextProp);
}
}
The binding works initially when loaded. But when I change the MyTextProp property and RaisePropertyChanged is called the UILabel is not being updated.
I am also binding to an ICommand which works fine and triggers normally.
Instead of doing var myView = new MyView { DataContext = new MyViewModel() };
Let MvvmCross construct your MvxViewController by doing this:
var viewController = this.CreateViewControllerFor<MyViewModel>();
CreateViewController is an extensions method for IMvxCanCreateTouchView, so the class where you do your view construction should be implementing that Inteface, otherwise that method will not be available.
I know IMvxCanCreateTouchView is implemented by MvxTouchViewPresenter and MvxViewController so you can call that method from your Presenter or from another MxvViewController.

Reference UIViewController within ContainerView

I have created a ContainerView in Xamarin, which automatically created a new ViewController.
I have created the class for this called Test1ViewController:
using System;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace test1
{
public partial class Test2ViewController : UIViewController
{
public Test2ViewController (IntPtr handle) : base (handle)
{
}
}
}
I am trying to reference this view controller in the ViewDidLoad() method of the main view controller. However if I put the following:
Test2ViewController.PresentViewController(picker, true, null);
I get a static error message, which makes sense as I am trying to reference the class not the specific object. Am I missing something, how do I reference the UIViewController in the ContainerView from the parent UIViewController?
What I am trying to achieve, is including the Scandit Barcode scanner within the container view:
// Setup the barcode scanner
var picker = new ScanditSDK.SIBarcodePicker ("API-KEY");
picker.OverlayController.Delegate = new BarcodeScanner ();
Test2ViewController.PresentViewController(picker, true, null);
picker.StartScanning ();
Assuming that variable picker is supposed to represent a Test2ViewController instance:
public override void ViewDidLoad()
{
base.ViewDidLoad();
this.picker = new Test2ViewController();
this.PresentViewController(picker, true, null);
}

MonoTouch Instantiating a ViewController programmatically for ContainerView

I am trying to work with a container view in MonoTouch and I am following some tutorials online. They talk about adding and removing view controller programmatically from the container. I created a viewcontroller and view in the storyboard of my project and attached a few outlets and one action (for labels and buttons respectively). I created an overloaded construc
Here is the code in the view controller that I am trying to add viewControllers into the container view.
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
ContainerView.AutoresizingMask = UIViewAutoresizing.FlexibleHeight;
_controllerOne = new IngredientsController("Perishables");
_controllerTwo = new IngredientsController("Spices");
AddChildViewController(_controllerOne);
ContainerView.AddSubview(_controllerOne.View);
_controllerOne.DidMoveToParentViewController(this)
}
When I add the subview for _controllerOne I get an error because the elements on my controller are marked null. Is MonoTouch incapable of having view controllers being programmatically created if the controller was made in Interface Builder? Below are the two constructors for the Ingredient Controller. When the segue is used then all of the UI controls are initialized properly. Do I need to create the controller programmatically and then instantiate it that way? Any help would be appreciated.
//This ctor does not work
public IngredientsController (string title) : base(NSObjectFlag.Empty)
{
_ingredientTitle = title;
}
//This ctor works
public IngredientsController (IntPtr handle) : base (handle)
{
}
Try to swap the AddSubView() and DidMoveToParentViewController() methods like below:
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
ContainerView.AutoresizingMask = UIViewAutoresizing.FlexibleHeight;
_controllerOne = new IngredientsController("Perishables");
_controllerTwo = new IngredientsController("Spices");
this.AddChildViewController(_controllerOne); // Root child controller.
_controllerOne.DidMoveToParentViewController(this); // Confirm the rooting.
ContainerView.AddSubview(_controllerOne.View); // Access the view.
}
Try instantiating the view controller like this:
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
this.ContainerView.AutoresizingMask = UIViewAutoresizing.FlexibleHeight;
var newController = this.Storyboard.InstantiateViewController("IngredientsController");
this.AddChildViewController (newController);
this.ContainerView.AddSubview (mapController.View);
}
Make sure you set the Storyboard Id in the properties panel for the ViewController

How to set the background color on a DialogViewController (Monotouch.Dialog)

environment: creating an iPad application using Monotouch and the Monotouch.Dialog library.
I've been trying to set the background color on a DialogViewController to no avail. I have multiple views in my application being loaded an unloaded. For non of them I manage to set the background color.
What I have tried so far:
Set the background color on the main window of my application --> works fine.
Create a simple UIView, give it a size, set the background color and load it into the window --> works fine.
But as soon as I load a DialogViewController (with an associated view) the background color is always gray. The DialogViewController is used from the Monotouch.Dialog framework.
I'm pushing the DialogViewController onto a navigation controller to show a set of buttons laid out in a table view.
I must be missing out on something fundamental ! I have been looking through the Monotouch.Dialog code and tried a couple of other things, but nothing fixed my problem so far.
Any help highly appreciated.
boris
You actually need to set the background view to null. This is the view that is behind a table view, such as the grouped one in MonoTouch.Dialog
http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableView_Class/Reference/Reference.html
Here is what a subclass for this might look like:
using System;
using System.Drawing;
using System.IO;
using MonoTouch.Foundation;
using MonoTouch.CoreGraphics;
using MonoTouch.Dialog;
using MonoTouch.UIKit;
namespace MyNameSpace{
public class MySpecialDialogViewController : DialogViewController {
public MySpecialDialogViewController (UITableViewStyle style, RootElement root)
: base (style, root)
{
}
public override void LoadView ()
{
base.LoadView ();
TableView.BackgroundView = null;
TableView.BackgroundColor = UIColor.Black;
}
}
}
This is described in the section "Customizing the DialogViewController" in the MonoTouch.Dialog documentation.
You need to subclass DialogViewController, like this:
public class ColoredViewController : DialogViewController {
[...]
public override LoadView ()
{
base.LoadView ();
TableView.BackgroundColor = UIColor.Clear;
ParentViewController.View.BackgroundColor = UIColor.Red;
}
}
Yes Eric's solution works now. I modified his below if you would like to use an image instead of a color.
public override void LoadView ()
{
base.LoadView ();
this.TableView.BackgroundView = null;
//this.TableView.BackgroundColor = UIColor.Black;
var background = UIImage.FromFile ("Images/down.png");
this.TableView.BackgroundColor = UIColor.FromPatternImage(background);
}
I find the pattern gets duplicated when using the other solutions and so setting the backgroundview is more preferable for me like so:
public override void LoadView ()
{
base.LoadView ();
UIImage tickImage = UIImage.FromBundle ("1.jpg");
UIImageView backgroundImageView = new UIImageView (this.View.Bounds);
backgroundImageView.Image = tickImage;
backgroundImageView.ContentMode = UIViewContentMode.BottomLeft; //your preference
TableView.BackgroundView = backgroundImageView;
}

In MonoTouch, how do I assign a custom view to my view controller?

If I want to use a custom view object with my view controller, instead of just using the one that's initialized by default, can I just assign it to the view controller's View property. For example, is the following the correct/safe approach?
public class MyView : UIView
{
}
public class MyController : UIViewController
{
// Constructors.
public MyController()
{
View = new MyView();
}
}
Seems to work in a simple test, but I don't want to be introducing any time-bombs.
Or, should I be adding my custom view as a subview of the existing view in ViewDidLoad?
You should be adding the custom views as subviews.
public class MyView : UIView
{
}
public class MyController : UIViewController
{
public override void ViewDidLoad()
{
var myView = new MyView();
this.View.AddSubview(myView);
}
}

Resources