วันอาทิตย์ที่ 5 มิถุนายน พ.ศ. 2554

iPhone: UIActionSheet Delegate

iPhone: UIActionSheet Delegate
จากบทความของ UIActionSheet ทั้ง 2 บทความที่เคยได้เขียนไปแล้วนั้น ทำให้เราได้เข้าใจหลักการการใช้งานและการประยุกต์ใช้ UIActionSheet ในบทความนี้จะพูดถึงการจัดการกดแต่ละปุ่มใน UIActionSheet กันนะครับว่าจะแยกการกดปุ่มแต่ละปุ่มได้อย่างไร และแต่ละฟังก์ชั่นมีความสำคัญอย่างไร มาดูกันครับ



สิ่งที่เราต้องรู้จักเพิ่มเติมคือ delegate นะครับ

delegate หากใครเคยเขียนโปรแกรมแบบ Event Driven Programming อย่างเช่น Java จะคล้ายๆ กับการ implements interface ครับ โอเคสำหรับคนที่ยังงงๆ อยู่ จะอธิบายเพิ่มเติมนะครับ delegate function นี้จะเราจะเขียนเอาไว้เพื่อรับค่า เมื่อเกิด Event เช่น การกดปุ่มใน UIActionSheet ขึ้น มันจะส่งค่าค่าหนึ่งมาใน delegate function ทำให้เราสามารถจัดกับพารามิเตอร์ที่ส่งเข้ามาได้จาก delegate function ผมเขียนไปก็งงไป เรามาดูตัวอย่างกันดีกว่า

เริ่มแรกกับการใช้งาน UIActionSheetDelegate

1) ในไฟล์ .h ให้ implement <UIActionSheetDelegate> นะครับ

[sourcecode language="objc"]

@interface DemoUIActionSheetViewController : UIViewController <UIActionSheetDelegate>{

}

[/sourcecode]

การเขียนโค้ดแบบข้างบนเป็นการประกาศว่าคลาสนี้กำลังจะรับอีเวนท์ที่เกิดขึ้นจาก UIActionSheet ซึ่งชื่อว่า UIActionSheetDelegate โดยจะเขียนอยู่ในเครื่องหมาย < ... > นะครับ เมื่อเราเขียน implement delegate แล้วเราจำเป็นต้องกลับไปเขียน ฟังก์ชั่นใน .m ด้วย ตามขั้นตอนต่อไป

2) การเซ็ต delegate ให้กับ UIActionSheet

การเซ็ต delegate จะทำเมื่อเราสร้างตัวแปรของ UIAction Sheet เสร็จเรียบร้อยแล้ว ดังนี้

[sourcecode langauge="objc"]

UIActionSheet *actSheet = [[UIActionSheet alloc] init];
actSheet.delegate = self;

[/sourcecode]

จากโค้ดข้างบน การเขียนว่า actSheet ซึ่งเป็นตัวแปร UIActionSheet ว่า

actSheet.delegate = self หมายถึงเราจะเขียน delegate function ไว้ที่คลาสนี้ ดังนั้น delegate function จะถูกเขียนขึ้นในไฟล์ .m (ที่ชื่อเดียวกันกับไฟล์ .h ในข้อ 1) นะครับ

3) ฟังก์ชั่น delegate ของ UIActionSheetDelegate

หากเราลองกดไปดูที่คลาส UIActionSheet จะพบว่า UIActionSheet ประกาศ delegate ไว้ทั้งหมด 6 ตัว ซึ่งทั้งหมดนั้นเป็นแบบ optional คือเราจะเลือกเขียนฟังก์ชั่นไหนก็ได้ โดยฟังก์ชั่นทั้งหมดมีดังต่อไปนี้

[sourcecode langauge="objc"]

@protocol UIActionSheetDelegate <NSObject>
@optional

// Called when a button is clicked. The view will be automatically dismissed after this call returns
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex;

// Called when we cancel a view (eg. the user clicks the Home button). This is not called when the user clicks the cancel button.
// If not defined in the delegate, we simulate a click in the cancel button
- (void)actionSheetCancel:(UIActionSheet *)actionSheet;

- (void)willPresentActionSheet:(UIActionSheet *)actionSheet;  // before animation and showing view
- (void)didPresentActionSheet:(UIActionSheet *)actionSheet;  // after animation

- (void)actionSheet:(UIActionSheet *)actionSheet willDismissWithButtonIndex:(NSInteger)buttonIndex; // before animation and hiding view
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex;  // after animation

@end

[/sourcecode]

