首页 > 其他分享 >[iOS开发教程-1]Hello UITableView!

[iOS开发教程-1]Hello UITableView!

时间:2023-10-13 12:32:17浏览次数:39  
标签:your tableView iOS Hello UITableView our table data method


http://www.iphonedevcentral.com/hello-uitableview/

 

Hello UITableView!

Ok, let’s start with something really simple. We’ll be creating an app to keep track of your DVD library. The app will have a table view, a detail view and some basic navigational components.

Pre-requisites

I assume you have Xcode and iPhone SDK 3.x already installed (I’m using version Xcode 3.1, with 3.2 being the newest at the time of this writing). I also assume you know how to create a project so I’m not going to cover those little things here. Lastly, I assume you have some knowledge Objective-C , its principles, syntax and paradigms.

1. Set up your project

Create a “Navigation-based Application” and name it “TableViewApp.” Right off the bat, you’ll have an empty app, which is pretty much useless. You can run it using Cmd+R.

2. Create a dummy data set

Right-click on the Resources folder and choose Add -> New File. Under Other category, choose Property List . Name it TestData.plist. This is basically an XML file that will have an empty Dictionary in it by default. Change Dictionary to Array since we’re going to be adding numerous “DVDs” which will be described as individual Dictionaries .

 

You can add data to it by simply clicking the little button to the right of the Value column. We will be adding information about your DVD collection to it so the schema of your data set could be something like this:

  • Title – String
  • Cover image – String
  • Feature length  - Number (in minutes)
  • Release date – Date

Of course, this could be extended to more fields such as director, genre, aspect ratio, etc.

Following this schema, add a few items to your dummy data set. You’ll eventually want to have your file looking something like this:

If you don’t feel like typing all this info in, you can download the file here: TestData.plist .

 

3. Create a DAO (Data Access Object) to access your data

Right-click on the Classes folder and choose Add -> New File . Under Cocoa Touch Class category choose Objective-C class . Name it DvdLibraryDao .

This will be a very simple class that will take our dummy data file, read it in as a NSArray and provide some utility methods to access the data from the file.

First, let’s define our custom init method and some instance variables that will be needed for our implementation.


// Gets a plist name and reads in its contents as an array
@interface DvdLibraryDao : NSObject {
    NSString *libraryPlist;
    NSArray *libraryContent;
}
 
@property (nonatomic, readonly) NSString *libraryPlist;
@property (nonatomic, readonly) NSArray *libraryContent;
 
- (id)initWithLibraryName:(NSString *)libraryName;
- (NSDictionary *)libraryItemAtIndex:(int)index;
- (int)libraryCount;
 
@end


Next we create a custom initialization method, which will give us the name of the property list we want to read in. This code goes in your DvdLibraryDao.m file.


// Gets a plist name and reads in its contents as an array
 - (id)initWithLibraryName:(NSString *)libraryName {
    if (self = [super init]) {
        libraryPlist = libraryName;
        libraryContent = [[NSArray alloc] initWithContentsOfFile:[[NSBundle mainBundle]
                                                                  pathForResource:libraryPlist ofType:@"plist"]];
    }
    return self;
}


To retrieve information about a particular DVD, we’ll want a method that would access our array at a requested index and then returns the NSDictionary that contains the data we’re after. Add this method to DvdLibraryDao.m.


/ [Safely] returns a "DVD" from the plist. Each item in the data source is a dictionary containing data about
// the chosen DVD.
- (NSDictionary *)libraryItemAtIndex:(int)index {
    return (libraryContent != nil && [libraryContent count] > 0 && index < [libraryContent count])
        ? [libraryContent objectAtIndex:index]
        : nil;
}


The last method simply returns the count of DVDs in our data file.


// Returns the count of all DVDs in our library
- (int)libraryCount {
    return (libraryContent != nil) ? [libraryContent count] : 0;
}


4. Make your Table View read from the DAO

Now that we have a data source, let’s make our table read from it.

Add an instance variable to your RootViewController.h called dao of type DvdLibraryDao.


#import "DvdLibraryDao.h"
 
@interface RootViewController : UITableViewController {
    DvdLibraryDao *dao;
}
 
@end


We’ll initialize this variable in the viewWillAppear method that can be found in the implementation file of RootViewController .


- (void)viewWillAppear:(BOOL)animated {
    dao = [[DvdLibraryDao alloc] initWithLibraryName:@"TestData"];
 
}


TestData here is the name of the plist containing our data we created earlier.

To tell our table how many rows it has, we override the delegate method of UITableView called numberOfRowsInSection . All this method does is it returns the number of rows there are in the current section. We’ll cover sections later.


// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [dao libraryCount];
}


We’re calling the libraryCount method we’ve implemented earlier to get the number of DVDs in our library.

In the last step before we can run this project and see our records in the table, we tell the table what to display at each row. We do this in the delegate method cellForRowAtIndexPath.


// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
 
    static NSString *CellIdentifier = @"LibraryListingCell";
 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                       reuseIdentifier:CellIdentifier] autorelease];
    }
 
	cell.textLabel.text = [[dao libraryItemAtIndex:indexPath.row] valueForKey:@"title"];
 
    return cell;
}


One note about line #4 that might not be so obvious  - static NSString *CellIdentifier = @”LibraryListingCell” . Since tables can potentially have thousands of rows, the system memory consumed by creating all the rows at once would in the best case considerably slow down your table’s performance and in the worst case crash your application.

That’s why Apple introduced the concept of cell reuse. Behind the scenes, the system only creates the visible cells (and some) and as you start scrolling, it reuses the cells that are currently off screen to display the content that is on screen. By giving a cell an identifier, you’re basically marking it to be reused over and over again in your view instead of continuously creating new cells.

5. Add a title to the header

To add a title to the header of the table view, we simply add this line to the viewWillAppear method we overrode earlier.

self.title = @"My DVD Library";


6. See what it looks like so far

Run your project (in the simulator or on the device) and if everything is wired correctly, you should see something like this:

7. Create the Detail View

After a user selects one of the rows, we want them to go to a detail page where more information about the DVD is shown. We could simply use a UIView and add a bunch of UILable s to it to achieve this but since we’re covering UITableView in this tutorial, we’ll create another table.

(Note that this NOT how you’d want do it in a real-life app. I’m showing it strictly to demonstrate a grouped style table.)

Right-click on the Classes folder and choose Add -> New File again.  From Cocoa Touch Class category pick the Objective-C class and then choose UITableViewController from the subclass dropdown menu in the lower half of the window. This is different in Xcode 3.1 from previous versions where UITableViewController was simply a part of the presented classes. Name the file DetailViewController.

 

There are few things we need to do here. We’ll need some place to hold values of the labels used to describe our fields and also the actual values of the fields. For that, let’s create two instance variables of type NSMutableArray which we’ll later fill with appropriate data.

To properly initialize our data in the detail view, we’ll also need a custom init method. It is a modified version of initWithStyle that comes by default with UITableViewController .


@interface DetailViewController : UITableViewController {
    NSMutableArray *labels;
    NSMutableArray *values;
}
 
- (id)initWithStyle:(UITableViewStyle)style andDvdData:(NSDictionary *)dvdData;
 
@end


Let’s implement our custom init method:


- (id)initWithStyle:(UITableViewStyle)style andDvdData:(NSDictionary *)dvdData {
    if (self = [super initWithStyle:style]) {
        labels = [NSMutableArray new];
        values = [NSMutableArray new];
 
        // Set up labels which will become header titles
        [labels addObject:@"Title"];
        [labels addObject:@"Release Date"];
        [labels addObject:@"Length"];
 
        // Add now the values that correspond to each label
        [values addObject:[dvdData valueForKey:@"title"]];
        // We're faking formatting of date and length here simply dumping them as objects.
        // We should really convert the values to proper data types and then display them as strings.
        [values addObject:[NSString stringWithFormat:@"%@", [dvdData valueForKey:@"releaseDate"]]];
        [values addObject:[NSString stringWithFormat:@"%@ minutes", [dvdData valueForKey:@"featureLength"]]];
    }
    return self;
}


Each table header will display the label of our field (e.g.Title or Release Date). To do that, we’ll override UITableView ’s delegate method titleForHeaderInSection .


- (NSString *)tableView:(UITableView *)aTableView titleForHeaderInSection:(NSInteger)section {
	return [labels objectAtIndex:section];
}


Now we need to handle header and row counts as well as displaying actual values in our table rows.

The number of headers would correspond to the number of labels we want to display.


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return [labels count];
}


We’re going to cheat a little bit here. As I mentioned previously, a table view isn’t exactly the best choice to display this kind of data. The reason we’re going to return 1 as number of rows per section is because if we set it to the count of values, we would get duplicate values per each section. Instead of leaving the value as 1 , try setting it to [values count] and see what I mean.


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 1;
}

Finally, we set the cell textual value to each corresponding field.


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
 
    static NSString *CellIdentifier = @"DetailViewCell";
 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                       reuseIdentifier:CellIdentifier] autorelease];
    }
 
    cell.textLabel.text = [values objectAtIndex:indexPath.section];
 
    return cell;
}


8. Modify RootViewController to handle DetailViewController

As the last step, we’ll need to tell RootViewController to actually display DetailViewController when a row is pressed. We do that in the didSelectRowAtIndexPath delegate method.


// Override to support row selection in the table view.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // UITableViewStyleGrouped table view style will cause the table have a textured background
    // and each section will be separated from the other ones.
    DetailViewController *controller = [[DetailViewController alloc]
                                        initWithStyle:UITableViewStyleGrouped
                                        andDvdData:[dao libraryItemAtIndex:indexPath.row]];
    controller.title = [[dao libraryItemAtIndex:indexPath.row] valueForKey:@"title"];
    [self.navigationController pushViewController:controller animated:YES];
    [controller release];
}


