
วิธีการพัฒนา iPhone Apps สำหรับผู้เริ่มต้นกับการใช้ UIGestureRecognizer เบื้องต้นจับการเคลื่อนไหวของตัวอุปกรณ์ เพื่อตอบสนองกับแอพพลิเคชันด้วย XCode 6 ครับอีกหนึ่งบทเรียนที่มีคนสอบถามกันมามากในซีรีย์ของนักพัฒนาแอพพลิเคชันบน iPhone ครับ ซึ่งกว่าจะจัดการเขียนชุด SQLite หรือ Core Data เสร็จคงต้องใช้เวลาอีกสักหน่อยก็จะมีพอมีเวลาคั่นด้วยบทเรียนเล็กๆ น้อยๆ เหล่านี้แทนครับ
Gesture คือการจับการเคลื่อนไหวของตัวอุปกรณ์ iPhone ครับ โดยสิ่งที่เรียกมาช่วยคือ UIGestureRecognizer ผ่านการใช้งานร่วมกับ MainStoryBoard ครับ
เริ่มต้นพัฒนา แอพพลิเคชันบน iPhone ด้วย UIGestureRecognizer
ให้ทำการสร้าง New Project ขึ้นมาใหม่ แล้วเลือก Template เป็น “Single View Application”

ให้หาไฟล์รูปภาพ ประเภท .PNG เป็น Transparent มาเตรียมไว้ในที่นี้ผมใช้ไฟล์ psy.png และ ball.png ตามตัวอย่างข้างล่างครับ

นำรูปภาพทั้ง 2 ไฟล์ไปวางไว้ที่ Project Tree เลยครับ เลือก Copy ด้วยนะครับ ต่อจากนั้นให้ลองเปิดไฟล์ MainStoryBoard ขึ้นมา แล้วลาก UIImageView ไปวางไว้ที่ ViewController 2 ตัวเลือกไฟล์ปลายทางของ UIImage View เป็น psy.png และ ball.png ครับ



หลังจากวาง UIImageView แล้ว 2 ตัวก็ให้เลือก และปรับขนาดของ UIImageView ให้พอดีกับภาพของเรา ปรับลากวางจัดตำแหน่งตามใจชอบครับ ให้เหมือนตัวอย่าง

ต่อมาจำเป็นจะต้องใช้ UIGesture มาช่วยแล้วให้ลงไปเลือก Object ที่ชื่อว่า Pan Gesture Recognizer มาวางไว้ที่ ViewController ครับ

ให้ทำการเลือก Pas Gesture Recognizer ไปวางไว้ที่ View Controller Scene ตามรูปครับ ให้ลากไปวางไว้เลย

ต่อจากนั้นให้คลิกที่ UIImageView โดยผมจะคลิกที่รูปของ psy.png ท่าเต้นกังนัมสไตล์ เมื่อคลิกแล้วให้ สังเกตที่แถบ บนขวาที่เขียนว่า Outlet collector ทำการ Link มันเข้าหากันตาม สเตปรูปภาพด้านล่างเลยครับ

Recogniser

ต่อจากนั้นให้เปิดไฟล์ ViewController.h ขึ้นมาแล้วเขียนคำสั่งต่อไปนี้
#import
@interface ViewController : UIViewController
- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer;
@end
ต่อจากนั้นให้เปิดไฟล์ ViewController.m ขึ้นมาแล้ว เพิ่ Method ใหม่เข้าไปเลยครับ ตามที่เรากำหนดไว้
- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer {
CGPoint translation = [
recognizer translationInView:self.view];
recognizer.view.center = CGPointMake(
recognizer.view.center.x + translation.x,
recognizer.view.center.y + translation.y);
[recognizer setTranslation:CGPointMake(0, 0)
inView:self.view];
}
ให้ไปที่ไฟล์ MainStoryBoard อีกครั้ง คราวนี้ให้ทำการ เลือกที่ Connection Inspector แล้วลากเชื่อมโยง Link จาก Sent Actions ไปยังหน้าต่าง ViewController ในพื้นที่ว่าง



ลองทำการ Run ตัว Project ดู แล้วลอง ลากรูปภาพของ Psy.png จะเห็นว่ามันสามารถเลื่อนไปมาได้บนหน้าจอแอพพลิเคชัน

ต่อมาให้เพิ่มคำสั่งในการ คำนวณ เวลาที่มีการ Touch หรือ End เหตุการณ์ที่เราสัมผัสหน้าจอ iPhone ครับ โดยไปที่ไฟล์ ViewController.m ขึ้นมาแล้วก็เพิ่ม คำสั่งเล็กน้อยใน Method เดิมที่ชื่อ handlePan() ครับ
if (recognizer.state == UIGestureRecognizerStateEnded) {
CGPoint velocity = [recognizer velocityInView:self.view];
CGFloat magnitude = sqrtf((velocity.x * velocity.x) + (velocity.y * velocity.y));
CGFloat slideMult = magnitude / 200;
NSLog(@"magnitude: %f, slideMult: %f", magnitude, slideMult);
float slideFactor = 0.1 * slideMult; // Increase for more of a slide
CGPoint finalPoint = CGPointMake(recognizer.view.center.x +
(velocity.x * slideFactor),
recognizer.view.center.y + (velocity.y * slideFactor));
finalPoint.x = MIN(MAX(finalPoint.x, 0), self.view.bounds.size.width);
finalPoint.y = MIN(MAX(finalPoint.y, 0), self.view.bounds.size.height);
[UIView animateWithDuration:slideFactor*2
delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
recognizer.view.center = finalPoint;
} completion:nil];
}
หากใส่ Code ลงไปจะเป็นดังนี้
- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer {
CGPoint translation = [recognizer translationInView:self.view];
recognizer.view.center = CGPointMake(
recognizer.view.center.x + translation.x,
recognizer.view.center.y + translation.y);
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
if (recognizer.state == UIGestureRecognizerStateEnded) {
CGPoint velocity = [recognizer velocityInView:self.view];
CGFloat magnitude = sqrtf((velocity.x * velocity.x)
+ (velocity.y * velocity.y));
CGFloat slideMult = magnitude / 200;
NSLog(@"magnitude: %f, slideMult: %f", magnitude, slideMult);
float slideFactor = 0.1 * slideMult; // Increase for more of a slide
CGPoint finalPoint = CGPointMake(
recognizer.view.center.x + (velocity.x * slideFactor),
recognizer.view.center.y + (velocity.y * slideFactor));
finalPoint.x = MIN(MAX(finalPoint.x, 0),
self.view.bounds.size.width);
finalPoint.y = MIN(MAX(finalPoint.y, 0),
self.view.bounds.size.height);
[UIView animateWithDuration:slideFactor*2
delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
recognizer.view.center = finalPoint;
} completion:nil];
}
}
หากทำการ Run ดูจะพบว่า Console DeBug ของ XCode จะโผล่ขึ้นมา และถ้ามีการ ลากตัว UIImageView ไปมา จะมีการเก็บค่าตำแหน่ง Position ล่าสุดไว้เสมอ เพื่อให้เราทราบพิกัดล่าสุดที่มีการเคลื่อนไหวครับ

เป็นไงบ้างครับ ขั้นตอนการใช้ UIPan GestureRecognizer เพื่อได้ไอเดียไปประยุกต์ใช้ค้นหาตำแหน่งที่วาง UIImage ตำแหน่งล่าสุด ยังคงเหลือรูปแบบอีกหลายรูปแบบหลายตัวเช่น Rotate GestureRecognizer และ Resize อีกครับ ไว้จะกลับมาเพิ่มเติมให้ศึกษาอีกนะครับ