Cocoa Programming II : NSTableView Advance

หลังจากได้ลองเขียน NSTableView ดูกันแล้ว วันนี้ก็ยังคงต่อด้วยเรื่องของ NSTableView เหมือนเดิมแต่ว่าเป็นขั้น Advance มากกว่าเดิม

More about datasource

จากโปรแกรมแสดงตารางรายชื่อครั้งก่อน จะเห็นว่าเราได้ set datasource มาที่ AppController และเราก็เขียน implement delegate ของ datasource ที่ AppController จะเห็นว่าวิธีแบบนี้ไม่ค่อยจะยืดหยุ่นมากนัก เพราะเนื่องจากว่าเราให้ AppController เป็นทั้งตัวควบคุม interface และยังให้เป็น datasource

สมมติว่าเราต้องการมี table มากกว่า 1 table และแต่ละ table มี datasource ที่มีข้อมูลต่างกัน เราก็คงต้องเพิ่ม datasource ให้เท่ากับจำนวนของ table ซึ่งนั่นก็แปลว่าเราก็ต้องสร้าง AppController instance มาหลายๆอัน มันก็คงจะไม่ใช่วิธีที่ดีนัก และที่สำคัญตัวโปรแกรมจะมองว่า AppController instance ที่เราสร้างขึ้นมาใหม่ มันเป็นตัวเดียวกัน ดังนั้นข้อมูลใน table A และ B ก็จะเหมือนกัน ( ดูรูปประกอบ ) ฉนั้นแล้วการที่เราให้ AppController เป็น datasource โดยตรงก็คงไม่ดีแน่

งั้นแทนที่เราจะให้ Class AppController เป็น datasource โดยตรง เราก็เปลี่ยนให้ AppController มี member เป็น datasource ก็น่าจะดีกว่า

จากรูปข้างบน จะเห็นว่า เราก็สามารถมีหลายๆ datasource ที่ต่างกันได้ แล้วเราจะเขียน class ออกมาได้ยังไง ? งั้นมาดูตัวอย่างจริงกันเลยดีกว่า

สมมติว่า เราต้องการ เขียนโปรแกรมแสดงรายชื่อเหมือนเดิม แต่เราต้องการแยก class datasource ออกมาจาก AppController โดยให้ชื่อว่า StudentDataSource

จาก Class StudentDataSource ข้างบนเราก็ได้ให้ NSMutableArray เป็นตัวเก็บข้อมูล รายชื่อ และในส่วนของ implement ก็เขียนได้ลักษณะแบบนี้

ก็เป็นว่าตอนนี้เรามี Class ที่เป็น DataSource ต่อไปก็แก้ไข AppController ของเรา แบบนี้

จะเห็นว่า เรามี member ที่เป็น StudentDataSource เข้ามาด้วย และในส่วน implement ก็จะได้แบบนี้

จาก Code ข้างบนจะมีส่วนที่สำคัญคือ awakeFromNib จะเห็นว่าเมื่อโปรแกรมเริ่มทำงาน เราก็ Set DataSource ให้กับ m_tableView ในทันที และเราก็ไม่ต้องไป link ที่ interface builder เลย

ลอง Download Source ไปลอง  Compile ดูครับ โปรแกรมก็ทำงานเหมือนเดิมแต่ ต่างกันตรงที่เราแยก datasource ออกมาให้เป็น member ของ AppController ต่อไปถ้าหากเราต้องการ มีหลายๆตาราง และ datasource ที่ต่างกัน ก็สามารถทำได้แล้วครับ

Editable Cell

โปรแกรมที่เราได้ลองเขียนนั้น เป็นแค่การอ่านข้อมูลมาแสดงผลอย่างเดียว ไม่สามารถ แก้ไขข้อมูลภายใน Cell ได้ ถ้าหากเราต้องการให้ table ของเราสามารถแก้ไขได้ เราต้อง implement delegate method เพิ่มอีก 1 นั่นก็คือ

– (void)tableView:(NSTableView *)aTable setObjectValue:(id)aData
forTableColumn:(NSTableColumn *)aCol
row:(int)aRow;

และจากโปรแกรมข้างบน ก็สามารถเขียนเพ่ิมให้ table ของเราสามารถแก้ไขข้อมูลได้ ดังตัวอย่าง code ข้างล่าง

ก็ลองโหลด Source Code ไปลอง Compile เล่นดู

More Column

จากตัวอย่างที่เขียนไปเราได้สร้างตารางที่มีแค่ 1 column เท่านั้น ถ้าหากต้องการสร้าง หลายๆ Column แล้วเราก็เพียงแค่ไปเปลี่ยน ค่าของจำนวน column ใน interface builder แบบรูปข้างล่าง

การสร้าง interface  ก็คงไม่ยากอะไร แต่ปัญหาคือ เราจะเขียน Code ให้มันแสดง cell ที่ตำแหน่ง column ที่เราต้องการได้อย่างไร ?

วีธีการก็คือ เราต้อง กำหนดชื่อ ให้กับ Column ก่อน แล้วก็แก้ไข code ในส่วนของ

-(id) tableView:(NSTableView*)    table
objectValueForTableColumn:(NSTableColumn*) tableColumn
row:(int) rows

สมมติว่า เราต้องการแก้ไข โปรแกรม แสดงรายชื่อนักเรียน ให้มีอีก 1 Column เพื่อแสดงสาขาที่เรียนของนักเขียนด้วย หน้าตาโปรแกรม เป็นลักษณะแบบนี้

เราก็ทำการแก้ไข datasource ของเราให้มี array เพ่ิมขึ้นมาอีก 1 เพื่อเอาไว้เก็บ สาขาที่เรียนของนักเรียน อาจจะเขียนใหม่ได้ว่า

และเราก็เขียน method เพิ่ิมเติม

และส่วนที่สำคัญที่สุดคือ tableView: objectValueForTableColumn: row: เราต้องเขียนให้มันส่ง ตำแหน่ง cell ใน column ที่ต้องการให้เป็นแบบนี้

จาก code ข้างบนเราสามารถอ้างอิงถึง column ได้โดยการใช้ column identifier เป็นการตรวจสอบว่า เป็น column ของเราที่ต้องการหรือเปล่า  อย่างตัวอย่างเราก็ได้ให้ เปรียบเทียบว่าเป็น column “name” หรือไม่ และการใส่ค่าให้กับ column identifier เราทำได้โดยการใช้ interface builder และใส่ค่าให้กับ column เหมือนรูปข้างล่าง

แล้วก็ Compile ดูครับ เพียงเท่านี้ก็เป็นอันเรียบร้อย โปรแกรมก็จะออกมาแบบนี้

สำหรับ Source ก็โหลดได้นี่เลย Download Source Code

One thought on “Cocoa Programming II : NSTableView Advance”

  1. ผมติดปัญหาหนึ่งอะครับ เรื่องการโหลดTableView ที่มี Row มากกว่า25 ใน Iphone ครับ ถ้ามันมีมากกว่ามันก็ crashes เลย ทำไงดีอะครับ

Leave a Reply