iPhone Programming VII : Table View ( Part 3)

วันนี้ก็ยังต่อเนื่องเกี่ยวกับเรื่องของ table view เหมือนเดิมนะครับ สืบเนื่องจากครั้งที่แล้วที่ผม ได้เขียน tutorial ในแบบลักษณะการเขียนย่อลง เอาแต่ส่วนที่สำคัญทำให้ผู้อ่านหลายๆคน บอกว่าน่าจะเอาแบบเดิม ( คือเริ่มตั้งแต่ สร้าง project ) เพราะ ยังประสบการณ์น้อย อ่านแล้วไม่เข้าใจ โอเค ครับ งั้นผมจะ พยายาม เขียน ในทุกๆขั้นตอนเลยละกัน ( แต่ในอนาคจะ ค่อยๆ ปรับลดลงนะครับ )

อย่างที่บอกไปว่าวันนี้ยังอยู่ในเรื่องของ table เหมือนเดิม วันนี้จะมาต่อในเรื่องของ Section ครับ
โดยปกติแล้ว Table View น้ันจะประกอบไปด้วย cell และ cell เหล่านี้สามารถแยกเป็นหมวดๆได้ เรียนกว่า section ดูรูปประกอบ จะเข้าใจ

table_section

จากรูปจะเห็นชื่อที่ขึ้นต้นด้วย ตัวอักษรเดียวกันนั้นจะถูกจับรวมกันเป็นกลุ่ม ( section ) งั้นเรามาเริ่มเลยดีกว่าครับ

โปรแกรมที่เราจะเขียนกันในวันนี้ก็ไม่มีอะไรมากครับ คือเราจะเขียน โปรแกรม ไว้เก็บรายชื่อของสัตว์ต่างๆ แล้วก็แยกตามหมวดหมู่เท่านั้นเอง แต่ก่อนที่จะเริ่มดูภาพประกอบกันก่อนครับว่า โครงสร้างของโปรแกรม เราเป็นแบบไหน จะได้เข้าใจกันก่อนสักนิดว่า เรากำลังจะทำอะไร

chart

ตามแผนภาพ ผมจะแบ่งหมวดหมู่ของสัตว์ออกเป็น 3 ประเภทคือ Mammal , Bird , Fish แล้วแต่ละประเภท นั้นก็จะมีรายชื่อของ สัตว์ต่างๆ การออกแบบ คลาสต่างๆ ก็จะเหมือนดังแผนภาพ ครับ นั่นก็คือ ผมมี class ที่ชื่อ Animal เป็น ทั้ง datasource , delegate ( NSTableView ) เมื่อดูภาพประกอบคร่าวๆ เรียบร้อยแล้ว ต่อไปก็เริ่มโปรเจคกันเลย

Start New Project

เราก็เลือก view based application ครับ แล้วหลังจากนั้นก็ตั้งชื่ออะไรก็ได้ ในตัวอย่างนี้ผมจะใช้ชื่อว่า AnimalDemo เสร็จแล้วก็จะได้โปรเจคออกมาดังรูปแบบนี้ครับ

new_project

เมื่อเรียบร้อยแล้ว ลำดับต่อไป เราก็จะออกแบบหน้าตาของโปรแกรมเราก่อน ก็ทำการเปิด AnimalDemoViewController.xib ขึ้นมา แล้วก็ลาก Table View เข้ามาดังรูปครับ

table_demo

ก็เป็นอันเสร็จ การออกแบบหน้าตาของโปรแกรม  หลังจากนี้ ลำดับต่อไปก็คือ เขียน class ที่เป็น datasource และ delegate นั่นเอง
เราจะทำการเพิ่ม class เข้ามายัง project ของเราโดยการ เลือกไปที่เมนู File > New File… แล้วก็เลือก ชนิดของ File ดังรูปครับ

new_class

หลังจากนั้นก็ตั้งชื่อว่า Animal ก็เป็นอันเสร็จเรียบร้อย ต่อไปเราก็จะมาเขียน code กัน

Implement Delegate & Data Source

อย่างที่เห็นในแผนภาพ ไปแล้ว ว่าเรามี class ที่ชื่อ Animal ที่ประกอบไปด้วย Array ที่เก็บรายชื่อของ สัตว์ต่างๆ เวลาเขียน code ออกมาก็จะได้ประมาณนี้ครับ

