MonoTouch

Monoの技術を使って、C#と.NETでiOSアプリが開発出来るソリューションの「MonoTouch」です。

元々、Novell社から製品として販売されていたパッケージなのですが、紆余曲折あったらしく現在はXamarin社が製品の権利を持ち、販売サポートを行っています。

プレビュー版の時代の話で、少し情報は古めなのですが日本語の情報でとっかかりとしてオススメなエントリは「C#でiPhone開発!MonoTouch Beta ファーストインプレッション – backyard of 伊勢的新常識」です。

いざプログラミングを書こうと思った時に、右も左も判らない状態では何も出来ません。Tutorials – MonoTouch」にてチュートリアルが公開されています。一通りの実装が出来る様になると思います。サンプルアプリが公式サイト上で配布されていますので、そちらも合わせてどうぞ。

Logging

var myString = "MyString";
var myFloat = 4.56f;
var myInt = 5;
Console.WriteLine(String.Format("log: {0}", myString));	
Console.WriteLine(String.Format("log: {0}", myFloat));	
Console.WriteLine(String.Format("log: {0}", myInt));

Display Images

UI Builderを使用せずに、スクリーン上にイメージを表示させる方法です。

var imageRect = new RectangleF(0f, 0f, 320f, 109f); 
using (var myImage = new UIImageView(imageRect))
{	
	myImage.Image = UIImage.FromFile("myImage.png");
	myImage.Opaque = true;
	view.AddSubview(myImage);
}

Web View

UIWebViewの基本的な使い方です。

var imageRect = new RectangleF(0f, 0f, 320f, 109f); 
using (var myImage = new UIImageView(imageRect))
{	
	myImage.Image = UIImage.FromFile("myImage.png");
	myImage.Opaque = true;
	view.AddSubview(myImage);
}

Display Network Indicator

インジゲータを表示します。NetworkActivityIndicatorVisibleプロパティをtrueに設定すると表示し、falseを設定すると非表示になります。

var app = UIApplication.SharedApplication;
app.NetworkActivityIndicatorVisible = true;

アニメーション: パラパラアニメ

List<UIImage> myImages = new List<UIImage>();
myImages.Add(UIImage.FromFile("myImage1.png"));
myImages.Add(UIImage.FromFile("myImage2.png"));
myImages.Add(UIImage.FromFile("myImage3.png"));
myImages.Add(UIImage.FromFile("myImage4.png"));
 
var myAnimatedView = new UIImageView(view.Bounds);
myAnimatedView.AnimationImages = myImages.ToArray();
myAnimatedView.AnimationDuration = 1.75; // Seconds
myAnimatedView.AnimationRepeatCount = 0; // 0 = Loops Forever
myAnimatedView.StartAnimating();
view.AddSubview(myAnimatedView);

アニメーション: オブジェクトの移動

var theAnimation = CABasicAnimation.FromKeyPath("transform.translation.x");
theAnimation.Duration = 1;
theAnimation.From = NSNumber.FromFloat(0f);
theAnimation.To = NSNumber.FromFloat(-60f);
exampleLabel.Layer.AddAnimation(theAnimation, "animateLabel");

Int型をString型に変換して表示する

var currentInt = 5;
exampleLabel.Text = String.Format("Int = {0}", currentInt);

正規表現(RegEx)

var emailRegex = @"^([0-9a-zA-Z]([-\.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$";
var realEmail = "my@email.com";
var fakeEmail = "notAEmailAddress.com";
var formatString = "{0} is a real e-mail = {1}";
Console.WriteLine ((String.Format(formatString, realEmail, Regex.IsMatch(realEmail, emailRegex))));			
Console.WriteLine ((String.Format(formatString, fakeEmail, Regex.IsMatch(fakeEmail, emailRegex))));

Draggable Items

public class MyDraggableImage : UIImageView
{
	public MyDraggableImage(RectangleF frame) : base(frame)
	{
	}
 
	public PointF StartLocation { get; set; }
}
public override void TouchesBegan (NSSet touches, UIEvent evt)
{
	var pt = (touches.AnyObject as UITouch).LocationInView(this);
	StartLocation = pt;
	this.Superview.BringSubviewToFront(this);
}
 