One more detail. When we return back to RootViewController from DetailViewController, we’ll want to deselect the row that had been pressed. To do so, we modify the viewWillAppear method.


- (void)viewWillAppear:(BOOL)animated {
    dao = [[DvdLibraryDao alloc] initWithLibraryName:@"TestData"];
    self.title = @"My DVD Library";
    [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
}


If everything went well, re-running the project and tapping on one of the rows should show you the detail view table that should look like this:

 

Conclusion

Hopefully this tutorial has given you a good starting point for creating your own app. The next steps could be replacing the static plist file with a Core Data store or maybe pull the data from a remote XML file. Also, the DetailViewController should really be a subclass of UIView that would provide a lot more flexibility in laying out your data.

You can download a finished version of this project here: My DVD Library Xcode Project .

 

 

 

 

 

标签:your,tableView,iOS,Hello,UITableView,our,table,data,method
From: https://blog.51cto.com/u_16125990/7843912

相关文章

  • Flutter 开发第一个 IOS 真机 APP
    准备工作安装fluterSDK安装xcode注册一个appId安装intellijideafluterSDK启用rosettaMac(M2)sudosoftwareupdate--install-rosetta--agree-to-license下载SDKhttps://storage.flutter-io.cn/flutter_infra_release/releases/stable/macos/flutter_ma......
  • 22 axios和axios拦截器
    1.axios由于jquery有严重的地狱回调逻辑.再加上jquery的性能逐年跟不上市场节奏.很多前端工程师采用axios来发送ajax.相比jquery.axios更加灵活.且容易使用.更加美丽的是.这玩意是用promise搞的.所以更加贴合大前端的项目需求.来吧.上手试试吧<scriptsrc="/static/......
  • Linux之iostat
    Linux之iostat前言iostat主要用于监控系统设备的IO负载情况。iostat首次运行时显示自系统启动开始的各项统计信息,之后运行iostat将显示自上次运行该命令以后的统计信息。用户可以通过指定统计的次数和时间来获得所需的统计信息。1.命令功能:通过iostat方便查看CPU、网卡、tty......
  • HelloWorld
    publicclassHelloWorld{publicstaticvoidmain(String[]args){System.out.println("Hello,World!");//单行注释//输出一个Hello,World!//有趣的代码注释//多行注释:可注释一段文字/*注释*//*我是多......
  • AXIOS测试
    AXIOS  1.注册测试1<!DOCTYPEhtml>2<htmllang="en">3<head>4<metacharset="UTF-8">5<metaname="viewport"content="width=device-width,initial-scale=1.0">6&l......
  • 安防视频监控平台EasyCVR集成到ios系统不能播放是什么原因?如何解决?
    视频监控TSINGSEE青犀视频平台EasyCVR能在复杂的网络环境中,将分散的各类视频资源进行统一汇聚、整合、集中管理,在视频监控播放上,TSINGSEE青犀视频安防监控汇聚平台可支持1、4、9、16个画面窗口播放,可同时播放多路视频流,也能支持视频定时轮播。视频监控汇聚平台EasyCVR支持多种播放......
  • Hello, Solitude.
    考虑任意时刻区间均为奇数的情况观察到一个区间被取到的概率与区间外的具体状态无关,只与区间外取了多少次有关,因此考虑计算一个区间被选中后的出现次数,设\(dp_{[l,r],t}\)表示区间\([l,r]\)在剩余\(t\)次入座时被选中的最终所有状态的出现次数之和,贡献加入中点\(ans_{mid}......
  • 在ts时使用axios请求类型定义增加属性
    1.需求在后台请求中有一些请求数据量比较大无法一下返回,需要增加loading动画,为了方便控制想在请求的时候增加一个参数isLoading,默认关闭,传真值时开启动画。这便需要拓展axios中增加个性化参数配置。但是如何进行类型的定义呢?2.操作 如上,在做左边增加了isLoading参数,代码......
  • iOS原生集成Cordova后再集成插件流程
    假设你已经在原生工程(取名native)上成功集成Cordova,参考官方文档往项目再集成插件步骤如下使用Cordova创建一个新iOS项目(取名demo)在demo里面安装你想要的插件,以device为例cordovapluginaddcordova-plugin-device这时我们发现demo工程里成功安装了device插件,接下来我......
  • Jenkins 配置MAC节点,编译iOS项目
     文章主要介绍Jenkins主从节点配置,mac机配置slave节点。从机已经搭建android和ios编译环境为例,介绍Jenkins节点配置。环境介绍主机环境介绍:主机Jenkins运行在tomcat中。Jenkins本身安装的环境仅包括java环境和gradle环境。#setjavaenvironmentexportJAVA_HOME=/usr......