iOS开发中的图像选择、键盘设置与选择器应用
1. 图像选择器(Image Picker)
1.1 图像源定义
可以使用
sourceType
属性来定义向用户展示的各种图像源,示例代码如下:
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
支持的图像源类型如下表所示:
| 类型 | 描述 |
| ---- | ---- |
| UIImagePickerControllerSourceTypePhotoLibrary | 照片库 |
| UIImagePickerControllerSourceTypeCamera | 相机 |
| UIImagePickerControllerSourceTypeSavedPhotosAlbum | 已保存的照片 |
1.2 图像编辑功能
若要允许用户按照自己的喜好移动和缩放图像,可通过将
allowsImageEditing
属性设置为
YES
来启用图像编辑功能,代码如下:
picker.allowsImageEditing = YES;
1.3 图像选择处理
当用户选择一张图片时,选择器的委托(delegate)会通过
didFinishPickingImage
方法得到通知。委托会接收到一个包含图像的
UIImage
对象,以及一个包含编辑属性的
NSDictionary
对象(如果启用了编辑功能)。
设置选择器的委托:
picker.delegate = self;
在委托类中添加以下方法以在用户选择图像时得到通知:
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingImage:(UIImage *)image
editingInfo:(NSDictionary *)editingInfo
{
/* Code to handle image selection */
}
若用户取消图像选择,也希望得到通知,则可在委托中添加
imagePickerControllerDidCancel
方法:
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
/* Additional code to handle image selection canceled */
}
2. 键盘属性设置
2.1 键盘设计理念
当用户点击文本字段时,运行时会自动弹出键盘供用户输入。苹果的框架设计使得文本字段对键盘的行为拥有完全的控制权,而不是键盘对象本身。当键盘出现时,它会自动适应文本字段中定义的行为。
2.2 键盘样式
UI Kit框架支持八种不同的键盘样式,可使用文本对象的
keyboardType
方法为每个文本字段分配不同的样式,示例代码如下:
textView.keyboardType = UIKeyboardTypePhonePad;
支持的键盘样式如下表所示:
| 样式 | 描述 |
| ---- | ---- |
| UIKeyboardTypeDefault | 默认键盘:所有字符可用 |
| UIKeyboardTypeASCIICapable | 支持ASCII的默认键盘 |
| UIKeyboardTypeNumbersAndPunctuation | 标准电话键盘,支持 + * # 符号 |
| UIKeyboardTypeURL | 带有.COM按钮的URL键盘;仅支持URI字符 |
| UIKeyboardTypeNumberPad | 用于数字输入的数字键盘 |
| UIKeyboardTypePhonePad | 用于输入电话号码的电话键盘 |
| UIKeyboardTypeNamePhonePad | 也支持输入姓名的电话键盘 |
| UIKeyboardTypeEmailAddress | 用于输入电子邮件地址的键盘 |
2.3 键盘外观
除了键盘类型,还可以通过设置
keyboardAppearance
属性来调整键盘的外观,示例代码如下:
textView.keyboardAppearance = UIKeyboardAppearanceDefault;
可用的键盘外观如下表所示:
| 样式 | 描述 |
| ---- | ---- |
| UIKeyboardAppearanceDefault | 默认外观;浅灰色 |
| UIKeyboardAppearanceAlert | 深灰色/石墨色 |
2.4 返回键样式
对于带有返回键的键盘,可以使用文本对象的
returnKeyType
属性为返回键分配各种样式,示例代码如下:
textView.returnKeyType = UIReturnKeyGo;
支持的返回键样式如下表所示:
| 样式 | 描述 |
| ---- | ---- |
| UIReturnKeyDefault | 默认:灰色的“Return”按钮 |
| UIReturnKeyGo | 蓝色的“Go”按钮 |
| UIReturnKeyGoogle | 蓝色的“Google”按钮,用于搜索 |
| UIReturnKeyJoin | 蓝色的“Join”按钮 |
| UIReturnKeyNext | 灰色的“Next”按钮 |
| UIReturnKeyRoute | 蓝色的“Route”按钮 |
| UIReturnKeySearch | 蓝色的“Search”按钮 |
| UIReturnKeySend | 蓝色的“Send”按钮 |
| UIReturnKeyYahoo | 蓝色的“Yahoo!”按钮,用于搜索 |
| UIReturnKeyDone | 蓝色的“Done”按钮 |
| UIReturnKeyEmergencyCall | 紧急呼叫按钮 |
2.5 自动大写功能
键盘可以自动将新行或句子的首字母大写。可以通过设置文本对象的
autocapitalizationType
属性来切换此功能,示例代码如下:
textView.autocapitalizationType = UITextAutocapitalizationTypeNone;
支持的自动大写类型如下:
- UITextAutocapitalizationTypeNone
- UITextAutocapitalizationTypeWords
- UITextAutocapitalizationTypeSentences
- UITextAutocapitalizationTypeAllCharacters
2.6 自动更正功能
输入文本时,文本视图和键盘对象会协同工作,根据内部的常用误拼单词字典和记录用户自己输入的打字缓存,提供可能的打字错误更正。iPhone在
/private/var/mobile/Library/Keyboard/dynamic-text.dat
中生成字典。
自动更正功能默认启用,但可以使用文本视图的
autocorrectionType
属性来切换此功能,示例代码如下:
textView.autocorrectionType = UITextAutocorrectionTypeDefault ;
可用的自动更正类型如下:
- UITextAutocorrectionTypeDefault
- UITextAutocorrectionTypeNo
- UITextAutocorrectionTypeYes
2.7 安全文本输入
当在文本窗口中输入密码或其他私人数据时,这些信息不应被缓存在iPhone中。开启安全文本输入会禁用文本字段的自动更正和单词缓存功能。要激活安全文本模式,可设置
secureTextEntry
属性,示例代码如下:
textView.secureTextEntry = YES;
3. 选择器(Pickers)
3.1 选择器概述
选择器是iPhone上的滚轮控件,是大型的旋转拨盘,可以容纳任意数量的不同选项。选择器用于替代下拉菜单,为用户提供图形丰富的选择界面。
UIPickerView
类被设计为一个完整的视图类,而不是一个控件,这是由于其复杂性和占用的屏幕空间。这使得可以将选择器附加到其他视图或窗口上。
3.2 创建选择器
UIPickerView
类在屏幕上占用320×216像素的空间,但可以在窗口中垂直偏移。与表格类似,
UIPickerView
类使用数据源;但与表格不同的是,选择器不使用索引路径,而是通过
NSInteger
值引用每一行。选择器可以有多个拨盘,每个拨盘称为一个组件。
创建选择器的示例代码如下:
UIPickerView *pickerView = [ [ UIPickerView alloc ]
initWithFrame: CGRectMake(0.0, 280.0, 0.0, 0.0)];
pickerView.delegate = self;
pickerView.dataSource = self;
3.3 选择器属性设置
选择器视图的许多属性在SDK中已被私有化,开发者对其的控制不如内部类那么多。选择器有切换声音、进行多项选择和进行美学调整等可变选项,但这些接口对SDK开发者不可用。唯一可用的美学选项是选择窗口。
若要在当前选择上显示一个半透明窗口,可将选择器的
showsSelectionIndicator
属性设置为
YES
,示例代码如下:
pickerView.showsSelectionIndicator = YES;
3.4 选择器数据源方法
创建选择器视图后,必须编写数据源代码来提供有关选择器构造的信息。构建数据源需要实现以下方法,这些方法是
UIPickerViewDataSource
协议的必需组件:
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A([开始]):::startend --> B(创建选择器视图):::process
B --> C(实现数据源方法):::process
C --> D(numberOfComponentsInPickerView):::process
C --> E(numberOfRowsInComponent):::process
D --> F(定义显示的组件数量):::process
E --> G(返回指定组件的行数):::process
F --> H(完成数据源配置):::process
G --> H
H --> I([结束]):::startend
-
numberOfComponentsInPickerView:定义选择器视图要显示的单个滚轮(列)的数量。 -
numberOfRowsInComponent:可以为选择器中的每个拨盘分配不同数量的可能值(行)。此方法应返回指定拨盘的总行数。
此外,
UIPickerViewDelegate
协议实现了以下方法来获取有关选择器组件的特定信息:
-
titleForRow
:返回给定拨盘(组件)的给定行的实际拨盘值,这些值以
NSString
对象的形式返回。
-
viewForRow
:此方法可以覆盖选择器的默认行为,以在组件拨盘中显示任何
UIView
类。
-
widthForComponent
:返回给定组件(拨盘)的宽度。如果未实现此方法,选择器将自适应大小。
-
rowHeightForComponent
:返回给定组件(拨盘)的高度。如果未实现此方法,选择器将自适应大小。
3.5 显示选择器
创建并配置选择器视图并编写数据源方法后,就可以将选择器附加到视图控制器上,示例代码如下:
[ self.view addSubview: pickerView ];
3.6 读取选择器的选择
获取选择器视图中所选列索引的最直接方法是使用视图的
selectedRowInComponent
方法,示例代码如下:
int selectedRow = [ pickerView selectedRowInComponent: 0 ];
还有一个委托方法,每当用户在选择器视图中选择一行时,该方法会得到通知。可以使用此方法提醒一个对象,使其能够对新的行选择做出响应,示例代码如下:
pickerView.delegate = myObject;
要在拨盘的值更改时收到通知,可以在类中添加以下名为
didSelectRow
的委托方法:
- (void)pickerView:(UIPickerView *)pickerView
didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
NSLog(@"Selected row %d from dial %d", row, component);
/* Additional code to handle row selection */
}
3.7 鼻子选择器示例(NosePicker)
此示例向用户展示一个包含不同鼻子样式和大小的
UIPickerView
。首先创建一个视图控制器,然后将选择器视图作为子视图添加到该控制器中。用户可以滚动鼻子列表并选择一个。
以下是该示例的主要代码:
3.7.1 NosePickerAppDelegate.h
#import <UIKit/UIKit.h>
@class NosePickerViewController;
@interface NosePickerAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
NosePickerViewController *viewController;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet NosePickerViewController *viewController;
@end
3.7.2 NosePickerAppDelegate.m
#import "NosePickerAppDelegate.h"
#import "NosePickerViewController.h"
@implementation NosePickerAppDelegate
@synthesize window;
@synthesize viewController;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
CGRect screenBounds = [ [ UIScreen mainScreen ] bounds ];
self.window = [ [ [ UIWindow alloc ] initWithFrame: screenBounds ] autorelease ];
viewController = [ [ NosePickerViewController alloc ] init ];
[ window addSubview: viewController.view ];
[ window makeKeyAndVisible ];
}
- (void)dealloc {
[ viewController release ];
[ window release ];
[ super dealloc ];
}
@end
3.7.3 NosePickerViewController.h
#import <UIKit/UIKit.h>
@protocol UIPickerViewDataSource, UIPickerViewDelegate;
@interface NosePickerViewController : UIViewController <UIPickerViewDelegate,
UIPickerViewDataSource> {
UIPickerView *pickerView;
UITextView *textView;
NSMutableArray *noses;
NSMutableArray *sizes;
int selection[2];
}
- (void)updateText;
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;
- (NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component;
- (NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row forComponent:(NSInteger)component;
- (void)pickerView:(UIPickerView *)pickerView
didSelectRow:(NSInteger)row inComponent:(NSInteger)component;
@end
3.7.4 NosePickerViewController.m
#import "NosePickerViewController.h"
@implementation NosePickerViewController
- (id)init {
self = [ super init ];
if (self != nil) {
noses = [ [ NSMutableArray alloc ] init ];
[ noses addObject: @"Straight" ];
[ noses addObject: @"Aquiline" ];
[ noses addObject: @"Retrousse" ];
[ noses addObject: @"Busque" ];
[ noses addObject: @"Sinuous" ];
[ noses addObject: @"Melanesian" ];
[ noses addObject: @"African" ];
sizes = [ [ NSMutableArray alloc ] init ];
[ sizes addObject: @"Small" ];
[ sizes addObject: @"Medium" ];
[ sizes addObject: @"Large" ];
[ sizes addObject: @"Super-Size" ];
selection[0] = selection[1] = 0;
}
return self;
}
- (void)loadView {
CGRect bounds = [ [ UIScreen mainScreen ] applicationFrame ];
[ super loadView ];
pickerView = [ [ UIPickerView alloc ]
initWithFrame: CGRectMake(0.0, bounds.size.height - 216.0, 0.0, 0.0)
];
pickerView.delegate = self;
pickerView.dataSource = self;
pickerView.showsSelectionIndicator = YES;
[ self.view addSubview: pickerView ];
textView = [ [ UITextView alloc ] initWithFrame:
CGRectMake(0.0, 0.0, bounds.size.width, bounds.size.height - 216.0)
];
textView.font = [ UIFont fontWithName: @"Arial" size: 18.0 ];
textView.textAlignment = UITextAlignmentCenter;
textView.editable = NO;
[ self updateText ];
[ self.view addSubview: textView ];
}
- (void)updateText {
textView.text = [ NSString stringWithFormat:
@"One %@, %@ schnoz:\nComing right up!\n",
[ sizes objectAtIndex: selection[1] ],
[ noses objectAtIndex: selection[0] ]
];
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 2;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component
{
switch(component) {
case(0):
return [ noses count ];
break;
case(1):
return [ sizes count ];
break;
}
return 0;
}
- (NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
switch (component) {
case(0):
return [ noses objectAtIndex: row ];
break;
case(1):
return [ sizes objectAtIndex: row ];
}
return nil;
}
- (void)pickerView:(UIPickerView *)pickerView
didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
selection[component] = row;
[ self updateText ];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)didReceiveMemoryWarning {
[ super didReceiveMemoryWarning ];
}
- (void)dealloc {
[ pickerView release ];
[ noses release ];
[ sizes release ];
[ super dealloc ];
}
@end
3.7.5 main.m
#import <UIKit/UIKit.h>
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, @"NosePickerAppDelegate");
[pool release];
return retVal;
}
3.8 鼻子选择器示例流程分析
-
应用程序实例化时,会创建一个新的视图控制器,该控制器会初始化一个鼻子样式数组和一个鼻子大小数组,并为当前选择的拨盘初始化变量存储,存储在
selection中。 -
当视图控制器的
loadView方法被调用时,会创建UIPickerView和UITextView对象,并将它们作为子视图添加到视图控制器中。选择器视图的委托和数据源被设置为视图控制器。控制器的updateText方法会被调用一次,以设置文本视图中的文本。 -
UIPickerView类的内部机制会调用其数据源,数据源会返回选择器视图中的组件数量、行数和每行的标题。 -
当用户在选择器视图的任何一个拨盘上选择一个新项时,视图的委托(即视图控制器)会通过
pickerView didSelectRow方法得到通知。这会更新给定拨盘的最后选择行,并刷新文本显示,以反映当前选择的鼻子和大小组合。
4. 日期/时间选择器(Date/Time Pickers)
4.1 日期/时间选择器概述
UIDatePicker
类是一个控件,它封装并定制了
UIPickerView
类,专门用于接受日期、时间和持续时间输入。日期选择器会自动配置其列以符合指定的样式,因此在配置拨盘时无需进行底层工作,还可以为任何日期范围进行定制。
UIDatePicker
严重依赖
NSDate
类,该类是桌面Cocoa中使用的基础类集的一部分。可以在苹果开发者连接网站的在线Cocoa参考中找到有关此类的更多信息。为了便于示例,我们使用其最简单的方法
initWithString
来创建一个
NSDate
对象:
NSDate *myDate = [ [ NSDate alloc ]
initWithString: @"1963-11-22 12:30:00 −0500" ];
4.2 创建日期/时间选择器
UIDatePicker
比标准的
UIPickerView
更简单,它会根据指定的日期范围构建自己的数据源。使用时只需创建对象即可,示例代码如下:
UIDatePicker *datePicker = [ [ UIDatePicker alloc ]
initWithFrame: CGRectMake(0.0, 0.0, 0.0, 0.0)];
默认情况下,选择器会显示当前日期和时间,并显示星期几、月、日、小时、分钟和上午/下午的拨盘。用户默认可以选择任何日期或时间组合。
4.3 日期选择器模式
日期/时间选择器支持四种不同的选择模式,可以通过设置
datePickerMode
属性来定义模式,示例代码如下:
datePicker.datePickerMode = UIDatePickerModeTime;
支持的模式如下表所示:
| 模式 | 描述 |
| ---- | ---- |
| UIDatePickerModeTime | 小时、分钟和上午/下午选择 |
| UIDatePickerModeDate | 月、日和年 |
| UIDatePickerModeDateAndTime | 默认;星期几 + 月 + 日、小时、分钟和上午/下午选择 |
| UIDatePickerModeCountDownTimer | 用于计时器的小时和分钟显示 |
4.4 时间间隔设置
可以将分钟拨盘设置为以各种间隔显示分钟,只要该间隔能被60整除即可。默认情况下,分钟拨盘以一分钟的间隔显示。若要使用不同的间隔,可以将
minuteInterval
属性设置为所需的间隔,示例代码如下:
datePicker.minuteInterval = 10;
4.5 日期范围设置
可以通过设置
minimumDate
和
maximumDate
属性来指定允许的日期范围。如果用户尝试滚动到超出此范围的日期,拨盘将滚动回最近的有效日期。这两个方法都期望传入一个
NSDate
对象,示例代码如下:
NSDate *minDate = [ [ NSDate alloc ]
initWithString: @"1773-12-16 12:00:00 −0500" ];
NSDate *maxDate = [ [ NSDate alloc ]
initWithString: @"1776-07-04 12:00:00 −0500" ];
datePicker.minimumDate = minDate;
datePicker.maximumDate = maxDate;
如果这两个日期范围属性中的一个或两个都未设置,默认行为将允许用户选择任何过去或未来的日期。例如,在选择生日时,生日可以是过去的任何日期,但上限为当前日期,这种设置就很有用。
若要设置默认显示的日期,可以设置
date
属性,示例代码如下:
datePicker.date = minDate;
也可以使用
setDate
方法。如果选择动画效果,拨盘将滚动到指定的日期,示例代码如下:
[ datePicker setDate: maxDate animated: YES ];
4.6 显示日期选择器
创建日期选择器后,可以使用与
UIPickerView
相同的方法将其附加到视图对象上,示例代码如下:
[ self addSubview: datePicker ];
无论传递给它的框架大小如何,选择器的高度始终为216像素,因此需要确保分配了足够的屏幕空间来容纳它。
4.7 日期/时间选择器使用流程
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A([开始]):::startend --> B(创建NSDate对象):::process
B --> C(创建UIDatePicker对象):::process
C --> D(设置日期选择器模式):::process
D --> E(设置时间间隔):::process
E --> F(设置日期范围):::process
F --> G(设置默认显示日期):::process
G --> H(将日期选择器添加到视图):::process
H --> I([结束]):::startend
5. 总结与拓展
5.1 功能总结
本文详细介绍了iOS开发中图像选择器、键盘属性设置、选择器以及日期/时间选择器的使用方法。图像选择器可以让用户从不同的图像源中选择图像,并支持图像编辑功能;键盘属性设置提供了丰富的自定义选项,包括键盘样式、外观、返回键样式、自动大写、自动更正和安全文本输入等;选择器和日期/时间选择器为用户提供了直观的选择界面,方便用户进行各种选项和日期时间的选择。
5.2 拓展建议
- 图像选择器拓展 :可以结合图像裁剪、滤镜等功能,进一步丰富图像编辑体验;还可以实现图像的上传和分享功能。
- 键盘属性拓展 :可以根据不同的应用场景,动态调整键盘的样式和属性,以提高用户输入的效率和体验。
-
选择器拓展
:可以使用
UIPickerView.h原型中提供的替代数据源方法,返回UIView对象而不是NSString对象,从而创建一组自定义的UIImageView对象用于选择器。 - 日期/时间选择器拓展 :可以结合日历视图,让用户更直观地选择日期;还可以实现日期时间的计算和提醒功能。
通过对这些功能的深入理解和灵活运用,可以开发出更加丰富、易用的iOS应用程序。希望本文能为iOS开发者在UI设计和用户交互方面提供有价值的参考。
超级会员免费看
1150

被折叠的 条评论
为什么被折叠?



