Apr 262013
 

Dalam pos kali ini saya akan terangkan bagaimana untuk buat table dalam Mac OSX.

Apa yang akan dipelajari adalah
– NSTableView
– Delegate

Pertama sekali anda perlu faham maksud delegate. Contoh yang ringkas adalah delegate atau wakil untuk
sesebuah negara atau organisasi. Mereka bertindak /bercakap sebagai wakil bagi negara atau organisasi tersebut.

Begitu juga delegate untuk objective-c, contohnya class NSTableView juga menggunakan delegate untuk
– mendapatkan data-data untuk display table daripada delegate.
– memberitahu table telah diclick kepada delegate.
dan sebagainya.

1. Pertama sekali, buat Xcode projek baru dan pilih Cocoa Application dalam OS X. Pastikan Use Automatic Reference Counting dicheck. Namakan nama projek BasicTable.

2. Kemudian pergi ke MainMenu.Xib dan tambah table view ke main window. Kemudian double click kedua2 colum header dan namakan ia Nama dan Kerjaya.

Drag Table dari Object Library ke window

Table yang telah didrag dari Object Library ke window

3. Pergi ke AppDelegate.h , dan tengok di , semua yang berada dalam kurungan <> adalah untuk menunjukkan class ini iaitu AppDelegate adalah delegate kepada NSApplication.

#import <Cocoa/Cocoa.h>

@interface AppDelegate : NSObject

@property (assign) IBOutlet NSWindow *window;

@end

4. Buat NSMutableArray property bernama persons di AppDelegate.h

5. Sekarang kita mahu tambah table view delegate pula. Tambah code seperti di bawah. NSTableViewDataSource bermakna table view (dari NSTableView) akan wakilkan AppDelegate untuk mendapatkan maklumat untuk display table dan NSTableViewDelegate pula adalah untuk programmer melakukan aksi yang sepatutnya setelah table row diclick, didrag dan sebagainya. Untuk mengetahui apa function yang disediakan oleh delegate ini, guna Command Key + Left Mouse pada delegate. Code akhir untuk AppDelegate.h adalah seperti di bawah.

#import <Cocoa/Cocoa.h>

@interface AppDelegate : NSObject <NSApplicationDelegate, NSTableViewDataSource, NSTableViewDelegate>

@property (assign) IBOutlet NSWindow *window;
@property (nonatomic, strong) NSMutableArray *persons;

@end

6. Sekarang anda perlu connect table ke AppDelegate.h. Tekan Assistant Editor dan AppDelegate.h akan terbuka bersebelahan dengan MainMenu.xib. Pastikan table view dihighlight di Document Outline. Untuk connect outlet, hold Ctrl key kemudian drag table view ke AppDelegate.h menggunakan mouse. Namakan ia sebagai tableView(Sila refer   Simple Calculator  jika anda mempunyai masalah sehingga step ini)

Xcode 5 copy

Drag table view dari IB ke AppDelegate.h

Namakan table view IBOutlet sebagai tableView

Namakan table view IBOutlet sebagai tableView

7. Cuba run tetapi masih tiada apa akan berlaku. Sebelum ini anda connect tableView ke AppDelegate, tetapi anda masih belum set delegate untuk tableView itu. Ada dua cara untuk set delegate iaitu dari Interface Builder atau guna code.

8. Untuk set delegate guna code, pergi ke AppDelegate.m dan tambah code seperti berikut

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    // Insert code here to initialize your application
    self.tableView.delegate = self;  //atau sama juga [self.tableView setDelegate:self]
    self.tableView.dataSource = self;
}

9. Try run program. Anda dapati pada ruangan output seperti berikut:
*** Illegal NSTableView data source (). Must implement numberOfRowsInTableView: and tableView:objectValueForTableColumn:row:
Ini kerana anda telah set delegate untuk table tetapi tidak implement di dalam AppDelegate.

10. Untuk hilangkan warning ini, tambah dua method tersebut dalam AppDelegate.m

//NSTableView tanya berapa bilangan row untuk table
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
{

}

//NSTableView tanya object (string dsb) untuk didisplay bagi setiap colum dan row
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{

}

11. Apabila run sekali lagi, tiada lagi warning kerana kita telahpun implement method yang diperlukan walaupun masih tidak melakukan apa-apa. Sekarang kita akan buat array untuk digunakan oleh table.
Ubah code dalam AppDelegate.m anda supaya seperti di bawah.

