วันจันทร์ที่ 27 มิถุนายน พ.ศ. 2554

iPhone: Basic UITableView Example using Custom Class

iPhone: Basic UITableView Example using Custom Class


บทความนี้เป็นบทความที่ต่อเนื่องจากบทความที่แล้วที่พูดถึงการเริ่มใช้งาน UITableView โดยการแสดงผลรายชื่อสีและกดที่ชื่อของสีเพื่อเปลี่ยนสีพื้นหลังของวิว (iPhone: Basic UITableView Example) ในบทความนี้ก็จะคล้ายๆ กันครับในฟังก์ชั่นคือแสดงรายชื่อของสีและกดชื่อของสีเพื่อเปลี่ยนสีพื้นหลัง แต่ว่าเราจะมาลองสร้างเป็นคลาสเพื่อเรียกใช้งานกันดีกว่าครับ จะได้ปูพื้นฐานเพื่อนำไปใช้ในเรื่องอื่นๆ ด้วย



ก่อนอื่นคงต้องทำความเข้าใจกันก่อนว่า ทำไมถึงต้องใช้คลาสที่เราสร้างเองมาเก็บข้อมูลเพื่อแสดงผล? สาเหตุที่สำคัญคือ คลาสที่เราสร้างมานั้นสามารถเก็บข้อมูลได้ตรงตามความต้องการของเราซึ่งจะเก็บอยู่ในรูปของ property ของคลาส หากเราต้องการเรียกใช้งาน property ใดก็แค่เรียกผ่าน instance ของคลาสที่เราสร้างขึ้น จะทำให้โปรแกรมของเราจัดการได้ง่ายกว่าการสร้างอาเรย์หลายๆ ตัวแปรมาเก็บข้อมูลแต่ละชนิด ดังบทความก่อนหน้านี้นะครับ งั้นก็มาเริ่มกันเลยครับ


1. การสร้างคลาสใหม่ ทำได้โดยการคลิกขวาที่กล่อง Project และเลือกที่ NewFile... -> Objective-C Class



คลิกขวา -> New File...



Cocoa Touch -> Objective-C Class -> Next -> ใส่ชื่อคลาส


ในที่นี้ผมตั้งชื่อคลาสว่า MyColor เนื่องจากเป็นคลาสของสีที่เก็บชื่อและสีเอาไว้ในคลาสนี้ เมื่อสร้างเสร็จแล้วจะเห็นไฟล์อยู่ในกล่อง Project ของเรา



2. เขียนโปรแกรมในคลาส MyColor เพื่อให้เก็บข้อมูล ชื่อ (NSString) สี (UIColor) ดังนี้


ในไฟล์ MyColor.h


[sourcecode langauge="objc"]</p>
<p>@interface MyColor : NSObject {<br />
NSString *title;<br />
UIColor *color;<br />
}</p>
<p>@property (nonatomic,retain) NSString *title;<br />
@property (nonatomic,retain) UIColor *color;</p>
<p>-(id)initWithTitle:(NSString*)_title color:(UIColor*)_color;</p>
<p>@end</p>
<p>[/sourcecode]


จากโค้ด MyColor.h ข้างต้นนั้นจะเห็นว่ากำหนดตัว property ไว้ 2 ตัวคือ



  • NSString *title เอาไว้เก็บชื่อ

  • UIColor *color เอาไว้เก็บสี


การประกาศ property เพื่อที่ให้คลาสอื่นที่สร้าง instance ของคลาส MyColor เรียกใช้ property ผ่านตัวแปรได้ เช่น myColor.title, myColor.color


ฟังก์ชั่นในการสร้าง instance (ตัวแปรของคลาส) MyColor คือ การสร้างพร้อมการส่งค่า ชื่อและสี มาด้วยเพื่อสร้างตัวแปร ฟังก์ชั่น -(id)initWithTitle:(NSString*)_title color:(UIColor*)_color;


[sourcecode langauge="objc"]</p>
<p>@implementation MyColor</p>
<p>@synthesize title,color;</p>
<p>-(id)initWithTitle:(NSString*)_title color:(UIColor*)_color{<br />
self = [super init];</p>
<p>self.title = _title;<br />
self.color = _color;</p>
<p>return self;<br />
}</p>
<p>@end</p>
<p>[/sourcecode]


