iOS之更丰富的界面

今天我们学习新的一章。本章将使用很多的控件,与实际的应用更相似。内容比较多,我们就分成几个部分。

一:

1)         创建应用程序。仍然是选择single view application。命名为Control Fun。

2)         这次,我们要将一个图像添加到项目之中。将想要添加的图像(图像不要太大,否则其它的控件就无法添加了)拖到工程里,在出现的对话框中,默认设置即可,确定。打开storyboard,从library中找到Image View,拖到view中,在Image View的四条边上有8个点,通过这几个点调节其与添加的图像差不多大小即可。

在attributes inspector中,找到image view中的image,在右侧的下拉菜单中,选择刚才添加到项目中的那幅图像的名称,这样图像就被添加到view中了。

双击图像,在editor菜单中,选择size to fit content,或者按快捷键command=,这样就调整了image view使它适应了所包含的内容。如图所示。

 

调整图像的个中属性。在attributes inspector中,会看到很多项。在这只说一下Apha,它是用来定义图像的透明度的。一般设为1.0。当该值小于1时,则iPhone回将此图绘制为透明的。即使图像后面没有任何内容,也会使应用程序花费处理周期来计算透明度。

由于图像视图使静态图像,并且也不会随着应用程序的运行发生改变,因此我们不需要outlet。

3)         在图像下添加两个Label(标签),分别更名为name和number,添加两个TextField(文本段)。修改第一个文本字段的属性,在attributes inspector中,在placeholder右边的文本框中输入Type in a name。这个placeholder的作用是用来指定在文本字段中以灰色显示的文本。在下面的capitalization中下拉列表中改为Words,此项将所有单词自动转换为首字母大写。在return key弹出项的值改为Done。其它文本输入特征保留为默认值。

 

再修改第二个文本字段的属性。再placeholder的文本框中输入Type in a Number。在keyboard 菜单中,选择number pad,因为这个文本段中,我们只希望输入数字。其它选项均为默认即可。

4)         编译运行下,看看结果。

 

5)         与我们设想的一样。但现在有个问题。按下Done按钮后,我们没有办法关掉键盘。因此,需要我们创建一个action,来关掉键盘。当用户按下Done按钮后,将产生一个Did End On Exit事件,此时我们需要让文本段取消控件,以关闭键盘。

为第一个TextField创建一个action,取名为textFeildDoneEditing,创建方法同上一节的一样。

    - (IBAction)textFeildDoneEditing:(id)sender {

      [sender resignFirstResponder];

    }

意思是告诉触发此操作的控件,取消第一响应者状态。当文本字段失去第一响应者状态时,与之相关的键盘将消失。而何为第一响应者呢(FirstResponder)?简单来说就是用户当前正在与之交互的对象。运行下,发现这回好了。

 

6)  仔细观察会发现,这里还有一个问题,就是iPhone上,单击屏幕上的空白处即可关闭键盘,而现在我们需要返回到name文本段处按Done后才能关闭键盘。因此仍然需要我们来改进。通过触摸背景关闭键盘。

实现原理:

 

这是控件布局的树形图,我们所添加的项均是在这个view上。它充当着用户界面容器,它在用户界面没有外观,但涵盖了整个iPhone窗口。它的主要用途是持有其他视图和控件。该容器视图是我们的用户界面的背景。我们要做的是写一个Action,使这个View所携带的一个event能够调用这个Action。但这个view(或者称为root view)的类型是UIView,而UIView是没有event的,这样就无法和Action关联,因此我们需要将它的类型改为UIControl,它是UIView的子类,并且拥有event。更改完毕后,会发现,这个rootView名字自动改成了Control了。

 

 

现在,创建为两个textField各创建一个outlet,分别命名为nameField,numberField,并未这个rootControl创建一个事件,命名为backgroundTag。其中,event处选择Touch Down。之所以选择Touch Down,是因为后台不是一个按钮,我们希望点击屏幕任何的空白处都可以触发这个操作。点击connect。代码如下:

 

    - (IBAction)backgroundTag:(id)sender {

        [nameField resignFirstResponder];

        [numberField resignFirstResponder];

}

7)  保存文件,编译运行,点击屏幕的任何位置,键盘都会取消,达到了我们想要的效果。

二:

下面我们继续学习,这部分主要学习slider控件。

