1.2 UISwitch创建和使用开关
问题
你想给你的用户打开一个选项或关闭的能力。
??????
解
使用UISwitch类。
讨论该UISwitch类提供像在图1-7为自动大写,自动校正,等等所示的开/关控制。
图1-7。UISwitch用在iPhone上的应用程序的设置
为了创建一个开关,你可以使用Interface Builder或者干脆在代码中创建的实例。让我们通过代码做到这一点。所以,接下来的挑战是确定放置哪个类的代码,它需要在一个视图控制器类,我们还没有讨论,但对于应用程序的单一视图的应用程序类型,我们正在创造的这个家伙 - 器,你可以找到视图控制器的.m(实现)文件ViewController.m。现在打开该文件。
让我们来创建一个类型UISwitch的属性和调用它mainSwitch:
#import "ViewController.h" @interface ViewController () ????? @property (nonatomic, strong) UISwitch *mainSwitch; @end @implementation ViewController ...
我们现在可以继续创建我们的开关。找到你的视图控制器的实现文件的viewDidLoad方法:
- (void)viewDidLoad{ [super viewDidLoad]; }
让我们来创建我们的开关,将它放在我们的视图控制器的view:
- (void)viewDidLoad{ [super viewDidLoad]; /* Create the switch */ self.mainSwitch = [[UISwitch alloc] initWithFrame: CGRectMake(100, 100, 0, 0)]; [self.view addSubview:self.mainSwitch]; }
接下来,我们分配类型UISwitch的对象,并使用initWithFrame:方法初始化初始化我们的开关。需要注意的是,我们要传递给此方法的参数的类型CGRect的。甲CGRect表示一个矩形的使用矩形,其宽度与高度的左上角的第(x,y)的位置的边界。我们可以使用CGRectMake联方法,其中前两个参数传递给该方法的第(x,y)的位置上,并在接下来的两个是矩形的宽度和高度,构造一个CGRect。
之后,我们已经创建了开关,我们只需将其添加到视图控制器的视图。现在,让我们运行在iOS模拟器应用程序。图1-8显示会发生什么。
正如你所看到的,开关的默认状态是关闭的。我们可以通过改变UISwitch实例的属性的值更改。在交开关上的方法,如下所示:另外,您可以通知seton:
[self.mainSwitch setOn:YES];
你可以通过使用开关的setOn:animated: 美化的用户交互。
动画参数接受一个布尔值。如果该布尔值设置为YES,在开关的状态变化(从开到关或关上),启用动画,就好像被用户与其进行交互。
很明显,可以从开关的接通属性读找出开关是否处于打开或关闭。或者,您也可以使用交开关的ison方法,如下所示:
if ([self.mainSwitch isOn]){ NSLog(@"The switch is on."); }else{ NSLog(@"The switch is off."); }
如果你想获得通知当开关被打开或关闭,你将需要添加开关的target ,addTarget:action:forControlEvents: UISwitch的方法,如下所示:
[self.mainSwitch addTarget:self action:@selector(switchIsChanged:)
forControlEvents:UIControlEventValueChanged];
然后实现switchIsChanged:方法。当运行时调用开关的UIControlEventValueChanged,event会通过在开关作为参数传递给这个方法,这样你就可以找出哪个开关已被触发这个事件:
- (void) switchIsChanged:(UISwitch *)paramSender{ NSLog(@"Sender is = %@", paramSender); if ([paramSender isOn]){ NSLog(@"The switch is turned on."); }else{ NSLog(@"The switch is turned off."); } }
现在继续运行在iOS模拟器的应用程序。你会看到类似这样的消息在控制台窗口:
Sender is = <UISwitch: 0x6e13500; frame = (100 100; 79 27); layer = <CALayer: 0x6e13700>> The switch is turned off. ? Sender is = <UISwitch: 0x6e13500; frame = (100 100; 79 27); layer = <CALayer: 0x6e13700>> The switch is turned on.
1.3自定义UISwitch问题
你已经把UISwitch放在UI上,现在想对其进行自定义以满足您的UI。
解
使用UISwitch,的色彩/图像的定制属性之一,如色调的颜色或onTintColor。
讨论
苹果已经做了将定制的UI组件,如UISwitch了出色的工作。在先前的软件开发工具包,开发者只要子类UISwitch只是以改变其外观和颜色去。现在的iOS SDK使这要简单得多。
有一个自定义开关的两种主要方式:
色调颜色
色调的颜色的颜色,你可以应用到用户界面组件,如UISwitch。着色颜色将在组件的当前颜色的顶部施加。例如,在正常的UISwitch,你就可以看到不同的颜色。当应用着色颜色之上,控制的正常颜色将与色调色混合,得到关于UI控制色调的颜色的风味。
图片
一个开关具有两个图像:
在图像
表示开关的接通状态中的图像。此图像的宽度为77点,并且其高度为22。
关图片
它表示在其断开状态的开关的图像。这个图象,像在开关的状态下,是77个宽度和高度22点。
图1-9示出了开和关的开关的图像的一个例子。
图1-9。上一个UISwitch的开和关的图像
现在我们知道了两种状态(开和关)开关的,让我们通过学习,我们怎样才能改变开关的UI组件的色调颜色开始。这可通过使用的UISwitch类的三个重要的属性来实现。每一个这种属性的类型的UIColor的。
tintColor
这是将被施加到开关的关断状态下的色调的色彩。不幸的是,苹果并没有花时间去此属性名称offTintColor而不是色调的颜色,使之更加明确。
thumbTintColor
这是将被施加到开关上的小旋钮着色颜色。
?1.3。自定义UISwitch|37
onTintColor
此着色颜色将被施加到开关处于导通状态。
下面是一个简单的代码片段,将改变开关的导通模式色调颜色为红色时,关闭模式下色彩色至褐色,而旋钮的颜色色调为绿色。这不是色的最佳组合,但会表现出什么这个配方是试图解释:
- (void)viewDidLoad { [super viewDidLoad]; /* Create the switch */ self.mainSwitch = [[UISwitch alloc] initWithFrame:CGRectZero]; self.mainSwitch.center = self.view.center; [self.view addSubview:self.mainSwitch]; /* Customize the switch */ /* Adjust the off-mode tint color */ self.mainSwitch.tintColor = [UIColor redColor]; /* Adjust the on-mode tint color */ self.mainSwitch.onTintColor = [UIColor brownColor]; /* Also change the knob's tint color */ self.mainSwitch.thumbTintColor = [UIColor greenColor]; }
现在,我们正用色调的颜色在上完成的,让我们继续利用其在定制开关的外观和关闭图像,同时考虑到自定义的开启和关闭图像只适用于iOS6或以上。 iOS的7忽略和关闭图像,并且只使用色调的颜色来定制它的外观。如之前提到的那样,无论是上和断开的图像中的开关应宽和22分高大77点。对于这一点,我已经准备了一套新的开启和关闭图像(在正常和视网膜分辨率)。我加入他们我的Xcode项目下On@2x.png和Off@2x.png的(视网膜)的名字和我也放在同一个图像的非视网膜的味道项目。现在我们要建立我们的开关,但开启和关闭图像交换机指定我们的自定义,使用上UISwitch以下属性:
onImage
如之前所解释的,这将是该图像时,开关处于其上模式显示的。
offImage
表示该开关,当它处于关闭模式时的图像。
这里是我们的代码片段实现这一崭新的面貌:
- (void)viewDidLoad { [super viewDidLoad]; /* Create the switch */ self.mainSwitch = [[UISwitch alloc] initWithFrame:CGRectZero]; self.mainSwitch.center = self.view.center; /* Make sure the switch won't appear blurry on iOS Simulator */ self.mainSwitch.frame = [self roundedValuesInRect:self.mainSwitch.frame]; [self.view addSubview:self.mainSwitch]; /* Customize the switch */ self.mainSwitch.onImage = [UIImage imageNamed:@"On"]; self.mainSwitch.offImage = [UIImage imageNamed:@"Off"]; }
1.4。采摘值的UIPickerView
问题
你要允许你的应用程序的用户从值列表中进行选择。
解
使用UIPickerView类。讨论
一个选择器视图是一个图形元素,让您展示一系列值给用户,让他们挑一。在iPhone上的时钟应用程序的定时器部分是这个(图1-10),一个很好的例子。
图1-10。在屏幕顶部的选择器视图
正如你所看到的,这个特定的选择器视图有两个独立的,独立的视觉元素求。一个是在左边,一个在右边。左边的元件被显示时(例如0,1,2小时等)与一个在右边显示的是分钟(如10,11,12分钟等)。这两个项目被称为组件。每个部件都有行。中的任何组件的任何项实际上由行表示的,正如我们将很快看到。例如,在左侧的元件,“0小时”是行中,“1”是一个行等
让我们继续创建我们的视图控制器的视图选择器视图。如果你不知道你的视图控制器的源代码,请看看食谱1.2,在这个问题进行了讨论。
首先,让我们去我们的视图控制器的.M(执行)文件的顶部,并确定我们的选择器视图:
@interface ViewController () @property (nonatomic, strong) UIPickerView *myPicker; @end @implementation ViewController ... Now let’s create the picker view in the viewDidLoad method of our view controller: - (void)viewDidLoad{ [super viewDidLoad]; self.myPicker = [[UIPickerView alloc] init];
self.myPicker.center = self.view.center; [self.view addSubview:self.myPicker]; }
值得注意的是,在这个例子中,我们围绕我们的选择器视图在我们视野的中心。当您运行在iOS7模拟器这个应用程序,你会看到一个空白的屏幕,因为在iOS7的选择器是白色的,所以是视图控制器的背景下。
这个选择器视图显示为纯白色的原因是,我们还没有填充它的任何值。让我们做到这一点。我们做到这一点通过指定数据源选择器视图,然后确保我们的视图控制器木棍到数据源需要的协议。 UIPickerView的一个实例的数据源必须符合UIPickerViewDataSource协议,所以让我们继续前进,使我们的视图控制器符合本协议中的.m文件:
@interface ViewController () <UIPickerViewDataSource, UIPickerViewDelegate> @property (nonatomic, strong) UIPickerView *myPicker; @end @implementation ViewController
不错。现在,让我们改变我们的代码中实现文件,以确保我们选择当前视图控制器作为选择器视图的数据源:
- (void)viewDidLoad{ [super viewDidLoad]; self.myPicker = [[UIPickerView alloc] init]; self.myPicker.dataSource = self; self.myPicker.center = self.view.center; [self.view addSubview:self.myPicker]; }
在此之后,如果你试图编译应用程序,你会得到从编译器的警告,告诉你,你还没有实现的一些的UIPicker ViewDataSource协议,希望你能实现的方法。解决这个问题的方法是按命令+ Shift + O,类型UIPickerViewDataSource,然后按键盘上的Enter键。这将送你到你的代码的地方,这个协议被定义,在那里你会看到类似这样:
@protocol UIPickerViewDataSource<NSObject> @required // returns the number of 'columns' to display. - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView; // returns the # of rows in each component.. - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component; @end
你可以看到@Required关键字呢?这告诉我们,无论哪个阶层要成为一个选择器视图必须实现这些方法的数据来源。很划算。让我们在我们的视图控制器的实现文件的贯彻落实:
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{ if ([pickerView isEqual:self.myPicker]){ return 1; } return 0; } -(NSInteger) pickerView:(UIPickerView*)pickerView numberOfRowsInComponent:(NSInteger)component{ if ([pickerView isEqual:self.myPicker]){ return 10; } return 0; }
因此,这里发生了什么?让我们一起来看看这些是什么数据源方法中的每一个期望:
numberOfComponentsInPickerView:
此方法将你一个选择器视图对象作为它的参数,希望你返回一个整数,告诉运行时,你将有多少成分是喜欢选择器视图来呈现。
pickerView:numberOfRowsInComponent:
对于被添加到一个选择器视图中的每个组件,您需要告诉系统你有多少行想在组件呈现。此方法将你的选择器视图的实例,你将需要返回一个整数,表示行数来呈现该组件。
因此,在这种情况下,我们要求系统显示组件1只10,我们之前已经创建了一个选择器视图,称为myPicker行。
编译并运行在iPhone模拟器(图1-11)的应用程序。 EWWW,那是什么?
它看起来像我们的选择器视图知道它应该有多少分量,应该有多少个行渲染的成分,但不知道以显示每行的文本内容。这是我们现在需要做的事情,而我们做到这一点提供了一个代表到选择器视图。 UIPickerView的一个实例的代表有,以符合UIPickerViewDelegate协议,并且必须执行该协议的所有@Required方法。
只有一个方法,在UIPickerViewDelegate我们感兴趣的是: pick erView:titleForRow:forComponent:方法。这种方法将通过您的当前节和当前行中的第一个选择器视图索引的索引,它期望你返回的NSString的实例。这个字符串就会得到渲染该组件内部的特定行。在这里,我只想以显示第一行的第1行,然后继续第2行,3行,等等,直到结束。请记住,我们也有我们的设置选择器视图的委托财产:
self.myPicker.delegate = self;
现在,我们将要处理,刚才了解了的委托方法:
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{ if ([pickerView isEqual:self.myPicker]){ /* Row is zero-based and we want the first row (with index 0) to be rendered as Row 1, so we have to +1 every row index */ return [NSString stringWithFormat:@"Row %ld", (long)row + 1]; } return nil; }
现在,让我们运行我们的应用程序,看看会发生什么(图1-12)。
图1-12。有一个部分和几行选择器视图
??????
Picker views在旧的 IOS6 中突出使用了一个名为showsSelectionIndicator属性,它在默认情况下被设置为NO当前的选择。您可以直接设置该属性的值YES或使用setShowsSelectionIndicator:选择器视图的方法把这个指标上:
self.myPicker.showsSelectionIndicator = YES;
现在,假设你已经创建了你的最终应用这个选择器视图。什么是使用选择器视图中,如果我们无法检测哪些用户在其每一个部件实际上已经选择了?嗯,这是很好的,苹果已经想到了这一点,给我们要问的是选择什么样的选择器视图的能力。致电selectedRowInCompo新界东北:一个UIPickerView的方法,并通过组件的从零开始的索引。该方法会返回一个整数,表明目前在该组件中选择的行的从零开始的索引。
如果您需要修改的值,在运行时你的选择器视图,您需要确保您的选择器视图的数据源和委托重新加载数据。要做到这一点,你可以强制所有的组件重新加载其数据,使用reloadAllCompo堂费的方法,或者你可以问一个具体的组件重新加载其数据,使用reload组件:方法和传递具有的组件的索引重新加载。
另请参阅
食谱1.2