Thursday, 09 February 2012

Touch4Apps Blog | posts about iPhone : iPad : iPod app development

While back I wrote an post about perform selector helper with pure delegates and a helper class. I then changed it a bit to use NSAction for easier use. So here it is:

 

namespace MonoTouch.Foundation.Extensions
{
	public static class CoreFoundationExtensions
	{
		public static void PerformSelector (this NSObject obj, NSAction action, float delay)
		{
			int d = (int)(1000 * delay);
 
			var thread = new Thread(new ThreadStart ( () => {
				using(var pool = new NSAutoreleasePool())
    				{
						Thread.Sleep (d); 
						action.Invoke ();
    				}
			 }));			
 
			thread.IsBackground = true;
			thread.Start();
		}
 
		public static void PerformSelector (this NSObject obj, NSAction action)
		{
			PerformSelector (obj, action, 0.001f);
		}
	}
}

 

Happy coding!

 

Tags , , , ,
AddThis Social Bookmark Button

New Twitter client for iPhone has a specific UI element that is utterly disruptive and annoying. Should you wish to annoy users of you application written in Monotouch, please feel free to use this port of original UIDickBar from Git hub: UIDickBar

And the most important part, download the Monotouch port here.

Control itself is coded as subclass of UIControl with custom drawing using Draw override and CGContext and so on, so a nice sample of how to use such approach.

To use it in you code simply call:

 

dickBar = new touch4apps.UIDickBar.Controls.UIDickBar ("Dick title", "Dick badge");
dickBar.DickBarAction += HandleDickBarDickBarAction;
dickBar.ShowInView (this.View);

 


Enjoy and happy coding!

Tags , , , , ,
AddThis Social Bookmark Button

When you have problems with UIBarButtonItem receiving tap events when the main View has UITapGestureRecognizer, it might be because you have UIToolbar and the actual UITapGestureRecognizer added to the same View. Then the recognizer receives all the tap events even those on the UIBarButtonItems.

Ensure you handle the ShouldReceiveTouch accordingly and do not return true if the tap is on the UIBarButtonItem. This is how I handle it:

 

public class TapGestureRecognizerDelegate : UIGestureRecognizerDelegate
{
	public UITouch ActiveTouch { get; set; }
 
	public override bool ShouldReceiveTouch (UIGestureRecognizer recognizer, UITouch touch)
	{
		if (touch.View.Superview is UIToolbar)
			return false;
 
		ActiveTouch = touch;
 
		return true;
	}
}

 

Happy coding!

 

Tags , , , , ,
AddThis Social Bookmark Button

When working on our next app, we found us in a situation where we have lots of graphics in some size and need to present it on the screen in several scaled versions.

The issue is, that graphics can be prepared for each of the sizes needed, but then, it will be redundant. Or find a way how to scale it in the code for the next drawing part.

And of course, there is a coding solution (how else? :-)). The trick is to draw the image to the context created for the screen, so it is properly sized, nice feature out of the box in iOS is that it will do the retina fine tuning automatically. We just need to draw it.

 

public static class UIImageHelper
{
	public static UIImage FromFile (string filename, SizeF fitSize)
	{
		var imageFile = UIImage.FromFile (filename);
 
		return imageFile.ImageToFitSize(fitSize);
	}
 
	public static UIImage ImageToFitSize (this UIImage image, SizeF fitSize)
	{
  	    double imageScaleFactor = 1.0;
	    imageScaleFactor = image.CurrentScale;
 
	    double sourceWidth = image.Size.Width * imageScaleFactor;
	    double sourceHeight = image.Size.Height * imageScaleFactor;
	    double targetWidth = fitSize.Width;
	    double targetHeight = fitSize.Height;
 
	    double sourceRatio = sourceWidth / sourceHeight;
	    double targetRatio = targetWidth / targetHeight;
 
	    bool scaleWidth = (sourceRatio <= targetRatio);
	    scaleWidth = !scaleWidth;
 
	    double scalingFactor, scaledWidth, scaledHeight;
 
	    if (scaleWidth) 
	    {
	        scalingFactor = 1.0 / sourceRatio;
	        scaledWidth = targetWidth;
	        scaledHeight = Math.Round (targetWidth * scalingFactor);
	    } 
	else 
	{
	        scalingFactor = sourceRatio;
	        scaledWidth = Math.Round(targetHeight * scalingFactor);
		scaledHeight = targetHeight;
	}
 
		RectangleF destRect = new RectangleF(0, 0, (float)scaledWidth, (float)scaledHeight);
 
		UIGraphics.BeginImageContextWithOptions(destRect.Size, false, 0.0f);
		image.Draw (destRect); 
		UIImage newImage = UIGraphics.GetImageFromCurrentImageContext ();
		UIGraphics.EndImageContext ();
 
		return newImage;
	}
}

 