1) 向view中添加一个slider控件.拖到view上,拉伸到合适的长度。

 

设置slider的属性。Value是取值范围,我们设为1-100;current为初始值,我们设为50。设置完成后,slider会根据设置自动调整。

 

2)           添加一个label。放到number下面,如图所示。同时选中这三个标签,Editor-Align-Right Edges或者command [使三者右对齐这其中有一点需要注意。50所在label的宽度一定要比50宽,因为我们设置的slider的最大值使100,如果label宽度不够的话,当其值变为100时,就会使部分数字看不见。

        

3)     这次label的值会随着slider的变化而变化,因此需要为label添加一个outlet,方法同以前一样,按住control,点击label,滑动到Control FunViewController.h中,在弹出的对话框中选择outlet,名字为sliderLabel,确认。为slider添加一个action,方法相似,命名为sliderChanged。

         sliderChanged实现如下:

                 - (IBAction)sliderChanged:(id)sender {

       UISlider *slider = (UISlider *) sender;

       int progressAsInt = (int)(slider.value + 0.5);

    NSString *newText = [[NSString alloc] initWithFormat:@"%d", progressAsInt];

    sliderLabel.text = newText;

}

下面介绍下这个方法:首先将sender转换为UISider *,作用是避免每次使用sender时都要进行类型转换,使代码可读性更强。

接着接受滑块的值(int型),+0.5以便四舍五入为整型值。然后使用该整型值创建一个字符串,用于设置label的text(文本)。

4) 保存,运行代码。滑动slider,左边的值随着变化。

   

三:

这部分呢,主要是学习Segmented Control和Switch。

1)  首先将一个Segmented Control控件拖到view上,并宽展控件宽度,从视图左侧蓝色引导线到右侧引导线。双击First单词,改为Swtch。双击Second单词,改为Button。添加两个Switch,分别放在Segmented Control下方的两侧,靠近蓝色引导线。

 

2)  下面接着创建outlet和action。

    为两个switch分别创建一个outlet,分别命名为leftSwitch和rightSwitch。为segmented创建一个action,命名为toggleControls,为switch创建一个action,命名为switchChanged,event处选择value changed,并将另一个switch关联到这个action上。

   

代码如下:

- (IBAction)switchChanged:(id)sender {

    UISwitch *whichSwitch = (UISwitch *) sender;

    BOOL setting = whichSwitch.isOn;

    [leftSwitch setOn:setting animated:NO];

    [rightSwitch setOn:setting animated:NO];

}

两个switch被关联在了同一个action,因此当有一个switch被按下后,该方法获取了sender的值,sender值只能等于leftSwitch或rightSwitch,并使有该值来设定两个开关。但在这个方法中,并没有确定实际是哪个开关别按下,只是简单的将两个开关设定成了相同的状态而已。

[leftSwitch setOn:setting animated:NO];

其中的animated,是用来指定按钮应该缓慢的滑动(YES)还是应该迅速的移动(NO)到新位置。 缓慢滑动给人的动画效果给用户的体验更好一些。

 

3)  在两个switch中间添加一个button按钮。拉伸,使其完全盖住两个switch。

双击,将其命名为DoSomething,在右边的attributes inspector中,选中Hidden复选框。现在button变成了透明状,但在真实的运行环境中,button会被隐藏。

   

4) 为button添加outlet和action。添加outlet是因为在点击segmented control时会控制它的隐藏或显示。outlet命名为doSomethingButton,action命名为buttonPressed。

       首先在toggleControls键入代码如下:

         - (IBAction)toggleControls:(id)sender {

    if([sender selectedSegmentIndex] ==kSwitchesSegmentIndex){

        leftSwitch.hidden =NO;

          rightSwitch.hidden = NO;

          doSomethingButton.hidden = YES;

      }

      else {

          leftSwitch.hidden = YES;

          rightSwitch.hidden = YES;

          doSomethingButton.hidden = NO;

         }

    }

       代码中引用了一个UISegmentedControl属性,即selectedSegmentIndex,它告诉我们当前选中的是哪一个分段(segmented control中块的index从左到右值依此为0,1…….)。kSwitchesSegentIndex是一个常量,值为零,让代码可读性更强。

       当触发这个方法时,根据选定的分段控件,确定隐藏button或是switches。

       运行程序,点击segmented control按钮,看看是否会隐藏相应的控件。