อธิยายเพิ่มเติม นะครับ ทั้ง 6 ฟังก์ชั่นนั้น จากที่บอกไปแล้วเราสามารถเลือกนำมาเขียนกี่ฟังก์ชั่นก็ได้ ตามแต่จำเป็น แต่หากเรานำมาเขียนทุกอันแล้วลองดู ลำดับเหตุการณ์ที่เกิดขึ้นจะได้ดังต่อไปนี้ครับ

[sourcecode language="objc"]

-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{
NSLog(@"clickButtonAtIndex: %d",buttonIndex);
}

-(void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex{
NSLog(@"didDismissButtonAtIndex: %d",buttonIndex);
}

-(void)actionSheet:(UIActionSheet *)actionSheet willDismissWithButtonIndex:(NSInteger)buttonIndex{
NSLog(@"willDismissWithButtonAtIndex: %d",buttonIndex);
}

-(void)actionSheetCancel:(UIActionSheet *)actionSheet{
NSLog(@"cancel");
}

-(void)willPresentActionSheet:(UIActionSheet *)actionSheet{
NSLog(@"willPresent ActionSheet");
}

-(void)didPresentActionSheet:(UIActionSheet *)actionSheet{
NSLog(@"didPresent ActionSheet");
}

[/sourcecode]

ผลลัพธ์ที่เกิดขึ้น สมมุติว่าเรากดปุ่มให้ action sheet มันแสดงขึ้นมาแล้ว ก้อกดสักปุ่มหนึ่ง (ตัวอย่างผมมีอยู่ 5 ปุ่ม รวมปุ่ม cancel ด้วย) ได้ผลลัพธ์ดังนี้

2011-06-04 22:45:03.923 DemoUIActionSheet[1403:207] willPresent ActionSheet
2011-06-04 22:45:04.179 DemoUIActionSheet[1403:207] didPresent ActionSheet
2011-06-04 22:45:05.568 DemoUIActionSheet[1403:207] clickButtonAtIndex: 2
2011-06-04 22:45:05.568 DemoUIActionSheet[1403:207] willDismissWithButtonAtIndex: 2
2011-06-04 22:45:05.821 DemoUIActionSheet[1403:207] didDismissButtonAtIndex: 2

ลำดับจะเป็นตามผลลัพธ์ข้างบน คือเมื่อกดให้ UIActionSheet แสดงขึ้นมา การทำงานจะเข้าไปทำในฟังก์ชั่น willPresent เมื่อ UIActionSheet กำลังเลื่อนขึ้นมา และ didPresent เมื่อ UIActionSheet แสดงเสร็จแล้ว

เมื่อเรากดปุ่มใดสักปุ่ม เช่นผมกดปุ่มที่ 3 (นับ index คือ 0,1,2 นั้นตกที่ index ที่ 2) ลำดับการทำงานจะเข้าไปที่

ClickButton -> willDismiss -> didDismiss ตามลำดับ

ประเด็นคือ เราสามารถตรวจสอบได้ว่าเรากดปุ่มไหนได้ที่ฟังก์ชั่น clickButtonAtIndex, willDismiss, didDismiss จากค่าของพารามิเตอร์ (NSInteger)buttonIndex

โดยที่เรานำ buttonIndex มาเปรียบเทียบใน switch case หรือ if ก็ได้นะครับ เช่น

[sourcecode language="objc"]

-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{
NSLog(@"clickButtonAtIndex: %d",buttonIndex);
switch (buttonIndex) {
case 0:{
//to do if click button 1
break;
}
case 1:{
//to do if click button 2
break;
}
case 2:{
//to do if click button 3
break;
}
case 3:{
//to do if click button 4
break;
}
}
}

[/sourcecode]


เพียงแค่เราตรวจสอบว่าปุ่มที่ถูกกดเป็นปุ่มไหน เราก้อสามารถเขียนคำสั่งให้แต่ละปุ่มของ UIActionSheet ได้แล้วครับ เหมือนภาพด้านบน ผมกดที่ปุ่ม "MY Button 2" เพื่อให้แสดงคำว่า MY Button 2 บน Label ที่ผมกำหนดเอาไว้ หากเพื่อนๆ คนไหนสงสัยหรือมีข้อแนะนำเพิ่มเม้นมาได้เลยนะครับ

บทความที่เกี่ยวข้อง

adaydesign :)

2 ความคิดเห็น:

  1. สุดยอด...อธิบายเข้าใจง่ายมาก

    ตอบลบ
  2. ขอบคุณมากคร๊าาาบ อ้นเอ้น....

    ตอบลบ