public override void TouchesMoved (NSSet touches, UIEvent evt)
{
	// Move relative to the original touch point 
	var pt = (touches.AnyObject as UITouch).LocationInView(this);
	var frame = this.Frame;
	frame.X += pt.X - StartLocation.X;
	frame.Y += pt.Y - StartLocation.Y;
	this.Frame = frame;
}
 
public override void TouchesEnded (NSSet touches, UIEvent evt)
{
	// Move relative to the original touch point 
	var pt = (touches.AnyObject as UITouch).LocationInView(this);
	var frame = this.Frame;
	frame.X += pt.X - StartLocation.X;
	frame.Y += pt.Y - StartLocation.Y;
	this.Frame = frame;
}
var image = UIImage.FromFile("myImage.png");
var draggableRect = new RectangleF(0f, 0f, image.Size.Width, image.Size.Height);
var dragger = new MyDraggableImage(draggableRect);
dragger.Image = image;
dragger.UserInteractionEnabled = true;
view.AddSubview(dragger);

Vibrate and Sound

SystemSound.Vibrate.PlaySystemSound();
var sound = new SystemSound(new NSUrl("audioFile.caf"));
sound.PlaySystemSound();

スレッド

新しいスレッドを作ります。

var thread = new Thread(NewThreadMethod as ThreadStart);
thread.Start();

新しいスレッドがから呼び出されるメソッドを作ります。

[Export("NewThreadMethod")]
void NewThreadMethod()
{
	using(var pool = new NSAutoreleasePool())
	{
		// Run code in new thread
	}
}

メインスレッド以外からUIのコントロールを更新したりすることが出来ません。新しいスレッドからUIを更新したい場合は、InvokeOnMainThreadを使用します。

InvokeOnMainThread( delegate {
	// Update UI Code (in Main thread) from the new thread.	
});

Access properties/methods in other classes

var appDelegate = (AppDelegate) UIApplication.SharedApplication.Delegate;
appDelegate.view.BackgroundColor = UIColor.Green;

乱数

Random r = new Random();
var randomNumber = r.Next();

Timers

var timer = NSTimer.CreateRepeatingScheduledTimer(TimeSpan.FromSeconds(1), OneSecondTimer);
var userInfo = new NSString("MyUserInfo");
var timer = NSTimer.CreateScheduledTimer(1, this, new Selector("OneSecondTimer"), userInfo, true);
[Export("OneSecondTimer")]
void OneSecondTimer(NSTimer timer)
{
	var userInfoString = timer.UserInfo.ToString();	
}

タイマーをストップさせる場合は、Invalidateメソッドを使用します。

timer.Invalidate();
timer = null;

現在時刻を取得する

var currentTime = DateTime.UtcNow;
Console.WriteLine ("Date/Time: " + currentTime);

アラートを表示する

OKボタンだけのシンプルなアラートを表示します

using(var alert = new UIAlertView("Title", "Message", null, "OK", null))
{
	alert.Show();	
}

プロパティリスト(plist)にアクセスする

var plist = NSUserDefaults.StandardUserDefaults;
var myKey = plist["myKey"];
// Or
var myKey2 = plist.StringForKey("myKey2");
var myBoolKey = plist.BoolForKey("myBoolKey");
var myIntKey = plist.IntForKey("myIntKey");
 
plist.SetString("Save this string", "myStringKey");
// Saves the new "myStringKey" string.
plist.Synchronize();

Infoボタンを表示する

var f = infoButton.Frame;
var newInfoButtonRectangle = new RectangleF(f.X - 25f, f.Y - 25f, f.Width + 50f, f.Height + 50f);
infoButton.Frame = newInfoButtonRectangle;

Subviewsを検出する

foreach(var view in this.window.Subviews)
{
	Console.WriteLine ("View" + view.ToString());
	foreach(var subView in this.view.Subviews)
	{
		Console.WriteLine ("SubView: " + subView.ToString());
	}
}

参考