Monotouch - Twitter/Path Application Master-Detail Swipe Table View - xamarin.ios

Any clue on how to create the twitter ipad application or path application swipe master-detail table view effect using MonoTouch?

Our good friend Clancey has a C# port of what is called "FlyOutNavigation" on Github. It works on both iPhone and iPad. However he has a custom MonoTouch.Dialog project which is not included in the repo. So I created a custom DialogViewController implementation you can just drop in (see below).
Code: https://github.com/Clancey/FlyOutNavigation
Custom DialogViewController:
public class NavigationDvc : DialogViewController
{
public Action<NSIndexPath> OnSelection { get; set; }
public NavigationDvc(UITableViewStyle style, RootElement root)
: base(style, root)
{
}
public override void Selected(NSIndexPath indexPath)
{
base.Selected(indexPath);
if(OnSelection != null) {
OnSelection(indexPath);
}
}
}

Related

Xamarin ios: loaded the nib but the view outlet was not set

I’m new in xamarin ios and I need to add view in existing project. Project use mvvmcross framework.
I’ve done:
Created PerevozkiViewModelClass :MvxViewModel in Core project
Add UI View controller with storydoard (P.S. BaseView extends MvxViewController)
public partial class PerevozkiView : BaseView
{
public PerevozkiView() : base("PerevozkiView", null)
{
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
var set = this.CreateBindingSet<PerevozkiView, PerevozkiViewModel>();
set.Apply();
}
}
Delete PerevozkiView.Storyboard
4.Add PerevozkiView.xib and in file owner specify PerevozkiView (I cant choose it from list, so I just hardcode “PerevozkiView as file owner)
After deploy in IOS simulator I’ve got exception:
Foundation.MonoTouchException
Сообщение = Objective-C exception thrown. Name: NSInternalInconsistencyException Reason: -[UIViewController _loadViewFromNibNamed:bundle:] loaded the "PerevozkiView" nib but the view outlet was not set here in Main:
public class Application
{
// This is the main entry point of the application.
static void Main(string[] args)
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main(args, null, "AppDelegate");
}
}
I have no idea what is wrong. Pls help

Change the navigation to come from bottom to top in MvvmCross in iOS + Xamarin

I am using MvvmCross and using ShowViewModel to navigate between view. It takes the default navigation behavior i.e., slides from Right->Left . I want few view controllers to slide from bottom to top . Can someone let me know how we can do this in MvvmCross. These are not overlays but regular view controllers.
You can achieve this by setting a custom delegate for your Navigation Controller. This can be done by override following method in your custom ViewPresenter
protected override void OnMasterNavigationControllerCreated()
{
this.MasterNavigationController.WeakDelegate = new NavigationControllerDelegate();
}
Within this delegate you can set your transitions, e.g.:
public class NavigationControllerDelegate : UINavigationControllerDelegate
{
public override IUIViewControllerAnimatedTransitioning GetAnimationControllerForOperation(UINavigationController navigationController, UINavigationControllerOperation operation, UIViewController fromViewController, UIViewController toViewController)
{
if (operation == UINavigationControllerOperation.Push)
{
if (fromViewController is MenuViewController)
{
return new BottomToTopTransition();
}
...
}
}
}
BottomToTopTransition is also a custom class and inherits from UIViewControllerAnimatedTransitioning. Last step is to override AnimateTransition() in this transition class and you are done.

Integrating third party controller with MVVMCross on MonoTouch