四:

1)         现在剩下最后一部分了,在这部分中,我们学习Action Sheet(操作表)和Alert(警告)。

Action Sheet:用于迫使用户在两个或更多项之间进行选择。从屏幕底部弹出,显示一系列按钮供用户选择。操作表通常用于确认潜在的危险或不能撤销的操作,比如删除一个对象。

Alert:以蓝色圆角巨型的形式出现在屏幕中央,迫使用户在继续使用应用程序前作出响应。警报更多地用于通知用户发生了一些重要的或者不正常的事,通常为单个按钮,但也可为多个。

这两项都应用了应用程序委托(delegate)。

应用程序委托:委托是一个对象周期性地向被指定为其委托的另一个对象发送消息,向其请求输入或者通知某件事情正在发生。该模式可替换类继承来对可复用对象的功能进行扩展。iOS中定义了很多方法,可供我们调用,但我们若想更改方法的一部分,如果通过继承来完成,这时候就需要继承一个很大的类,因此为了解决这个问题,就是用delegate来完成。但程序发现你改写了某个方法时,就会调用你的方法,而不是原来的方法。(其实,对于delegate我也很糊涂,上面这样说也不知道对不对,如果有那位朋友知道,希望你能告诉我,谢谢。)

2)     看看具体的实例。我们需要在实例中产生一个Action Sheet,为了让控制器类充当操作表的委托,控制器类需要遵从UIActionSheetDelegate(当然并不是所有的委托方法都需要我们实现,Alert 就不需要)

首先打开control funViewController.h文件,在类后面加上协议的名称

 

    在buttonPressed中添加如下代码:

    - (IBAction)buttonPressed:(id)sender {

    UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"Are you sure?" delegate:self cancelButtonTitle:@"No Way" destructiveButtonTitle:@"Yes, I'm Sure!" otherButtonTitles:nil];

       [actionSheet showInView:self.view];

    }

首先我们在buttonPressed操作方法中分配了一个UIActionSheet对象并进行了初始化,这个对象用于表示操作表。初始化方法接受了多个参数。第一个是操作表的标题,第二个是操作表的委托,它将在该表上的按钮被按下时受收到通知,它指明了这个actionSheet的delegate在哪里,self说明是在本类里。即在UIActionSheet所在的类中寻找UIActionSheet的代理方法的实现(这个例子中的类就是指类control funViewController,原因是<UIActionSheetDelegate>,让该类可以接收并响应UIActionSheet的委托事件)。

接着是操作表上的取消按钮,也就是不进行下一步的按钮,接着是确定按钮,如果还想在上面加一些其他按钮,可以上面otherButtonTitles:@“Foo”,@”Bar”,nil等,最后以nil表示结束。最后一行让它显示自己。每一个ActionSheet都需要有一个父视图,在父视图中显示自己,因为我们是单一视图项目(Single View),也只有一个View,因此这里的self.view就是说在actionSheet实现的这个view里显示。

 

3)     实现actionsheet的委托方法

在buttonPressed下面添加一个方法

- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex {

    if(buttonIndex != [actionSheet cancelButtonIndex]) {

        NSString *msg = nil;

        if(nameField.text.length > 0)

            msg = [[NSString alloc] initWithFormat:@"You can breathe easy, %@,everything went OK.",nameField.text];

        else

            msg = [[NSString alloc] initWithFormat:@"You can breathe easy,everything went OK."];

        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Something was done" message:msg delegate:self cancelButtonTitle:@"Prew!" otherButtonTitles:nil];

        [alert show];

    }

}

这些代码实现了一个action sheet的delegate,当点击action sheet按钮时,回调用这个delegate。参数buttonIndex可以告诉我们实际按下的是哪个按钮。

如果用户在顶部的文本字段中输入了名字,我们将获取该值并在警报消息中使用它。

4)     编译运行,点击Yes,I’m sure,会出现一个alert,与我们料想的一样。

  

五:

    本章终于结束了,内容好多,对于delegate这我还是不太明白,里面的很多东西都是参考网上的一些博客和书里的内容的。希望在以后慢慢会明白。

 

转载于:https://www.cnblogs.com/9826myblogs/archive/2013/03/08/2950173.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值