zoukankan      html  css  js  c++  java
  • IOS之UI基础

    2.1 增强版Hello World

    2.2 MVC设计模式

    2.3 Cocoa MVC

    2.4 视图控制器的方法

    2.5 输出口和动作

    2.6 键盘输入

    2.7 使用AlertView

    2.8 使用ActionSheet

    2.8 等待有关控件

    2.9 屏幕旋转

    2.1 增强版Hello World

    wps_clip_image-10454

    实现步骤

    1.创建Hello World工程

    在Xcode中创建Hello World工程,基于iPhone试图基础应用程序。

    iPhone OS ->Application ->View-based Application

    2.修改Hello_WorldViewController.h

    需要UITextField控件接受文字和响应一个按钮点击事件,所以在h文件中我们要定义一个UITextField属性和一个响应事件方法

    #import <UIKit/UIKit.h>
    
    @interface Hello_WorldViewController : UIViewController {
        UITextField *txtField;
    }
    
    @property (nonatomic, retain) IBOutlet UITextField *txtField;
    
    -(IBAction)onClickButton:(id)sender;
    
    @end

    3.修改Hello_WorldViewController.m

       实现txtField属性

       实现-(IBAction)onClickButton:(id)sender 方法

    #import "Hello_WorldViewController.h"
    
    @implementation Hello_WorldViewController
    
    @synthesize txtField;
    
    -(IBAction)onClickButton:(id)sender {
        txtField.text = @"Hello World.";
    }
    
    - (void)viewDidUnload {
        self.txtField = nil;
    }
    
    - (void)dealloc {
        [txtField dealloc];
        [super dealloc];
    }
    
    @end

    4.使用IB设计页面,摆放控件

    Resources/Hello_WorldViewController.xib文件,打开Library将控件拖入设计窗口

    wps_clip_image-7058

    5.连接输出口

    为了将控件属性通过屏幕“输入”或“输出”,我们需要定义“输出口”,在控制器中我们已经定义了与这个数据对 应的属性:

    @property (nonatomic, retain)  IBOutlet

    UITextField *txtField;

    UITextField用于展示输出和输入数据。在iPhone(包括Mac)开发时候控件属性要通过定义输出口才能在屏幕中使用 的。

    wps_clip_image-23933

    6.处理事件

    为了响应控件的事件,我们需要在控制器中定义一个事件处理方法:

    -(IBAction)onClickButton:(id)sender;

    在iPhone(包括Mac)开发控件事件处理要自己编写对应方法,并在IB中将控件的事件与该方法连接起来。

    wps_clip_image-13768

    2.2 MVC设计模式

    MVC是一种设计模式,所谓设计模式就是解决某一特定问题的方案,MVC是解决具有UI的应用系统的成熟解决方案,

    在Cocoa应用系统中严格按照该模式实现。M-Model(模型)是应用系统中与视图对于部分的数据。V -View(视图)是应用系统中用户看到并与之交互的界面。C-Controller(控制器)是应用系统中起到控制器作用,接受用户事件,显示数据等等,与视图进行交互等。

    2.3 Cocoa MVC

    采用MVC 设计模式意味着,Interface Builder 不需要编写或生成任何代码,您只需专注于应用程序的视图。Mac 的Cocoa 绑定消除了大部分的黏合代码,它就像连接在Xcode 编写的控制器和Interface Builder 设计的视图之间的一条线,用图形化的表示方法简化了二者之间的关系。Interface Builder 和Cocoa 可以快速开发地您的应用程序。

    wps_clip_image-32174

    File's owner:

    wps_clip_image-29401

    2.4 视图控制器的方法

    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

    如果视图使用NIB文件创建,在加载视图之前调用这个方法,做一些初始化工作。

    - (void)loadView

    视图加载的时候调用的方法一般不使用NIB文件创建视图的时候使用,而是使用代码创建视图对象。

    - (void)viewDidLoad 

    视图加载之后调用的方法,我们常常在这个方法中做视图初始化出来。

    - (void)didReceiveMemoryWarning

    当系统内存警告的时候调用的方法,我们一般在该方法释放消耗资源的对象。

    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 

    用于处理屏幕旋转的方法。

    - (void)viewDidUnload 

    视图对象卸载的使用调用的方法,一般在把内存视图中的属性设置为nil值。

    - (void)viewDidUnload {
        self.txtField = nil;
    }

    - (void)dealloc

    视图对象内存释放的时候调用的方法,在该方法中先要释放掉成员变量。

    - (void)dealloc {
        [txtField dealloc];
        [super dealloc];
    }

    2.5 输出口和动作

    输出口(Outlet),为了实现控制器在视图上输入输出结果,需要定义输出口。

    定义输出口,是在ViewController定义一个控件属性,如下:

    //h文件
    @interface Hello_WorldViewController : UIViewController {
        UITextField *txtField;
    }
    
    @property (nonatomic, retain) IBOutlet UITextField *txtField;
    
    //m文件
    @synthesize txtField;

    动作(Action),为了实现视图控制器响应视图事件,需要定义动作。

    定义动作,是在ViewController定义一个方法,如下:

    //h文件
    -(IBAction)onClickButton:(id)sender;
    
    //m文件
    -(IBAction)onClickButton:(id)sender {
        txtField.text = @"Hello World.";
    }

    动作(Action)是在控件器中的方法,但它的返回类型必须是IBAction声明的,该关键字告诉IB,此方法是个Action,可以被某个事件触发。

    2.6 键盘输入

    在iPhone应用程序中,键盘输入处理比较麻烦。在输入完成后我们需要自己关闭键盘。

    在iPhone中我们还可以指定键盘输入类型,可以是Email、电话和数字等类型。

    输入完成关闭键盘:

    Phone中文本框输入后,键盘是不会关闭的,必须编写代码。

    1 为关闭键盘添加事件处理方法:

    //h file
    -(IBAction)textFieldDoneEditing:(id)sender;
    
    //m file
    -(IBAction)textFieldDoneEditing:(id)sender {
        [sender resignFirstResponder];    
    }

    2 链接事件

    文本框对象的Did End On Exit事件链接到File’s  Owner。

    wps_clip_image-11610

    wps_clip_image-26608

    3 小结

    点击键盘中的“换行”或“return”键关闭键盘。 第一响应者是当前与用户交互的控件,在这个例子中,点击TextField控件,它就变成第一响应者键盘就会自动出现。

    [sender resignFirstResponder];

    是使TextField控件放弃第一响应者状态。

    4 通过触摸背景关闭键盘

    点击关闭键盘中的“return”关闭键盘比较麻烦,我们可以通过触摸背景关闭键盘。

    //h
    -(IBAction)backgroundTap:(id)sender;
    
    //m
    -(IBAction)backgroundTap:(id)sender {
        [txtField resignFirstResponder];    
    }

    5 连接动作和事件

    为了使背景控件能够响应事件,我们需要背景View的父类(UIView)修改成为UIControl,UIControl是能够触发actionɼ所有控件都是UIControl的子类。而UIControl是UIView子类,也具有View基本特征。

    从Touch Down事件拖到File’s Owner图标,然后选择backgroundTap:动作。这样触摸视图中没有活动的控件的任何位置就可以触发backgroundTap:动作,关闭键盘。

    wps_clip_image-9817

    6 键盘输入类型

    在iPhone中我们还可以指定键盘输入类型,可以是Email、电话和数字等类型。

    wps_clip_image-21337

    Email键盘                         数字键盘                        电话键盘

    wps_clip_image-26960wps_clip_image-23738wps_clip_image-32252

    7 Return Key设定

    在键盘输入属性框中我们可以定义Return Key,可以有Google等等。但是这些并没有实际的含义,只是代表它可以触发输入完成事件(Did End On Exit)。

    2.7 使用AlertView

    修改Hello World项目代码,添加AlertView:

    修改Hello-.m代码

    -(IBAction)onClickButton:(id)sender {
        
        //txtField.text = @"Hello World.";
        NSString *str = [[NSString alloc] initWithFormat:@"Hello. %@", txtField.text];
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Hello!" 
                                            message:str delegate:self 
                                            cancelButtonTitle:@"Done" 
                                            otherButtonTitles:nil];
        [alert show];
        [alert release];
        [str release];
        
    }

    2.8 使用ActionSheet

    ActionSheet和AlertView比较相似都是给用户一个提示信息。它是从底部弹出。它通常用于确认潜在的危险或不能撤消的操作,如删除一个数据。 为了使用ActionSheet我们需要在h文件中实现UIActionSheetDelegate协议。其中,我们常常需

    要实现: actionSheet:didDismissWithButtonIndex:

    该方法是ActionSheet消失的时候调用。

    wps_clip_image-21640

    修改Hello-.h文件

    在Hello_WorldViewController.h文件中添加协议UIActionSheetDelegate:

    //h
    #import <UIKit/UIKit.h>
    
    @interface Hello_WorldViewController : UIViewController 
            <UIActionSheetDelegate> {
        UITextField *txtField;
    }
    
    @property (nonatomic, retain) IBOutlet UITextField *txtField;
    
    -(IBAction)onClickButton:(id)sender;
    
    @end
    //m
    #import "Hello_WorldViewController.h"
    
    @implementation Hello_WorldViewController
    
    @synthesize txtField;
    
    -(IBAction)onClickButton:(id)sender {
        
        //txtField.text = @"Hello World.";
        UIActionSheet *actionSheet = [[UIActionSheet alloc] 
                                      initWithTitle:@"您确认清除文本框中的数据吗?" 
                                      delegate:self 
                                      cancelButtonTitle:@"取消" 
                                      destructiveButtonTitle:@"确定" 
                                      otherButtonTitles:nil];
        
    //    NSArray *array = [[NSArray alloc] initWithObjects:
    //                      [NSString stringWithString:@"1st Button"],
    //                      [NSString stringWithString:@"2nd Button"],
    //                      [NSString stringWithString:@"3rd Button"],
    //                      [NSString stringWithString:@"4th Button"],
    //                      nil];
    //    
    //    UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"Title Here"
    //                                                             delegate:self
    //                                                    cancelButtonTitle:nil
    //                                               destructiveButtonTitle:nil
    //                                                    otherButtonTitles:nil];
    //    
    //    for (int i = 0; i < 3; i++) {
    //        
    //        [actionSheet addButtonWithTitle:[array objectAtIndex:i]];
    //        
    //    }
    //    
    //    [actionSheet addButtonWithTitle:@"Cancel"];
    //    actionSheet.cancelButtonIndex = 4;
        
        [actionSheet showInView:self.view];
        [actionSheet release];    
    }
    
    -(void)actionSheet:(UIActionSheet *)actionSheet 
                didDismissWithButtonIndex:(NSInteger)buttonIndex {
        if (buttonIndex == [actionSheet destructiveButtonIndex]) {
            txtField.text = @"";    
        }
    }
    
    - (void)viewDidUnload {
        self.txtField = nil;
    }
    
    
    - (void)dealloc {
        [txtField dealloc];
        [super dealloc];
    }
    
    @end

    2.8 等待有关控件

    对于一些费时的处理,需要使用一些等待控件消除用户心里等待的时间。

    等待有关的控件有:

    " UIActivityIndicatorView

    " UIProgressView

    UIActivityIndicatorView:

    wps_clip_image-26447

    UIActivity-.h

    @interface UIActivityIndicatorViewController : UIViewController {
        UIActivityIndicatorView * myActivityView;
    }
    
    @property (nonatomic, retain) IBOutlet UIActivityIndicatorView * myActivityView;
    
    -(IBAction)onClickButton: (id)sender;
    
    @end

    UIActivity-.m

    #import "UIActivityIndicatorViewController.h"
    
    @implementation UIActivityIndicatorViewController
    
    @synthesize myActivityView;
    
    -(IBAction)onClickButton: (id)sender {
        if ([myActivityView isAnimating]) {
            [myActivityView stopAnimating];            
        } else {
            [myActivityView startAnimating];
        }
    }
    
    - (void)dealloc {
        [myActivityView release];
        [super dealloc];
    }
    
    @end

    UIProgressView

    wps_clip_image-24783

    Progress-.h

    @interface ProgressViewViewController : UIViewController {
        IBOutlet UIProgressView *Progress; 
        NSTimer *timer;
    }
    
    @property (nonatomic, retain) IBOutlet UIProgressView *Progress; 
    @property (nonatomic, assign) NSTimer *timer;
        
    -(IBAction)start;
    
    @end

    Progress-.m

    @synthesize  Progress;
    @synthesize timer;
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    }
    
    -(IBAction)start{
        Progress.progress = 0.0;
        timer = [NSTimer 
                 scheduledTimerWithTimeInterval:1.0 
                 target:self 
                 selector:@selector(update) 
                 userInfo:nil repeats:YES];
    }

    NSTimer是可以隐式地启动一个线程,scheduledTimerWithTimeInterval指定线程要休眠多少时间调用一次,selector所指定的方法update

    Progress-.m

    -(void)update{
        Progress.progress = Progress.progress + 0.1;
        if (Progress.progress == 1.0) {
            [timer invalidate]; 
            UIAlertView *alert = [[UIAlertView alloc] 
                                  initWithTitle:@"任务通知" 
                                  message:@"硬盘格式化完成!" 
                                  delegate:self 
                                  cancelButtonTitle:@"OK" 
                                  otherButtonTitles:nil];
            [alert show];
            [alert release];
        }
    }
    
    - (void)viewDidUnload {
        self.Progress = nil;
    }
    
    
    - (void)dealloc {
        [Progress release];
        [super dealloc];
    }

    UIProgressView控件的progress属性是0.0~1.0烦范围。0.0时候在开始的位置,1.0时候是进度到了100%。

    2.9 屏幕旋转

    iPhone中有重力感应我们可以通过旋转手机使屏幕旋转。但是屏幕旋转后页面的布局需要注意。

    wps_clip_image-30651

    屏幕旋转的类型

    UIInterfaceOrientationPortrait,垂直向上

    UIInterfaceOrientationPortraitUpsideDown,垂直倒放。

    UIInterfaceOrientationLandscapeLeft,水平向左。

    UIInterfaceOrientationLandscapeRight,水平向右。

    注意:以手机屏幕为参照物的向左、向右。

    开启旋转 :可以通过shouldAutorotateToInterfaceOrientation:方法开启或禁止旋转。

    允许任何方向的旋转:

    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
        return YES;
    }

    垂直向上和水平向右:

    - (void)willAnimateRotationToInterfaceOrientation: (UIInterfaceOrientation) interfaceOrientation duration: (NSTimeInterval) duration {
        if (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
            
        } else {
            
        }
    }

    触发旋转事件 :

    我们可以在屏幕旋转的时候触发很多事件,其中willAnimateRotationToInterfaceOrientation是我们常用的事件,这个事件是在即将开始屏幕旋转动画的时候触发。

    - (void)willAnimateRotationToInterfaceOrientation: (UIInterfaceOrientation) interfaceOrientation duration: (NSTimeInterval) duration {
        if (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
            txtField.text = @"垂直显示。";
        } else {
            txtField.text = @"水平显示。";
        }
    }

    自动调整屏幕控件

    由于屏幕旋转后,控件的位置会发生变化,我们要让这些控件能够摆放相对比较合理。我们可以通过“Control Size”调整。 其中红色实线代表绝对位置, 红色虚线代表相对位置。

    wps_clip_image-31232

    横屏竖屏切换不同视图

    wps_clip_image-1221

    新建工程Swap

    SwapViewController.h文件

    #import <UIKit/UIKit.h>
    #define degreesToRadians(x) (M_PI * (x) / 180.0)
    
    @interface SwapViewController : UIViewController {
        UIView *landscape; 
        UIView *portrait; 
        
        UIButton *landscapeFooButton;//Foo
        UIButton *portraitFooButton; 
        
        UIButton *landscapeBarButton;//Bar 
        UIButton *portraitBarButton;
    } 
    
    @property (nonatomic, retain) IBOutlet UIView *landscape; 
    @property (nonatomic, retain) IBOutlet UIView *portrait; 
    @property (nonatomic, retain) IBOutlet UIButton *landscapeFooButton; 
    @property (nonatomic, retain) IBOutlet UIButton *portraitFooButton; 
    @property (nonatomic, retain) IBOutlet UIButton *landscapeBarButton; 
    @property (nonatomic, retain) IBOutlet UIButton *portraitBarButton; 
    
    -(IBAction) buttonPressed:(id)sender;
    
    
    @end

    #define degreesToRadians(X) (M_PI * (x) / 180.0)这是一个宏,用于在度数和弧度之间的转换。

    landscape水平视图,portrait垂直视图;

    landscapeFooButton水平视图中Foo按钮;

    portraitFooButton垂直视图中Foo按钮;

    landscapeBarButton水平视图中Bar按钮;

    portraitBarButton垂直视图中Bar按钮。

    视图设计

    wps_clip_image-2323

    输出口和事件 

    wps_clip_image-22664

    编写m实现文件

    #import "SwapViewController.h"
    
    @implementation SwapViewController
    
    @synthesize landscape; 
    @synthesize portrait; 
    @synthesize landscapeFooButton; 
    @synthesize portraitFooButton; 
    @synthesize landscapeBarButton; 
    @synthesize portraitBarButton; 
    
    -(IBAction) buttonPressed:(id)sender {
        if (sender == portraitFooButton) {
            NSLog(@"portraitFooButton press.");
        } else if (sender == landscapeFooButton) {
            NSLog(@"landscapeFooButton press.");
        } else if (sender == landscapeBarButton) {
            NSLog(@"landscapeBarButton press.");
        } else {
            NSLog(@"portraitBarButton press.");
        }
    }
    
    // Override to allow orientations other than the default portrait orientation.
    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
        // Return YES for supported orientations
        //return (interfaceOrientation == UIInterfaceOrientationPortrait);
        return YES;
    }
    
    -(void) willAnimateRotationToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation duration: (NSTimeInterval)duration{
        
        if (interfaceOrientation == UIInterfaceOrientationPortrait) {
            self.view = self.portrait; 
            self.view.transform = CGAffineTransformIdentity; 
            self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(0));
            self.view.bounds = CGRectMake(0.0, 0.0, 320.0, 460.0);
        } else if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
            self.view = self.landscape; 
            self.view.transform = CGAffineTransformIdentity;
            self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(-90));
            self.view.bounds = CGRectMake(0.0, 0.0, 480.0, 300.0);
        } else if (interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
            self.view = self.portrait; 
            self.view.transform = CGAffineTransformIdentity; 
            self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(180)); 
            self.view.bounds = CGRectMake(0.0, 0.0, 320.0, 460.0);
        } else if (interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
            self.view = self.landscape; 
            self.view.transform = CGAffineTransformIdentity; 
            self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(90)); 
            self.view.bounds = CGRectMake(0.0, 0.0, 480.0, 300.0);
        }
        
    }
    
    - (void)didReceiveMemoryWarning {
        // Releases the view if it doesn't have a superview.
        [super didReceiveMemoryWarning];
        
        // Release any cached data, images, etc that aren't in use.
    }
    
    - (void)viewDidUnload {
        // Release any retained subviews of the main view.
        self.landscape = nil;
        self.portrait = nil;
        self.landscapeFooButton = nil;
        self.portraitFooButton = nil;
        self.landscapeBarButton = nil;
        self.portraitBarButton = nil;
    }
    
    
    - (void)dealloc {
        [landscape release]; 
        [portrait release]; 
        [landscapeFooButton release]; 
        [portraitFooButton release]; 
        [landscapeBarButton release];  
        [portraitBarButton release]; 
        [super dealloc];
    }
    
    @end

    willAnimateRotationToInterfaceOrientationduration:这个方法来自我们重写的一个父类,这个方法在旋转开始之后与旋转实际发生之前被调用。

    CGAffineTransformIdentity,重置变换属性。

    CGAffineTransformMakeRotation来创建一个旋转变换。

    注:

    1 本教程是基于关东升老师的教程

    2 基于黑苹果10.6.8和xcode4.2

    3 本人初学,有什么不对的望指教

    4 教程会随着本人学习,持续更新

    5 教程是本人从word笔记中拷贝出来了,所以格式请见谅

  • 相关阅读:
    [编程题]多多的数字组合
    mac传输文件到服务器
    git 清除缓存、查看add内容
    go build
    vim编辑器
    Git: clone指定分支
    查看端口占用以及kill
    curl小记录
    Python3.9 malloc error: can’t allocate region
    设计模式-策略模式
  • 原文地址:https://www.cnblogs.com/syxchina/p/2668176.html
Copyright © 2011-2022 走看看