I want to use a third party view controller that already inherits from UIViewController (https://bitbucket.org/thedillonb/monotouch.slideoutnavigation/src/f4e51488598b/MonoTouch.SlideoutNavigation?at=master), how would I integrate that with MVVMCross?
I could just take the source and change it to inherit from MvxViewController, but guessing I will run into this with other libraries.
Do I need to implement all the interfaces MvxViewController does? IMvxTouchView? IMvxEventSourceViewController?
For this particular case, where you don't actually want to do any data-binding so you can just use a custom presenter - e.g. see #Blounty's answer, or see this project demo - https://github.com/fcaico/MvxSlidingPanels.Touch
If you ever do need to convert third party ViewController base classes so that they support data-binding, then the easiest way is exactly what you guessed:
inherit from them to provide an EventSource-ViewController
inherit from the EventSource-ViewController to add the Mvx BindingContext
This technique is exactly how MvvmCross itself extends each of UIViewController, UITableViewController, UITabBarController, etc in order to provide data-binding.
For example, see:
extending UIViewController to provide an eventsource - MvxEventSourceViewController.cs
extending the event source ViewController to provide a binding context - MvxViewController.cs
Note that because C# doesn't have any Multiple-Inhertiance or any true Mixin support, this adaption of ViewControllers does involve a little cut-and-paste, but we have tried to minimise this through the use of event hooks and extension methods.
If it helps, this iOS technique for a previous MvvmCross version was discussed in Integrating Google Mobile Analytics with MVVMCross (obviously this is out of date now - but the general principles kind of remain the same - we adapt an existing viewcontroller via inheritance)
In Android, a similar process is also followed for Activity base classes - see ActionBarSherlock with latest MVVMCross
You can use a custom view presenter like below, This is pretty much straight out of my app using the SlideOutNavigation.
public class Presenter
: IMvxTouchViewPresenter
{
private readonly MvxApplicationDelegate applicationDelegate;
private readonly UIWindow window;
private SlideoutNavigationController slideNavigationController;
private IMvxTouchViewCreator viewCreator;
public Presenter(MvxApplicationDelegate applicationDelegate, UIWindow window)
{
this.applicationDelegate = applicationDelegate;
this.window = window;
this.slideNavigationController = new SlideoutNavigationController();
this.slideNavigationController.SlideWidth = 200f;
this.window.RootViewController = this.slideNavigationController;
}
public async void Show(MvxViewModelRequest request)
{
var creator = Mvx.Resolve<IMvxTouchViewCreator>();
if (this.slideNavigationController.MenuView == null)
{
// TODO: MAke this not be sucky
this.slideNavigationController.MenuView = (MenuView)creator.CreateView(new MenuViewModel());
((MenuView) this.slideNavigationController.MenuView).MenuItemSelectedAction = this.MenuItemSelected;
}
var view = creator.CreateView(request);
this.slideNavigationController.TopView = (UIViewController)view;
}
public void ChangePresentation(MvxPresentationHint hint)
{
Console.WriteLine("Change Presentation Requested");
}
public bool PresentModalViewController(UIViewController controller, bool animated)
{
Console.WriteLine("Present View Controller Requested");
return true;
}
public void NativeModalViewControllerDisappearedOnItsOwn()
{
Console.WriteLine("NativeModalViewControllerDisappearedOnItsOwn");
}
private void MenuItemSelected(string targetType, string objectId)
{
var type = Type.GetType(string.Format("App.Core.ViewModels.{0}ViewModel, AppCore", targetType));
var parameters = new Dictionary<string, string>();
parameters.Add("objectId", objectId);
this.Show(new MvxViewModelRequest { ViewModelType = type, ParameterValues = parameters });
}
}

How do I prevent a single UIViewContoller from rotating in Monotouch? (All other views can rotate)

I have an iPhone app that supports all orientations but in one UIViewController I only want to support portrait (or upside down).
I have added the following code to my UIViewController but it still rotates.
public override bool ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation)
{
// Return true for supported orientations
return ((toInterfaceOrientation != UIInterfaceOrientation.LandscapeLeft) && (toInterfaceOrientation != UIInterfaceOrientation.LandscapeRight));
}
No matter where I add the ShouldAutorotateToInterfaceOrientation code it still rotates!
Is there a way to allow the app to support all orientations for all UIViewControllers except one?
Also i am using a NavigationController - does that affect things?
if you use iOS 6 you must override GetSupportedInterfaceOrientations method instead ShouldAutorotateToInterfaceOrientation
public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations()
{ ... }
Probably this happens because your root navigation controller brings it own rotation. Lets assume that your root navigation controller is a normal UINavigationViewController. Create a derived own version:
public class UINavigationControllerWithoutRotation : UINavigationController
{
public UINavigationControllerWithoutRotation()
{
}
public UINavigationControllerWithoutRotation(UIViewController viewController) : base(viewController)
{
}
public override bool ShouldAutorotate()
{
return false;
}
}
Now use this as the root controller. Find the code saying something like:
var myRootController = new UINavigationController();
and replace it with
var myRootController = new UINavigationControllerWithoutRotation();
That should do the job. Keep in mind, that you have to do it a little bit different if for instance your root view controller is a UITabBarController!

Display a new view from within a custom control

I have a custom button which inherits from UIButton. I'm handling the TouchUpInside event and want to display a view on top of the current View. Is there such a thing as Dialogs like in Windows development? Or should I do this in another way?
[MonoTouch.Foundation.Register("HRPicker")]
public class HRPicker : UIButton
{
public HRPicker () : base()
{
SetUp();
}
public HRPicker(NSCoder coder) : base(coder)
{
SetUp();
}
public HRPicker(NSObjectFlag t) : base(t)
{
SetUp();
}
public HRPicker(IntPtr handle) : base(handle)
{
SetUp();
}
public HRPicker(RectangleF frame) : base(frame)
{
SetUp();
}
public void SetUp()
{
TouchUpInside += HandleTouchUpInside;
}
void HandleTouchUpInside (object sender, EventArgs e)
{
//I want to display a View here on top of the current one.
}
}
Thanks,
Yes, you have a couple options:
ModalViewController - is called from any UIViewController and overlays a ViewController in the foreground.
UIPopoverController - is a native control that takes a UIViewController and has hooks for presentation and dismissal
WEPopoverController - is a re-implementation of UIPopoverController and allows you to customize the layout, size, and color of the Popover container.
ModalViewController: http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html
UIPopoverController: http://developer.apple.com/library/ios/#documentation/uikit/reference/UIPopoverController_class/Reference/Reference.html
WEPopoverController: https://github.com/mono/monotouch-bindings/tree/master/WEPopover
Update: Regardless of which option you use you must call the presentation of the Popover / Modal view from the main thread:
using(var pool = new NSAutoReleasePool()) {
pool.BeginInvokeOnMainThread(()=>{
// Run your awesome code on the
// main thread here, dawg.
});
}
The equivalent of dialog in Cocoa is UIAlertView: http://developer.apple.com/library/ios/#documentation/uikit/reference/UIAlertView_Class/UIAlertView/UIAlertView.html
Check out this question for an example of how to use it: Showing an alert with Cocoa
The code should be pretty easy to translate to c# and MonoTouch. But here is a simple example: http://monotouchexamples.com/#19

Resources