จากโค้ดในไฟล์ MyColor.m เขียนเพื่อ implement ฟังก์ชั่น -(id)initWithTitle:(NSString*)_title color:(UIColor*)_color เพื่อให้ค่าที่ส่งเข้ามาตอนสร้าง instance ใหม่นั้นถูกเก็บไว้ใน property


เท่านี้ก็เรียบร้อยแล้วครับการสร้างคลาส MyColor เพื่อเก็บข้อมูลสี เพื่อนำมาแสดงเป็นรายการใน TableView ของตัวอย่างนี้ โอเคเราเริ่มกันเลย


3. มากันที่ไฟล์ RootViewController.m จากบทความ iPhone: Basic UITableView Example จะมีอาเรย์อยู่ 2 ตัวเพื่อเก็บข้อมูลชื่อและสีที่จะแสดงนะครับ ในบทความนี้จะใช้เพียงอาเรย์ 1 ตัวเท่านั้นคืออาเรย์ของ MyColor เพื่อใช้ในการแสดงข้อมูลรายการชื่อของสีและกดสีให้เปลี่ยนสีพื้นหลังเหมือนเดิม


[sourcecode langauge="objc"]</p>
<p>#import &quot;RootViewController.h&quot;<br />
#import &quot;MyColor.h&quot;//import คลาส MyColor ด้วยนะครับ</p>
<p>@implementation RootViewController</p>
<p>NSMutableArray *listData;</p>
<p>...</p>
<p>@end</p>
<p>[/sourcecode]


จากโค้ดด้านบนเป็นการประกาศตัวแปรอาเรย์ที่ใช้เก็บ สมาชิกที่เป็น MyColor ต่อไปก็จะกำหนดค่าให้กับอาเรย์ตัวนี้นะครับ


4. การกำหนดค่าอาเรย์ listData (ชื่อตัวแปรอาเรย์) กำหนดค่าโดยสร้าง instance ของคลาส MyColor ใส่เข้าไปเลยตามชอบนะครับ ในฟังก์ชั่น viewDidLoad


[sourcecode langauge="objc"]</p>
<p>- (void)viewDidLoad{<br />
[super viewDidLoad];</p>
<p>[self setTitle:@&quot;Demo UITableView (3)&quot;];//ตั้งชื่อ Title ให้กับ Navigation Bar</p>
<p>listData = [[NSMutableArray alloc] initWithObjects: [[MyColor alloc] initWithTitle:@&quot;Blue&quot;  color:[UIColor blueColor]],<br />
[[MyColor alloc] initWithTitle:@&quot;Brown&quot; color:[UIColor brownColor]],<br />
[[MyColor alloc] initWithTitle:@&quot;Cyan&quot;  color:[UIColor cyanColor]],<br />
[[MyColor alloc] initWithTitle:@&quot;Dark&quot;  color:[UIColor darkGrayColor]],<br />
[[MyColor alloc] initWithTitle:@&quot;Gray&quot;  color:[UIColor grayColor]],<br />
[[MyColor alloc] initWithTitle:@&quot;Green&quot; color:[UIColor greenColor]],<br />
[[MyColor alloc] initWithTitle:@&quot;Light&quot; color:[UIColor lightGrayColor]],<br />
[[MyColor alloc] initWithTitle:@&quot;Magenta&quot; color:[UIColor magentaColor]],<br />
[[MyColor alloc] initWithTitle:@&quot;Orange&quot; color:[UIColor orangeColor]],<br />
[[MyColor alloc] initWithTitle:@&quot;Purple&quot; color:[UIColor purpleColor]],<br />
[[MyColor alloc] initWithTitle:@&quot;Red&quot;   color:[UIColor redColor]],<br />
[[MyColor alloc] initWithTitle:@&quot;White&quot; color:[UIColor whiteColor]],<br />
[[MyColor alloc] initWithTitle:@&quot;Yellow&quot; color:[UIColor yellowColor]],<br />
nil];<br />
}</p>
<p>[/sourcecode]


จากโค้ดนะครับสังเกตุว่า การสร้างอาร์เรย์จะใช้ฟังก์ชั่น initWithObjects ซึ่งจะใส่ Object ได้หลายตัว (มันเติม s เห็นหรือป่าว) แต่ต้องตามหลังด้วย nil เสมอนะครับ เนื่องจากว่าเป็นตัวบอกว่าสิ้นสุดที่สมาชิกตัวสุดท้ายแล้ว การใส่ค่า String ก้อใช้เป็น @"ชื่อ" การใส่ค่าสี ก้อใส่เป็น [UIColor สีที่ UIColor มีมาให้]