Explain

ดู code แล้วอาจจะค่อนข้างจะยาวนิดหนึ่งนะครับ ค่อยๆทำความเข้าใจกันในแต่ละส่วนก่อนดีกว่า

ฟังก์ชั่นนี้ ไม่ได้มีอะไรมากนอกจาก ประกาศ array ที่ประกอบไปด้วยรายชื่อของสัตว์ต่างๆ และนำมันไปใส่ไว้ใน dictionary ( m_animal ) จริงๆแล้วเราจะใช้ array ทั้งหมดก็ได้นะครับ

สองฟังก์ชั่น ข้างบน นั้น เป็นการบอกว่า ตารางนี้ประกอบไปด้วย section ทั้งหมดเท่าไหร่ และแต่ละ section นั้นมีแถวจำนวนเท่าไหร่
ซึ่งจำนวน section ของเราทั้งหมดนั้นมี จะมีเท่ากับ จำนวน array ที่ได้เก็บไว้ใน m_animal นั่นก็คือ 3 และจำนวน แถวของแต่ละ section นั้นก็หามาจาก จำนวนชื่อของสัตว์ในแต่ละ array ที่ได้เก็บไว้นั่นเอง
และฟังก์ชั่นสุดท้าย ก็คือ ชื่อของแต่ละ section ในตัวอย่างผมได้ให้ ชื่อของแต่ละ section น้ันเป็นชื่อของ key ที่ผมได้ใส่ไปใน dictionary ตอนสร้างครั้งแรกนั่นเอง

หมายเหตุ ใน Dictionary เราไม่สามารถจะขอข้อมูลที่เราได้ใส่ไปถ้าหากไม่มี key ดังนั้นแล้ว ผมจึงใช้ ** [NSDictionary allKey] เพื่อที่จะได้ key ทั้งหมดกลับมาซึ่งจะเป็น array ** หลังจากนั้นแล้วค่อยไปไล่หาค่าต่างๆตามลำดับ index ใน array อีกที

ส่วนสุดท้ายก็คือ

เราได้ implement delegate เพื่อที่ตารางจะได้รู้ว่าควรนำอะไรไปแสดง ในแต่ละ section , row
จาก code ข้างบน อธิบายคร่าวก็คือ เมื่อเรา ได้ index path มาแล้วเราหากลุ่มจาก section เมื่อเรารู้กลุ่มแล้ว หลังจากนั้นก็ไปหา ชื่อของสัตว์ตามลำดับของแถว ที่ควรจะแสดง

ก็เป็นอันจบในส่วนของ Animal Class

แต่ยังเหลือในส่วนของ View Controller ที่เรายังไม่ได้เขียนเพิ่มครับ เราต้อง เพิ่ม Animal เข้าไปยัง View Controller ของเรา ก็เปิด File ที่ชื่อ AnimalDemoViewController.h ขึ้นมาครับ
หลังจากนั้นก็เพิ่ม code เข้าไปดังนี้

แล้วส่วน implement ก็จะเป็นประมาณนี้ครับ

ก็เป็นอันเสร็จ อธิบายกันสักนิด ที่เราได้เพิ่มเข้าไปก็คือ Animal ( m_animalDataSource ) แต่เราได้ประกาศให้เป็น Outlet เพื่อที่ว่าจะได้นำไป link กับตารางที่อยู่ interface builder ครับ

Link Object

กลับไปยัง interface builder ครับ เรายังเหลือสิ่งที่ต้องทำอีก อย่างสองอย่าง นั่นก็คือ สร้าง instance ของ Animal ก็เริ่มจาก เปิด AnimalDemoViewController.xib ขึ้นมา หลังจากนั้นก็เพิ่ม Object เข้าไปดังรูปครับ

animal_object

จากรูป เมื่อ ลาก Object เข้ามาแล้ว เราก็เปิด หน้าต่าง inspector ขึ้นมาครับ แล้วตรง indentity จะเห็น Class เราก็เปลี่ยนให้เป็น Animal ก็เรียบร้อย เพียงเท่านี้เราก็มี Animal Instance เรียบร้อย  หลังจากนั้นก็เชื่อมมันเข้ากับ m_animalDataSource ของเรา ดังรูป