#import "AppDelegate.h"

NSString *NameKey = @"nameKey";
NSString *KerjayaKey = @"kerjayaKey";

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    // Insert code here to initialize your application
    self.tableView.delegate = self;
    self.tableView.dataSource = self;

    self.persons = [NSMutableArray array];

    NSDictionary *Zakir = @{NameKey: @"Zakir", KerjayaKey: @"Cikgu"}; //cara lama:
    NSDictionary *Husin = @{NameKey: @"Husin", KerjayaKey: @"Peguam"};
    NSDictionary *Hasan = @{NameKey: @"Hasan", KerjayaKey: @"Pensyarah"};

    [self.persons addObject:Zakir];
    [self.persons addObject:Husin];
    [self.persons addObject:Hasan];

}

//NSTableView tanya berapa bilangan row untuk table
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
{

}

//NSTableView tanya object (string dsb) untuk didisplay bagi setiap colum dan row
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{

}

@end

Code Explanation:
line 3-4: Kita hanya declare constant untuk digunakan pada dictionary key. Kemungkinan untuk tersalah taip berkurang jika ia akan banyak digunakan.
line 14: Initialize array.
line 15-19: Buat dictionary untuk setiap person, dalam dictionary itu ada ada nama dan kerjaya.
line 21-23: Masukkan setiap dictionary yang dibuat ke dalam persons array.

12. Untuk tableView mendapatkan data supaya kita berfungsi, kita perlu tambah code dalam method numberOfRowsInTableView: dan tableView:objectValueForTableColumn:. Tambah code seperti dibawah

//NSTableView tanya berapa bilangan row untuk table
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
{
    //bilangan row adalah sebanyak bilangan person
   return  [self.persons count];
}
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
    NSString *value;
    if ([tableColumn.identifier isEqualToString:@"name"]) {
        value = self.persons[row][NameKey]; //atau sama juga: [[self.persons objectAtIndex:row] valueForKey:NameKey];
    }
    else if ([tableColumn.identifier isEqualToString:@"kerjaya"]) {
        value = self.persons[row][KerjayaKey];
    }
    return value;
}

Code Explanation:
line 4 &7 : Table column identifier di cek supaya sama ada nama atau kerjaya
line 5 &8 : Set value untuk ambil data daripada, dari array untuk index ke row dan key NameKey atay KerjayaKey.

13. Run program. Tetapi nampaknya masih tiada apa yang berlaku. Ini disebabkan kita masih belum set identifier untuk table column. Pergi semula ke IB, highlight column Nama dan Kerjaya, dan set identifier di Identity Inspector sebagai ‘name’ dan ‘kerjaya’. Ambil perhatian bahawa identifier key ini tidak berkaitan dengan NameKey atau KerjayaKey constant. Anda boleh guna apa-apa nama sahaja.

Select table column dan set identifier di Identity Inspector

Select table column dan set identifier di Identity Inspector

14. Run dan sepatutnya anda dapat lihat table dengan person data yang dibuat. Bagaimana kalau nak tambah data? Jawapannya adalah dengan modify persons array kemudian reload data. Untuk demo secara ringkas, tambah push button di IB dan create IBAction di AppDelegate.m dan namakan ia addPerson.

Drag Add Person button to AppDelegate.m and name it addPerson

Drag Add Person button to AppDelegate.m and name it addPerson

15. Dalam addPerson:, ubah code menjadi seperti berikut

- (IBAction)addPerson:(id)sender {
    [self.persons addObject:@{NameKey: @"Ali", KerjayaKey: @"Jurutera"}];
    [self.tableView reloadData];
}

Code Explanation:
Kita lihat dalam code ini kita tambah NSDictionary baru, kemudian data direload supaya numberOfRowsInTableView: dan tableView:objectValueForTableColumn:row: dipanggil untuk update table.

16. Run dan tekan Add Person, jika anda tekan berkali-kali person baru akan sentiasa bertambah. Jika mahu tambah data person selain Ali, perlu lagi ubah code ini. Tetapi setakat ini cukuplah untuk tahu bagaimana menggunakan table.

Tekan Add Person untuk tambah data

Tekan Add Person untuk tambah data