Monotouch.Dialog: IElementSizing not being used - xamarin.ios

I have a Custom element class that only resizes the rows when I rotate the device. On initial display the rows are not resized.
public class MultiImageElement : Element, IElementSizing
Which implements the IElementSizing interface:
#region IElementSizing implementation
public float GetHeight (UITableView tableView, NSIndexPath indexPath)
{
return 78;
}
#endregion
However, this is never called and the row heights remain the default size.
I add elements to my root in a loop:
for (int i = 0; i < secFolder.Rows; i++)
{
sec.Add (new MultiImageElement (secFolder.ThumbnailPathsForRow (i), imageSize));
}
this.Root.Add (sec);

I found the solution.
To have Monotouch.Dialog implement the IElementSizing, the Sections and Elements must be added to a local "myRoot" variable.
After it's been built out, then set the Dialog's Root to that.
var myRoot = new Root();
MakeElements()
this.Root = myRoot;
This works.

Another solution is custom DialogViewController and then setup Root.UevenRows to true:
public class CustomViewController : DialogViewController
{
public CustomViewController (RootElement root) : base(root)
{
Root.UnevenRows = true;
...
}
...
}

Might not be related, but happened to me that the initial rotate device event was not fired to me. So I implemented the flag and initiated a scheduled selector to be called upon app start to ensure the ShouldAutorotate... was called and performed the Layout for me if needed.

Related

push a view controller from selecting a row in a table view

So I have a UITableView where I want to push to a details controller when the row is selected.
My attempt was to:
public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
{
var controller = new BlogDetailViewController();
navController.PushViewController(controller, true);
tableView.DeselectRow (indexPath, true);
}
But I am getting the complaint that BlogDetailViewController() takes an argument.
My BlogDetailViewController:
public partial class BlogDetailViewController : UIViewController
{
public string blogTitle;
public BlogDetailViewController (IntPtr handle) : base (handle)
{
}
}
What is Intptr handle and how do I pass it in? I tried adding a zero argument constructor and pushing to that, but when I ran the app it pushed to a black screen.
If you're instantiating it from a XIB, I believe you want to use
UIStoryboard board = UIStoryboard.FromName ("name", null);
UIViewController ctrl = (UIViewController)board.InstantiateViewController ("name");
UIApplication.SharedApplication.KeyWindow.RootViewController = view;
add this line also in last

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!

Monotouch Dialog Custom Element and GetHeight not being called