เพิ่มเติม [UIColor red], [UIColor green], [UIColor pink] และตัวอื่นๆ ที่นำมาเป็นตัวอย่าง นั้นเป็นค่า property ของคลาส UIColor (static) ดังนั้นจึงสามารถเรียกผ่านคลาส UIColor ได้โดยตรง


5. เหลือขั้นตอนสุดท้ายแล้วนะคับ คือการนำอาเรย์เข้าไปใช้ในเทเบิลวิว โดยการนำไปใช้เราก้อจะเข้าไปเขียนในฟังก์ชั่น



  • numberOfRowsInSection เพื่อบอกจำนวนรายการ

  • cellForRowAtIndexPath แสดงชื่อสีของรายการต่างๆ

  • didSelectRowAtIndexPath เมื่อกดที่แถวใดแถวหนึ่งแล้วให้เกิด action เปลี่ยนสีพื้นหลังตามชื่อสีนั้น


เรามาดูกันว่าต้องทำอย่างไรนะครับ


5.1 ในฟังก์ชั่น numberOfRowsInSection


[sourcecode langauge="objc"]</p>
<p>- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{<br />
return [listData count];<br />
}</p>
<p>[/sourcecode]


จากโค้ดเราต้อง รีเทิร์นจำนวนสมาชิกของ listData ออกมานะครับ เนื่องจากจะได้ตรงกับจำนวนสมาชิกในอาเรย์จริงๆ


5.2 ในฟังก์ชั่น cellForRowAtIndexPath


[sourcecode language="objc"]</p>
<p>- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath<br />
{<br />
static NSString *CellIdentifier = @&quot;Cell&quot;;</p>
<p>UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];<br />
if (cell == nil) {<br />
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];<br />
}</p>
<p>// Configure the cell. : การปรับแต่งข้อความบนรายการของเทเบิลวิวแต่ละแถว<br />
cell.textLabel.text = ((MyColor*)[listData objectAtIndex:indexPath.row]).title;<br />
return cell;<br />
}</p>
<p>[/sourcecode]


ในฟังก์ชั่นนี้เราเขียนเพิ่มแค่ บรรทัดหลังจากคอมเม้น //Configure the cell นะครับ คือ การเซ็ตข้อความให้กับแถวนั้นเป็นชื่อสี โอเคทีนี้เราจะเอาชื่อของสีมาได้อย่างไร


จาก [listData objectAtIndex:indexPath.row] อันนี้จะได้ค่า object ที่อยู่ในแถวนั้นออกมา แต่เรายังไม่สามารถเรียกใช้ property title ได้โดยตรง เนื่องจาก object นั้นไม่ใช่ MyColor ดังนั้นเราต้องเปลี่ยนให้เป็น MyColor ก่อนโดยการใส่ (MyColor*) ไว้ด้านหน้าดังนี้


(MyColor*)[listData objectAtIndex:indexPath.row]


แล้วใส่วงเล็บครอบทั้งหมด ก็จะสามารถใช้งาน property หรือ method ของ MyColor ได้อย่างสมบูรณ์


5.3 การแสดง action  การกดรายการสีแล้วให้เปลี่ยนสีพื้นหลัง ในฟังก์ชั่น didSelectRowAtIndexPath


[sourcecode langauge="objc"]</p>
<p>- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{<br />
[self.view setBackgroundColor:((MyColor*)[listData objectAtIndex:indexPath.row]).color];<br />
}</p>
<p>[/sourcecode]


ฟังก์ชั่นที่ใช้เปลี่ยนสีพื้นหลังคือ [self.view setBackgroundColor:(UIColor*)] ส่วนค่าที่เราจะเอาใส่นั้นก้อคือ สีของ MyColor ตัวที่ถูกกดนั้นเอง​โดยเอามาจากค่า indexPath ที่จะบอก row และ section ส่วนสีของ MyColor ก้อเอามาจากการใช้ .color เมื่อเราเปลี่ยนจาก object เป็น MyColor แล้วเหมือนข้อ 5.2 ครับ


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




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



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



adaydesign :)

ไม่มีความคิดเห็น:

แสดงความคิดเห็น