Happy coding!

 

Tags , , , , ,
AddThis Social Bookmark Button

For one of our app we needed drawing technique that would delete the image in graphics context based on the user input and act like a erase rubber.

Of course there is again everything needed in MonoTouch to do the job.

Tags ,
AddThis Social Bookmark Button

Objective C sure is nice and powerful, but don't you just love stuff like:

 

this.NavigationItem.RightBarButtonItem = new UIBarButtonItem("Close", UIBarButtonItemStyle.Done, (s, e) => popoverContent.DismissModalViewControllerAnimated(true));

 

(Inside UIViewController class that is being presented in UINavigationController)

Happy coding!

 

AddThis Social Bookmark Button

Just came across a problem to have UITableViewController on a custom texture, wanted and needed to have the nice rounded corners as well and found out it is not that straightforward to set the background color to transparent in case that running on iPad (3.2 and 4.2 as well).

So here is a little code snippet that does the trick.

 

// create the UITableViewController
SettingTableViewController tableController = new SettingTableViewController(UITableViewStyle.Grouped);
 
// set its color to transparent as well, as this is needed, this is the first layer of the setup
tableController.View.BackgroundColor = UIColor.Clear;
tableController.View.Frame = new RectangleF(12, 101, 280, 98);
 
// create a dummy view for the underlaying view			
UIView view = new UIView();
view.Frame = tableController.View.Frame;
 
// make its color transparent as well
view.BackgroundColor = UIColor.Clear;
 
// and now the little trick, get to the core of the view hierarchy and set the view from the original UIImageView, in which the UITableView of the controller lays, to our custom transparent view
((UITableView)tableController.View).BackgroundView = view;
 
 

 

Happy coding!

 

AddThis Social Bookmark Button

One of the clients wanted in the app a little feature for a menu system, something like a karusel, where specific menu items will be scrolled from side to side with a touch in an infinite loop.

I found out that it can be possible to do with a simple tweak to UIScrollView, handing the

scrollViewDidEndDecelerating from the UIScrollViewDelegate.

 

Guys from Monotouch team made the great job on this (as usual) and we have the delegate already available via built-in events, in this case DecelerationEnded.

So lets have a look at the implementation of the UIViewController class of some view, note we are adding the UI from the code, not from the nib file, just for simplicity. View has UIScrollView item and loads some images, last image is placed as the first one, then all images in the order and then first image as the last one.

Then the event for DecelerationEnded is handled to actually swap the position (fast - no animation) so user does not find out. For added more touch, the paging is enabled and of course the scroller is hidden, so it is not visible to the user where in the scrolling position he actually is.

AddThis Social Bookmark Button

If you ever needed to set the status bar hidden in Monotouch App, and wanted to do it properly for code that runs backward compatible on OS 3.X while developing on iOS SDK 4.X and also for newer devices, here is the answer:

 

if (UIApplication.SharedApplication.RespondsToSelector (new Selector ("setStatusBarHidden: withAnimation:")))
	UIApplication.SharedApplication.SetStatusBarHidden (true, UIStatusBarAnimation.Fade);
else
	UIApplication.SharedApplication.SetStatusBarHidden (true, true);
 

 


 

 

AddThis Social Bookmark Button

Few weeks ago I wrote a post about how to handle tap gesture on iOS prior gesture recognizers. In Objective-C there is simple trick with [self.nextResponder ...] and then [NSObject cancelPreviousPerformRequestWithTarget ...].

In MonoTouch NextResponder on Controller object is read only for some reason, and therefore cannot be used to implement this technique in a simple way. So a bit more coding is needed.

AddThis Social Bookmark Button