【www.bbyears.com--ios】
常用控件之Picker View
实现的功能:演示Picker View的使用方法
关键词:Picker View
1、创建一个Single View Application工程,命名为:PickersDemo,如下图
2、修改ViewController.xib,添加一个Picker View和一个Button控件,如下
连接输出口、操作,如下
3、视图控制器ViewController,需要实现协议UIPickerViewDataSource、UIPickerViewDelegate中的必须实现的方法,
在工程目录依次展开 Frameworks->UIKit.framework->Headers,然后打开UIPickerView.h,在文件的尾部可以看到协议UIPickerViewDataSource、UIPickerViewDelegate的定义,如下
4、修改ViewController.h:
代码如下 #import#define kDeviceCategory 0 #define kDeviceName 1 @interface ViewController : UIViewController @property(strong,nonatomic)IBOutlet UIPickerView *picker; @property(nonatomic,retain)NSDictionary *appleDevices; @property(nonatomic,retain)NSArray *deviceCategory; @property(nonatomic,retain)NSArray *deviceName; -(IBAction)buttonPressed:(id)sender; @end
5、修改ViewController.m:
代码如下 #import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
@synthesize picker;
@synthesize appleDevices;
@synthesize deviceCategory;
@synthesize deviceName;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSArray *array1 = [NSArray arrayWithObjects:@"iPhone",@"iPad",@"iPod",nil];
NSArray *array2 = [NSArray arrayWithObjects:@"Mac",@"iMac",@"Mac Mini",@"Mac Pro",nil];
NSDictionary *dictionary= [NSDictionary dictionaryWithObjectsAndKeys:array1,@"Mobile",array2,@"Computers",nil];//注意用nil结束
appleDevices = [[NSDictionary alloc]initWithDictionary:dictionary copyItems:YES];
NSArray *components = [self.appleDevices allKeys];
NSArray *sorted = [components sortedArrayUsingSelector:@selector(compare:)];
self.deviceCategory = sorted;
NSString *selectedCategory = [self.deviceCategory objectAtIndex:0];
self.deviceName = [self.appleDevices objectForKey:selectedCategory];
}
- (void)viewDidUnload
{
[super viewDidUnload];
picker = nil;
appleDevices = nil;
deviceCategory = nil;
deviceName = nil;
// Release any retained subviews of the main view.
}
-(void)dealloc{
[picker release];
[appleDevices release];
[deviceCategory release];
[deviceName release];
}
-(IBAction)buttonPressed:(id)sender{
NSString *selectedCategory = [self.deviceCategory objectAtIndex:[self.picker selectedRowInComponent:kDeviceCategory]];
NSString *selectedDevice = [self.deviceName objectAtIndex:[self.picker selectedRowInComponent:kDeviceName]];
//NSLog(@"%@-%@",selectedCategory,selectedDevice);
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"结果" message:[NSString stringWithFormat:@"%@:%@",selectedCategory,selectedDevice] delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#pragma mark Picker View DataSource methods
// returns the number of "columns" to display.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 2;
}
// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
if(component == kDeviceCategory){
return [self.deviceCategory count];
}else{
return [self.deviceName count];
}
}
#pragma mark Picker View Delegate methods
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
if(component == kDeviceCategory){
return [self.deviceCategory objectAtIndex:row];
}else{
return [self.deviceName objectAtIndex:row];
}
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
if(component == kDeviceCategory){
NSString *selectedCategory = [self.deviceCategory objectAtIndex:row];
NSArray *array = [self.appleDevices objectForKey:selectedCategory];
self.deviceName = array;
[self.picker selectRow:0 inComponent:kDeviceName animated:YES];
[self.picker reloadComponent:kDeviceName];
}
}
@end
6、编译、运行,效果如下:
UITableView
这个不多讲!因为我自己开始被它折腾的晕晕的!后来仔细一琢磨才慢慢明白!
无非几个要素:
1.遵守协议
2.加载数据
3.设置必要的参数
4.单元格的内容定义
5.优化及交互
不太明白的时候多看看它的协议头文件中的定义:在工程目录依次展开 Frameworks->UIKit.framework->Headers,然后打开UITableView.h,搜索找到协议 UITableViewDataSource、UITableViewDelegate的定义
定义个可变的数组,作用是用来动态加载数据。
@property(nonatomic,retain)NSMutableArray *apps;
初始化:
{
[super viewDidLoad];
//加载数据
[self loadData];
}
//模拟加载数据
-(void)loadData{
apps = [[NSMutableArray alloc]init];
for(int i=0;i<8;i++){
[apps insertObject:[NSString stringWithFormat:@"App-%d",(i+1)] atIndex:i];
}
}
- (void)viewDidUnload
{
[super viewDidUnload];
apps = nil;
// Release any retained subviews of the main view.
}
-(void)dealloc{
[super dealloc];
[apps release];
}
#pragma mark table view datasource methods
//可选实现的方法,默认为1
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;{
return 1;
}
//必须实现的方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [apps count];
}
//必须实现的方法
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *myTableViewCellIdentifier = @"Cell";
UITableViewCell *cell = [[UITableView alloc]dequeueReusableCellWithIdentifier:myTableViewCellIdentifier];//备注1
if(cell==nil){
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:myTableViewCellIdentifier]; //备注2
}
NSString *imageName = [NSString stringWithFormat:@"%d",[indexPath row]+1];
cell.imageView.image = [UIImage imageNamed:imageName];
cell.textLabel.text = [apps objectAtIndex:[indexPath row]];
cell.textLabel.textAlignment = UITextAlignmentLeft;
cell.textLabel.font = [cell.textLabel.font fontWithSize:30];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
//可选实现的方法
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
return @"Header";
}
//可选实现的方法
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{
return @"Footer";
}
#pragma mark table view data delegate methods
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 50;
}
@end
备注1、备注2,代码解释:
1)表中的每一行都拥有一个子视图,即一个UITableViewCell类的实例
2)对于一个拥有大量数据的表,如果UITableView为表中的每一行都分配一个UITableViewCell的实例,而不管该行是否正在显示,这无疑将带来大量内容开销。当然,UITableView并不是这样设计的。
3)只有当前显示的行才被分配UITableViewCell的实例,因滚动操作已离开屏幕的表视图单元(UITableViewCell的实例)将被放置在一个可以被重用的单元序列中。
如果系统运行比较缓慢,表视图就从该序列中删除这些单元,以释放存储空间;
只要有可用的存储空间,表视图就会重新获取这些单元,以便以后再次使用。
4)//当一个表单视图滚出屏幕时,另一个表单视图就会从另一边滚动到屏幕上,如果滚动到屏幕上的新行重新使用从屏幕上滚动下来的那些单元格中的某一个单元格,系统就会避免与不断创建和释放那些视图相关的开销。
5)为了使用此机制,需要一个标识符(identifier)来标示可重用的单元格
6)表第一次初始化时肯定没有可重用的表单元,所以需要初始分配:
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:myTableViewCellIdentifier];
reuseIdentifier参数即标示该表单元可重用的标示符
ActionSheet与AlertView
先看下效果:
不多了,直接上代码啦!!
创建一个按钮,并且给他一个动作
//修改.h,实现UIActionSheetDelegate协议
@interface ViewController : UIViewController
实现操作delete,如下
UIActionSheet *actionSheet = [[UIActionSheet alloc]
initWithTitle:@"确定要删除该服务器?"
delegate:self //actionSheet的代理,按钮被按下时收到通知,然后回调协议中的相关方法
cancelButtonTitle:@"取消"
destructiveButtonTitle:@"确定"
otherButtonTitles:nil];
//展示actionSheet
[actionSheet showInView:self.view];
}
ViewController作为ActionSheet的代理,需要实现协议中定义的方法,有2中实现方法
方法一:实现didDismissWithButtonIndex,在ActionSheet消失后做提示处理
-(void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex{
NSLog(@"didDismissWithButtonIndex");
UIAlertView *alert = nil;
if(buttonIndex == [actionSheet destructiveButtonIndex]){//确定
//NSLog(@"确定");
alert = [[UIAlertView alloc]
initWithTitle:@"结果"
message:@"删除完毕"
delegate:self
cancelButtonTitle:@"确定"
otherButtonTitles:nil];
[alert show];
}else if(buttonIndex == [actionSheet cancelButtonIndex]){//取消
NSLog(@"取消");
}
}
方法二:实现clickedButtonAtIndex,在ActionSheet上的按钮被点击时做处理
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{
NSLog(@"clickedButtonAtIndex");
UIAlertView *alert = nil;
if(buttonIndex == [actionSheet destructiveButtonIndex]){//确定
//NSLog(@"确定");
//执行删除操作
[self doDelete];
alert = [[UIAlertView alloc]
initWithTitle:@"结果"
message:@"删除完毕"
delegate:self
cancelButtonTitle:@"确定"
otherButtonTitles:nil];
[alert show];
}else if(buttonIndex == [actionSheet cancelButtonIndex]){//取消
NSLog(@"取消");
}
}
两种方法都是通过buttonIndex判断当前点击的按钮,做不同处理演示方法,doDelete没有实现实际操作,如下
NSLog(@"执行删除操作");
}