link_instance

และลำดับสุดท้ายครับ เราต้อง set datasource ให้กับตารางของเรา เราก็ click ขวาไปยังตาราง แล้วก็ลาก เชื่อมเข้ากับ Animal Instance ดังรูปครับ

link_data-source

ก็เป็นอันเสร็จทุกๆอย่างครับ Compile แล้วก็ Run จะเห็นโปรแกรมมีหน้าตา แบบนี้ครับ

animal_done

ครั้งหน้าเดี๋ยวมาต่อกัน ในเรื่องของ ตารางต่อนะครับ
ตัวอย่าง Source Code ก็กด Download ได้เลยครับ

iPhone Programming VI : Table View ( Path 2 )

วันนี้มาต่อเรื่องของ table view กันหน่อยดีกว่า

Adding Image to Cell

เมื่อครั้งก่อน เราได้ใช้งาน table view ที่ไว้แสดงผลแต่ตัวหนังสือ จริงๆแล้วเราสามารถเพิ่ม รูปภาพเข้าไปยัง cell ได้ด้วย วิธีการก็ไม่ได้ยากอะไรเลยครับ เราก็เพียงแต่ สร้าง image ขึ้นมาแล้วก็ set ให้ cell เท่านั้นเองดูตัวอย่างอาจจะเข้าใจง่ายกว่า จากการ implement ของ method
– (UITableViewCell *)tableView: (UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath;
ในครั้งก่อน เราจะทำการเพิ่ม image เข้าไป โดยเพิ่ม code เข้าไปดังนี้ครับ

จะเห็นว่า เราได้เขียน code ขึ้นมาเพิ่มเพียง 2 บรรทัดเองครับ คือ

เมื่อ run program หน้าตาก็จะเป็นประมาณแบบนี้

table_with_image

Row Selection

วิธีการจัดการเกี่ยวกับการเลือกแถวในตาราง เราอาจจะใช้ method ที่ใช้ถามว่าแถวไหนถูกเลือกอยู่ โดยเรียกใช้ method ที่ชื่อว่า indexPathForSelectedRow ก็ได้ครับ ตารางก็จะบอกเรามาว่าแถวไหนถูกเลือกอยู่ ดังตัวอย่าง

สมมติว่า ผมเขียน IBAction สำหรับ Button ไว้ชื่อว่า getSelectRow นะครับ

ผลลัพธ์ก็จะมีหน้าตาประมาณนี้

table_with_row_selected

เมื่อกด ไปที่ตาราง แล้วก็กด ปุ่มมันก็จะบอกว่า เราเลือกที่แถวไหน ทำได้ไม่ยากเลยครับ
และ table view นั้นมี delegate ที่เกี่ยวกับการเลือกแถวที่น่าสนใจ ได้แก่ delegate แรกจะเป็นการเขียนเหตุการณ์ที่เกิดขึ้นก่อนการเลือกแถว ที่ชื่อว่า
-(NSInteger) tableView: (UITableView*) tableView willSelectRowAtIndexPath: (NSIndexPath*) indexPath
ตัวอย่าง code จะเป็นประมาณนี้ครับ

เราอาจจะเอา button ออก แต่เมื่อกดไปที่ตาราง มันก็จะบอกแถวมาเรียบร้อยเลย เพราะว่าเมื่อตารางถูกเลือก มันจะมาเรียก delegate โดยอัตโนมัติ เหมือนกับรูปข้างล่าง

table_with_row_delegate

และมีอีก delegate ที่น่าสนใจคือ เหตุการณ์หลังจากกดไปที่แถวของตาราง นั่นก็คือ
-(void) tableView: (UITableView*) tableView didSelectRowAtIndexPath: (NSIndexPath*) indexPath
ตัวอย่าง code การใช้งานก็จะเช่นว่า เราต้องการให้มันแสดง alert ขึ้นมาหลังจากกดไปที่แถวของตารางนะครับ ก็จะเขียนได้ประมาณนี้

หน้าตาหลังจาก run program ก็จะเป็นแบบนี้ครับ

table_with_delegate_alert

วันนี้ก็จบเพียงเท่านี้ครับ ครั้งหน้า เดี๋ยวมาต่อด้วย custom cell