Using Monotouch 5.2.11 iOS
I have followed this tutorial (http://tirania.org/monomac/archive/2011/Jan-18.html), created a custom cell with an image and have also added the IElementSizing Interface. The GetHeight is never called.
Similar questions have been asked and the generally accepted solution was to make sure and create the RootElements first, set the UnEvenRows=true before adding them to the Controller. This did not work. I've tried that as well as about every other combination of adding sections to root elements and have not ever seen the GetHeight fired.
The MyDataElement is an image that is 320x200 which displays fine, but the string element that comes after it is not shown (assuming it is behind it). Consequently if I drag the custom cell up above the top, it disappears, reappears, and the second stringelement displays on top of it.
Here is the code I've tried:
public class MyDataElement : Element, IElementSizing {
static NSString key = new NSString ("myDataElement");
public MyData MyData;
public MyDataElement (MyData myData) : base (null)
{
MyData = myData;
}
public float GetHeight (UITableView tableView, NSIndexPath indexPath){
return 200f; // break point here is never hit ever
}
public override UITableViewCell GetCell (UITableView tv)
{
var cell = tv.DequeueReusableCell (key) as MyDataCell;
if (cell == null)
cell = new MyDataCell (MyData, key);
else
cell.UpdateCell (MyData);
return cell;
}
public partial class TableTester : DialogViewController
{
public TableTester () : base (UITableViewStyle.Grouped, null)
{
var re = new RootElement("Sample") {
new Section("Testy") {
new MyDataElement(new MyData() { stuff="hello"}),
new StringElement("Sample")
}
};
re.UnevenRows = true;
this.Root = re;
//this.Root = root;
}
}
In addition to that I've even done this which didn't work either:
public class TestNavigator : UINavigationController {
public TestNavigator() {
TabBarItem = new UITabBarItem("Test", null, 1);
var re = new RootElement("Sample") {
new Section("Sammy") {
new StringElement("Sample"),
new MyDataElement(new MyData() { stuff="sam"}),
new StringElement("Sample 2")
}
};
re.UnevenRows = true;
var dv = new DialogViewController(re);
re.UnevenRows = true;
PushViewController(dv, true);
}
After plenty of trial and error, I had to make sure and remove the reference to Monotouch.Dialog that I had downloaded from github and use the built in reference. It seems that the getheight maybe broken in github.

dynamically change image in ImageStringElement as part of monotouch.dialog

My problem is as follows:
I am creating a section with a number of ImageStringElements that when selected an audio file will play, e.g.
Section s = new Section();
foreach (var idea in ideas)
{
s.Add(new ImageStringElement(idea.Id, delegate {ElementTapped();}, playImage));
}
Now when one of the elements is tapped, I would like to change the playImage to another one, i.e. PauseImage. Then again, when is it selected it changes back to the PlayImage. Not sure how to do this in the ElementTapped() method. Basically I would like to have a similar functionality as in the voice memos app.
You can subclass ImageStringElement and make two changes:
Add:
class FlippingImageElement : ImageStringElement
{
UIImage currentImage;
UITableViewCell currentCell;
public FlippingImageElement (string caption, UIImage image) : base (caption, image)
{
currentImage = image;
}
public override UITableViewCell GetCell (UITableView tv)
{
var cell = base.GetCell (tv);
cell.ImageView.Image = currentImage;
currentCell = cell;
}
public void SetImage (UIImage image)
{
currentImage = image;
if (currentCell != null)
currentCell.ImageView.Image = currentImage;
}
}
Use this new element instead of the MonoTouch.Dialog one, and call the SetImage API to change the image

How to use QLPreviewController in a non-modal way? Why does my code not work?

I have QLPreviewController up and running but I'm using PresentModalViewController() to show the QLPreviewController directly. For reasons beyond explanation, I would like to have my own UIViewController which will create its own view and within that view I would like to use the QLPreviewController. Should be easy I thought, but the code below just does nothing. The QLPreviewControllers ViewDidAppear never gets called. (In my example below, PreviewController inherits from QLPreviewController and encapsulates delegate, preview item and source).
Can somebody explain what is wrong with the code below (besides the fact that it is pointless :-))?
Oh, yeah: in my test scenario, I present the controller below modally. It shows up but witout the preview.
public class OuterPreviewController : UIViewController
{
public OuterPreviewController (QLPreviewControllerDataSource oDataSource) : base()
{
this.oDataSource = oDataSource;
}
private PreviewController oPreviewController;
private QLPreviewControllerDataSource oDataSource;
public override void LoadView ()
{
this.View = new UIView();
this.View.Frame = new RectangleF(0, 0, 500, 500);
this.View.BackgroundColor = UIColor.Red;
}
public override void ViewDidAppear (bool animated)
{
// Code execution comes her. No errors, no issues.
base.ViewDidAppear (animated);
this.oPreviewController = new PreviewController();
this.oPreviewController.DataSource = this.oDataSource;
// Preview controller's view is added but it never shows up.
this.View.AddSubview(this.oPreviewController.View);
this.oPreviewController.View.Frame = this.View.Frame;
this.oPreviewController.View.Center = this.View.Center;
}
public override bool ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation)
{
return true;
}
}
Found a solution by coincidence today: all ReloadData() on the preview controller and magically it will show its contents.
This allows to add a QLPreviewController to an existing view as a subview and embed a preview. It also gets you rid of the toolbar which contains the open in menu.

Resources