ocios_ociosswift - CSDN
  • OCiOS开发:界面传值

    2016-04-11 13:10:26
    引言在IOS开发过程中,界面传值无处不在,可以说界面传值在IOS开发过程中是非常重要的,而传值方式也多种多样,如下我将介绍几种常见的界面传值方式。传值方法假设目前有控制器HomeViewController(主页)与...

    引言

    • 在iOS开发过程中,界面传值无处不在,可以说界面传值在iOS开发过程中是非常重要的,而传值方式也多种多样,如下我将结合几种场景介绍几种常用的界面传值方式。

    传值需求

    • 将用户信息 userInfo 作为传值对象进行传递。

    场景一 主页传值到详情页

    • 现在模拟传递用户名:userName

    属性传值

    • 属性传值一般用于从主页传值到详情页。

    • 传值步骤:

    steps 1:在DetailViewController.h文件中将需要获取的值声明成属性。

    #import <UIKit/UIKit.h>
    
    @interface DetailViewController : UIViewController
    
    @property (nonatomic, strong)NSDictionary *userInfo; /**< 用户信息 */
    
    @end
    

    steps 2:在HomeViewController.m文件中导入头文件“DetailViewController.h”,然后在界面跳转逻辑处理方法中初始化DetailViewController,并通过点语法给属性userInfo赋需要传递的值。

    - (void)respondsToButton:(UIButton *)sender {
    
        // 初始化详情视图控制器
        DetailViewController *detailVc = [[DetailViewController alloc] init];
    
        // 属性传值:赋值
        NSDictionary *userInfo = @{@"name":@"Charles", @"age":@(22)};
        detailVc.userInfo = userInfo;
    
        // 模态切换(界面跳转)
        [self presentViewController:detailVc animated:YES completion:nil];
    
    }

    steps 3:在DetailViewController.m文件viewDidLoad方法中获取userName的值,此时获取到的值就是从主页传过来的值。

    - (void)viewDidLoad {
        [super viewDidLoad];
    
        NSLog(@"%@", userInfo);
    }

    init传值

    • init方法传值与属性传值类似,一般用于从主页传值到详情页。

    • 传值步骤:

    steps 1:在DetailViewController.h文件中声明init方法。

    - (instancetype)initWithUserInfo:(NSDictionary *)userInfo; /**< init传值方法声明 */

    steps 2:在HomeViewController.m文件中导入头文件“DetailViewController.h”,然后在界面跳转逻辑处理方法中通过initWithUserInfo:方法初始化DetailViewController并赋值。

    - (void)respondsToButton:(UIButton *)sender {
    
        NSDictionary *userInfo = @{@"name":@"Charles", @"age":@(22)};
    
        // 初始化详情视图控制器
        DetailViewController *detailVc = [[DetailViewController alloc] initWithUserInfo:userInfo];
    
        // 模态切换(界面跳转)
        [self presentViewController:detailVc animated:YES completion:nil];
    
    }

    steps 3:在DetailViewController.m文件中重写init方法,即实现initWithUserInfo:方法,在这个方法中获取userName的值,此时获取到的值就是从主页传过来的值。

    - (instancetype)initWithUserInfo:(NSDictionary *)userInfo {
        if (self = [super init]) {
            NSLog(@"%@", userInfo);
        }
        return self;
    }

    场景二 详情页传值到主页

    Block块传值

    • block在传值中主要用于回调,现模拟从详情视图控制器传值到主页视图控制器。

    steps 1:在 DetailViewController.h文件中声明block类型、属性以及block回调方法。

    #import <UIKit/UIKit.h>
    
    // 1 声明block类型
    
    typedef void(^CallBackBlock)(NSDictionary *info);
    
    @interface DetailViewController : UIViewController
    
    // 2 声明block属性
    
    @property (nonatomic, copy) CallBackBlock callBackBlock;
    
    / 3 声明block传值方法
    - (void)getsUserInfoWithBlocks:(CallBackBlock)callBackBlock;
    
    
    @end

    steps 2:在 DetailViewController.m文件中,实现如下操作:

    // 4 赋值属性block
    - (void)getsUserInfoWithBlocks:(CallBackBlock)callBackBlock {
        self.callBackBlock = callBackBlock;
    }
    
    // 处理按钮点击
    - (void)respondsToButtonClick:(UIButton *)sender {
        // 5 传值
        if (self.callBack) {
    
            NSDictionary *userInfo = @{@"name":@"Charles", @"age":@(22)};
            self.callBackBlock(userInfo);
    
            [self dismissViewControllerAnimated:YES completion:nil];
        }
    }

    steps 3:在 ViewController.m文件实现如下操作:

    - (void)respondsToButtonClick:(UIButton *)sender {
        DetailViewController *detailVc = [[DetailViewController alloc] init];
    
        // 6 调用block,取值
        [detailVc getsUserInfoWithBlocks:^(NSDictionary *userInfo) {
        NSLog(@"%@", userInfo);
    }];
    
        // 模态切换(界面跳转)
        [self presentViewController:detailVc animated:YES completion:nil];
    }

    Tips:

    1、为block取别名,可在参数列表中将需要传递的参数写成形参;

    2、设置block属性注意使用copy关键字;

    3、设置一个方法持有当前block;

    4、在合适的地方进行调用类似于代理;

    5、在创建该对象的地方进行block方面的调用;

    协议传值

    • 协议传值又称代理传值,可直接将需要传递的值从委托方传送至代理人,协议传值可用于从下一个视图控制器传值到上一个视图控制器(详情页传值到主页),现假定主页是详情页的代理。

    • 传值步骤:

    steps 1:在DetailViewController.h文件中声明协议,并且设置代理属性。

    #import <UIKit/UIKit.h>
    
    
    // @class 意在告诉编译器,“DetailViewController”为一个类。
    
    @class DetailViewController;
    
    // @protocol 声明协议
    // 协议命名规范:类名 + delegate
    
    @protocol DetailViewControllerDelegate <NSObject>
    
    // @optional:声明可选协议方法
    // 协议方法的声明模仿苹果官方声明方式,将类实例以及传递信息一并暴露在参数中
    
    @optional
    
    - (void)detailViewController:(DetailViewController *)detailViewController goBackWithUserInfo:(NSDictionary *)userInfo;
    
    @end
    
    @interface DetailViewController : UIViewController
    
    // 声明代理属性,注意关键字使用 weak || assign,可避免保留环
    @property (nonatomic, weak) id <DetailViewControllerDelegate> delegate;
    @end

    steps 2:在DetailViewController.m文件处理返回按钮方法中调用协议方法传值。

    - (void)respondsToButton:(UIButton *)sender {
        // 首先判断代理人是否存在并且是否遵守协议并且实现了协议方法
        if (_delegate && [_delegate respondsToSelector:@selector(detailViewController:goBackWithUserInfo:)]) {
            // 如果满足判断条件,则让代理执行协议方法,此处让代理人执行协议方法,在代理人那个控制器中的协议方法会被执行;
            // 通常经协议传值在此处调用方法时,直接给参数赋值即可,在代理人控制器实现的协议方法中,可直接获取此处设置的值;
            NSDictionary *userInfo = @{@"name":@"Charles", @"age":@(22)};
            [_delegate detailViewController:self goBackWithUserInfo:userInfo];
        }
    
    }

    steps 3:在HomeViewController.m文件处理界面跳转按钮方法中初始化详情视图控制器,设置详情视图控制器协议代理为self主页),并且遵守<DetailViewControllerDelegate>协议。

    - (void)respondsToButton:(UIButton *)sender {
        // 初始化详情视图控制器
        DetailViewController *detailVc = [[DetailViewController alloc] init];
    
        // 设置代理,并且遵守<DetailViewControllerDelegate>
        detailVc.delegate = self;
    
        // 模态切换(界面跳转)
        [self presentViewController:detailVc animated:YES completion:nil];
    }

    steps 4:在HomeViewController.m中实现<DetailViewControllerDelegate>协议方法,获取值。

    #pragma mark *** DetailViewControllerDelegate ***
    // 实现协议方法,获取值
    - (void)detailViewController:(DetailViewController *)detailViewController goBackWithUserInfo:(NSDictionary *)userInfo {
        NSLog(@"%@", userInfo);
    }

    场景三 多界面传值

    通知传值

    • 通知传值适用于任意控制器(界面),不管两个控制器之间是否有关联,只需满足一个条件,在传值的时候必须保证通知已经被设定,即已添加通知(观察者observer)。现假设从详情界面传值到主界面,即从下一个界面传值到上一个界面,具体实现方式如下。

    • 传值步骤:

    steps 1:注册通知:为保证在传值时通知已经被设定,因此需要在HomeViewController.m文件中注册通知。

    #import "HomeViewController.h"
    #import "DetailViewController.h"
    
    @interface HomeViewController ()
    
    @end
    
    @implementation HomeViewController
    
    - (instancetype)init {
        self = [super init];
        if (self) {
    
        /**
         *  注册通知
         *
         *  @param observer 观察者对象
         *  @param selector 触发方法,即当收到通知之后执行的方法
         *  @param name     通知代号,即通知标识,发送通知时的标识必须和注册通知时的标识一致
         *  @param object   是否传值,在注册通知的时候无需值,因此此处可填nil
         *
         */
    
            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(respondsToNotification:) name:@"notification_name" object:nil];
        }
        return self;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    }
    
    #pragma mark *** responds notification ***
    
    // 处理通知,当接收到通知的时候该方法会自动调用
    // 在此处获取从发送通知的控制器传过来的值
    - (void)respondsToNotification:(NSNotification *)info {
    
    }

    steps 2:发送通知:在DetailViewController.m文件处理返回按钮方法中,发送通知,传值到主界面,发送通知时的标识必须与注册通知时的标识一致。

    - (void)respondsToButton:(UIButton *)sender {
    
        // 发送通知:通知标识必须与注册通知时的标识一致
        // 将需要传递的信息以字典形式赋给 userInfo 参数
        NSDictionary *userInfo = @{@"name":@"Charles", @"age":@(22)};
        [[NSNotificationCenter defaultCenter] postNotificationName:@"notification_name" object:nil userInfo:userInfo];
    
    }

    steps 3:处理通知:在HomeViewController.m文件处理通知方法中,获取值。

    #pragma mark *** responds notification ***
    
    // 处理通知,在此处获取从发送通知的控制器传过来的值
    // 注意:info参数包含两个属性,可通过点语法访问。
    // 1、name:为对应通知的标识
    // 2、userInfo:为传递的信息
    - (void)respondsToNotification:(NSNotification *)info {
        NSLog(@"%@", info.userInfo); 
    }

    steps 4:移除通知:通知在界面被释放的时候一定记得移除,否则可能会导致程序的奔溃。移除通知在注册通知控制器中的[dealloc]方法中实现。

    - (void)dealloc
    {
        // 移除通知
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }

    注意
    1、通知传值的使用会贯穿如下4个步骤:注册通知 -> 发送通知 -> 处理通知 -> 移除通知

    2、通知必须先注册再使用,通知必须在不需要的时候调用remove方法移除。

    单例传值

    • 单例贯穿整个应用程序声明周期,利用单例传值适用于任何控制器,使用前提是在获取值的时候必须保证单例属性有值,否则获取值为nil,此处模拟从主页视图控制器传值到详情视图控制器。

    • 传值步骤:

    steps 1:创建单例,继承于NSObject,任意命名,必须符合规范。此处创建单例类名为Singleton

    steps 2:在Singleton.h中声明传值属性,并且声明单例类便利构造器。

    @interface Singleton : NSObject
    
    @property (nonatomic, strong) NSDictionary *userInfo; /**< 单例属性 */
    
    + (instancetype)defaultSingleton; /**< 单例便利构造器 */
    
    @end

    steps 3:在Singleton.m文件中实现遍历构造器方法。

    #import "Singleton.h"
    
    static Singleton *singleton = nil;
    
    @implementation Singleton
    
    + (instancetype)defaultSingleton {
    
        // GCD创建单例,效率更高,性能更好,消耗更低。
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            singleton = [[Singleton alloc] init];
        });
        return singleton;
    }
    @end

    steps 4:在HomeViewController.m文件中获取单例实例,并且赋值单例属性,赋值位置可根据实际情况进行调整。

    // 单例属性赋值
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        // 获取单例实例,首先需导入Singleton.h
        Singleton *singleton = [Singleton defaultSingleton];
    
        // 单例属性赋值
        NSDictionary *userInfo = @{@"name":@"Charles", @"age":@(22)};
        singleton.userInfo = userInfo;
    }

    steps 5:在DetailViewController.m文件中获取单例属性,取值位置可根据实际情况进行调整。

    // 获取单例属性
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        // 获取单例实例,首先需导入Singleton.h
        Singleton *singleton = [Singleton defaultSingleton];
    
        // 获取单例属性值
        NSLog(@"%@", singleton.userInfo);
    }

    NSUserDefaults传值

    -NSUserDefaults系统单例传值和自定义单例传值基本一致,首先需保证NSUserDefaults对应key中有值,此处模拟主页视图控制器传值到详情视图控制器。

    • 传值步骤:

    steps 1:在HomeViewController.m中获取NSUserDefaults实例,并且存值。

    - (void)saveValueInUserDefaults {
    
        // 获取NSUserDefaults实例
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    
        // 存值
        NSDictionary *userInfo = @{@"name":@"Charles", @"age":@(22)};
        [defaults setObject:userInfo forKey:@"userInfo"];
    
        // 同步数据
        [defaults synchronize];
    }

    steps 2:在DetailViewController.m中获取值

    - (void)getValueInUserDefaults {
    
        // 获取NSUserDefaults实例
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    
        // 根据key获取值
        NSDictionary *userInfo = [defaults objectForKey:@"userInfo"];
    
        NSLog(@"%@", userInfo);
    }
    展开全文
  • 简介 UIImagePickerController是一个独立的控制器类,继承自UINavigationController,因此它拥有UINavigationController相同的功能,但我们无法将它放入到我们自己的导航控制器栈中,它作为一个模态视图单独运行在你...

    简介

    UIImagePickerController是一个独立的控制器类,继承自UINavigationController,因此它拥有UINavigationController相同的功能,但我们无法将它放入到我们自己的导航控制器栈中,它作为一个模态视图单独运行在你的界面之上,提供少量的属性和方法供我们使用,因此我们无法改变它的行为,只能做些简单的选取图片以及照相机的使用。

    UIImagePickerController共有三种 sourceType 可选:

    • UIImagePickerControllerSourceTypePhotoLibrary:所有你能通过iPhone内置的照片应用看得到的,通过这个源类型都能显示出来。

    • UIImagePickerControllerSourceTypeCamera:允许用户使用iPhone内置摄像头拍照。

    • UIImagePickerControllerSourceTypeSavedPhotosAlbum:包含用户通过摄像头拍摄的。

    使用图像拾取器

    使用图像拾取器需要遵守两个协议:<UINavigationControllerDelegate, UIImagePickerControllerDelegate>。

    初始化、配置图像拾取器

    // 选择相册照片
    - (void)selectPhotoAlbumPhotos {
        // 获取支持的媒体格式
        NSArray *mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
        // 判断是否支持需要设置的sourceType
        if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
    
            // 1、设置图片拾取器上的sourceType
            _imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
            // 2、设置支持的媒体格式
            _imagePickerController.mediaTypes = @[mediaTypes[0]];
            // 3、其他设置
            _imagePickerController.allowsEditing = YES; // 如果设置为NO,当用户选择了图片之后不会进入图像编辑界面。
            // 4、推送图片拾取器控制器
            [self presentViewController:_imagePickerController animated:YES completion:nil];
    
        }
    }

    回调方法

    用户选择

    当用户选择了某一张图片或编辑使用了某张图片后会回调以下方法:

    - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info;

    我们可通过上述方法中info参数得到有用的信息,按如下方式可获取字典的具体值:

    UIImage *editedImage = info[@"UIImagePickerControllerEditedImage"];

    下面列举5个常用的字典键值:

    • UIImagePickerControllerMediaType:用户选择的媒体类型,得到的是一个NSString得值,返回@"public.image"或者@"public.movie",通过这个值我们就可以判断用户选取的是图片还是视频了。

    • UIImagePickerControllerOriginalImage:没有被编辑过的原始图像。

    • UIImagePickerControllerEditedImage:用户编辑过后的图像(allowsEditing属性设为YES,通过编辑的到的图像)。

    • UIImagePickerControllerCropRect:返回用户选择的图像区域,它作为一个NSRect数据类型返回。

    • UIImagePickerControllerReferenceURL:返回一个媒体类型的NSURL

    实例,获取选择的图片,赋值给图片视图,呈现在用户界面上。

    // 用户选择了某个媒体
    - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    
        NSLog(@"User chosed imageView media with info '%@'.", info);
    
        _uploadButton.hidden = NO;
    
        if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
            if ([info[UIImagePickerControllerMediaType] isEqualToString:@"public.image"]) {
                UIImage *originalImage = info[UIImagePickerControllerOriginalImage];
                _headPortraitImageView.image = originalImage;
            }
        }else if (picker.sourceType == UIImagePickerControllerSourceTypePhotoLibrary){
            // UIImage *editedImage = info[@"UIImagePickerControllerEditedImage"];
            // _headPortraitImageView.image = editedImage;
    
            _headPortraitImageView.image = info[UIImagePickerControllerEditedImage];
        }
    
        [self dismissViewControllerAnimated:YES completion:nil];
    }

    用户取消

    当用户点击取消按钮的时候会调用下面的方法:

    - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker;

    用户选取了图片或者点击了取消以后,我们还需要添加退出图像拾取器的代码,否则将永远处于图像拾取器界面。需要添加的代码如下所示:

    // 用户点击了取消按钮
    - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
        [self dismissViewControllerAnimated:YES completion:nil];
    }

    使用照相机

    要使用照相机就必须在真机环境下运行,模拟器暂不支持该功能,如果你在模拟器上运行照相机将会直接奔溃。使用照相机很简单,只需将sourceType更改为UIImagePickerControllerSourceTypeCamera即可,别的代码都跟图像拾取器的使用基本一致。

    使用照相机的时候,我们可以使用默认的照相机界面,也可以完全使用自己定制的界面。要自定义界面,我们需要将showsCameraControls属性置为NO;然后将自定义的UIView赋给cameraOverlayView属性即可。

    照相机常用属性

    • cameraCaptureMode:设置相机模式

      • UIImagePickerControllerCameraCaptureModePhoto:拍照
      • UIImagePickerControllerCameraCaptureModeVideo:录制
    • cameraDevice:更改摄像头

      • UIImagePickerControllerCameraDeviceFront:前置摄像头
      • UIImagePickerControllerCameraDeviceRear :后置摄像头
    • cameraFlashMode:设置闪关灯模式

      • UIImagePickerControllerCameraFlashModeOff:关闭闪关灯
      • UIImagePickerControllerCameraFlashModeAuto:自动模式
      • UIImagePickerControllerCameraFlashModeOn:打开闪关灯

    代码示例

    // 拍照
    - (void)takingPictures {
        // 获取支持的媒体格式
        NSArray *mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
    
        // 判断是否支持需要设置的sourceType
        if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
    
            // 1、设置图片拾取器上的sourceType
            _imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
    
            // 2、设置支持的媒体格式
            _imagePickerController.mediaTypes = @[mediaTypes[0]];
            // 3、其他设置
            // 设置相机模式
            _imagePickerController.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
            // 设置摄像头:前置/后置
            _imagePickerController.cameraDevice = UIImagePickerControllerCameraDeviceFront;
            // 设置闪光模式
            _imagePickerController.cameraFlashMode = UIImagePickerControllerCameraFlashModeAuto;
    
    
            // 4、推送图片拾取器控制器
            [self presentViewController:_imagePickerController animated:YES completion:nil];
    
        }else {
            NSLog(@"当前设备不支持拍照");
            UIAlertController * alertController = [UIAlertController alertControllerWithTitle:@"温馨提示"
                                                                                      message:@"当前设备不支持拍照"
                                                                               preferredStyle:UIAlertControllerStyleAlert];
            [alertController addAction:[UIAlertAction actionWithTitle:@"确定"
                                                                style:UIAlertActionStyleDefault
                                                              handler:^(UIAlertAction *action) {
                                                                  _uploadButton.hidden = NO;
                                                              }]];
            [self presentViewController:alertController
                               animated:YES
                             completion:nil];
        }
    }

    使用视频录制

    • 使用视频录制和拍照用法基本一致,只需将 cameraCaptureMode 属性设为 UIImagePickerControllerCameraCaptureModeVideo 即可,代码如下:

    代码示例

    // 录制
    - (void)takingShooting {
        // 获取支持的媒体格式
        NSArray * mediaTypes =[UIImagePickerController  availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
        // 判断是否支持需要设置的sourceType
        if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
            _imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
            _imagePickerController.mediaTypes = @[mediaTypes[1]];
            _imagePickerController.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo;
            [self presentViewController:_imagePickerController animated:YES completion:nil];
        }else {
            NSLog(@"当前设备不支持录像");
            UIAlertController * alertController = [UIAlertController alertControllerWithTitle:@"温馨提示"
                                                                                      message:@"当前设备不支持录像"
                                                                               preferredStyle:UIAlertControllerStyleAlert];
            [alertController addAction:[UIAlertAction actionWithTitle:@"确定"
                                                                style:UIAlertActionStyleDefault
                                                              handler:^(UIAlertAction *action) {
                                                                  _uploadButton.hidden = NO;
                                                              }]];
            [self presentViewController:alertController
                               animated:YES
                             completion:nil];
        }
    }
    展开全文
  • CAGradientLayer 简介 CAGradientLayer是CALayer图层类的子类,用于处理渐变色的层结构。 CAGradientLayer的渐变色可以做隐式动画。 CAGradientLayer和CAShapeLayer配合使用可实现复杂效果。 CAGradientLayer可以...

    CAGradientLayer 简介

    • CAGradientLayer是CALayer图层类的子类,用于处理渐变色的层结构。

    • CAGradientLayer的渐变色可以做隐式动画。

    • CAGradientLayer和CAShapeLayer配合使用可实现复杂效果。

    • CAGradientLayer可以用作PNG的遮罩效果。

    CAGradientLayer 坐标系统

    • CAGradientLayer的坐标系统是从坐标(0,0)到(1,1)绘制的矩形。

    • CAGradientLayer的frame值的size不为正方形的话,坐标系统会被拉伸。

    • CAGradientLayer的startPoint与endPoint会直接影响颜色的绘制方向。

    • CAGradientLayer的颜色分割点是以0~1的比例来计算的,颜色分割点为渐变色开始或终止的地方。

      这里写图片描述

    CAGradientLayer 属性介绍

    • colors:渐变颜色数组

    • locations:渐变颜色的区间分布(分割点),locations的数组长度和colors一致。这个属性可不设,默认是nil,系统会平均分布颜色如果有特定需要可设置,数组设置为0 ~ 1之间单调递增。

    • startPoint:映射locations中起始位置,用单位向量表示。比如(0, 0)表示从左上角开始变化。默认值是:(0.5, 0.0)

    • endPoint:映射locations中结束位置,用单位向量表示。比如(1, 1)表示到右下角变化结束。默认值是:(0.5, 1.0)

    • type:默认值是kCAGradientLayerAxial,表示按像素均匀变化。

    CAGradientLayer 案例

    三原色渐变

    • 效果展示

      这里写图片描述

    • 代码示例

    - (void)viewDidLoad {
    
        [super viewDidLoad];
    
        /**< 初始化colorsView */
        UIView *colorsView = [[UIView alloc] init];
        colorsView.bounds = CGRectMake(0, 0, 220, 220);
        colorsView.center = self.view.center;
        [self.view addSubview:colorsView];
    
        /**< 初始化渐变层 */
        CAGradientLayer *gradientColorLayer = [CAGradientLayer layer];
        gradientColorLayer.frame = colorsView.bounds;
        [colorsView.layer addSublayer:gradientColorLayer];
    
        /**< 设置颜色组 */
        gradientColorLayer.colors = @[(__bridge id)[UIColor redColor].CGColor,
                                      (__bridge id)[UIColor greenColor].CGColor,
                                      (__bridge id)[UIColor blueColor].CGColor];
    
        /**< 设置颜色分割点 */
        gradientColorLayer.locations  = @[@(0.25), @(0.5), @(0.75)];
    
    
        /**< 设置渐变颜色方向 */
        // 1、起始位置
        gradientColorLayer.startPoint = CGPointMake(0, 0);
        // 2、结束位置
        gradientColorLayer.endPoint   = CGPointMake(0, 1);
    
    }

    分割点动画

    • 效果展示

      这里写图片描述

    • 代码示例

    #import "ViewController.h"
    
    @interface ViewController ()
    
    @property (strong, nonatomic) CAGradientLayer *gradientLayer;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
    
        [super viewDidLoad];
    
        // 添加 CAGradientLayer
        [self.view.layer addSublayer:self.gradientLayer];
    
        // 延时3秒执行,实现分割点动画(隐式动画)
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            // 颜色分割点效果
            self.gradientLayer.locations = @[@(0.4), @(0.5), @(0.6)];
        });
    
    }
    
    #pragma mark - Getter methods
    
    - (CAGradientLayer *)gradientLayer {
        if (!_gradientLayer) {
            // 初始化并创建
            _gradientLayer             = [CAGradientLayer layer];
            _gradientLayer.frame       = CGRectMake(0, 0, 250, 250);
            _gradientLayer.position    = self.view.center;
            _gradientLayer.borderWidth = 1.f;
    
            // 设置颜色
            _gradientLayer.colors = @[(__bridge id)[UIColor redColor].CGColor,
                                      (__bridge id)[UIColor greenColor].CGColor,
                                      (__bridge id)[UIColor blueColor].CGColor];
    
            // 设置颜色渐变方向
            _gradientLayer.startPoint = CGPointMake(0, 0);
            _gradientLayer.endPoint   = CGPointMake(1, 0);
    
            // 设置颜色分割点
            _gradientLayer.locations  = @[@(0.25), @(0.5), @(0.75)];
        }
        return _gradientLayer;
    }
    
    @end

    色差动画

    • 实现思路

      • 确定渐变色渐变方向;

      • 至少设定两种颜色,此处设置两种颜色为例,其中一种是透明色,另外一种是自定义颜色。

      • 设定好locations颜色分割点。

    • 效果展示

      这里写图片描述

    • 代码示例

    #import "ViewController.h"
    
    @interface ViewController () {
    
        NSTimer *_timer; /**< 定时器 */
    }
    
    @property (strong, nonatomic) CAGradientLayer *gradientLayer; /**< 渐变层 */
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
    
        [super viewDidLoad];
    
        self.view.backgroundColor = [UIColor blackColor];
    
        // 创建背景图片
        UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"image"]];
        imageView.bounds       = CGRectMake(0, 0, 260, 450);
        imageView.center       = self.view.center;
        [self.view addSubview:imageView];
    
        // 添加渐变层
        [imageView.layer addSublayer:self.gradientLayer];
    
        // 初始化定时器
        _timer = [NSTimer scheduledTimerWithTimeInterval:1.f
                                                  target:self
                                                selector:@selector(respondsToTimerEvent)
                                                userInfo:nil
                                                 repeats:YES];
    
    
    }
    
    #pragma mark - Timer and animations methods
    - (void)respondsToTimerEvent {
        // 设定颜色组动画
        self.gradientLayer.colors = @[(__bridge id)[UIColor clearColor].CGColor,
                                      (__bridge id)[UIColor colorWithRed:arc4random()%255 / 255.f
                                                                   green:arc4random()%255 / 255.f
                                                                    blue:arc4random()%255 / 255.f
                                                                   alpha:1].CGColor];
        // 设置颜色分割点动画
        self.gradientLayer.locations = @[@(arc4random() %10 / 10.f), @(1.f)];
    }
    
    #pragma mark - Getter methods
    - (CAGradientLayer *)gradientLayer {
        if (!_gradientLayer) {
            // 初始化渐变层
            _gradientLayer       = [CAGradientLayer layer];
            _gradientLayer.frame = CGRectMake(0, 0, 260, 450);
    
            // 设置颜色渐变方向
            _gradientLayer.startPoint = CGPointMake(0, 0);
            _gradientLayer.endPoint   = CGPointMake(0, 1);
    
            // 设定颜色组
            _gradientLayer.colors = @[(__bridge id)[UIColor clearColor].CGColor,
                                      (__bridge id)[UIColor blueColor].CGColor];
    
            // 设定颜色分割点
            _gradientLayer.locations = @[@(0.5f), @(1.f)];
        }
        return _gradientLayer;
    }
    
    @end
    展开全文
  • 作者:朱克锋 邮箱:zhukefeng@iboxpay.com 转载请注明出处:http://blog.csdn.net/linux_zkf NSString* ASCIIConvertFromBCD(NSString *bcdString) { ... char PDUpack[len/2+1

    作者:朱克锋

    邮箱:zhukefeng@iboxpay.com

    转载请注明出处:http://blog.csdn.net/linux_zkf


    NSString* ASCIIConvertFromBCD(NSString *bcdString)

    {

        int len = bcdString.length;

        char PDUpack[len/2+1], *PDUStr;

        bzero(PDUpack, len/2+1);


        PDUStr = (char *)[bcdString cStringUsingEncoding:NSUTF8StringEncoding];

    for (int i=0; i <len; i+=2) {

    char tempchar;

            tempchar = PDUStr[i];

    if ((tempchar <='9') && (tempchar >= '0')) {

    tempchar = tempchar & 0x0f;

    }

    else {

    tempchar = (tempchar & 0x0f) + 9;

    }

    PDUpack[i/2] = tempchar;

    tempchar = PDUStr[i+1];

    if ((tempchar <= '9') && (tempchar >='0')) {

    tempchar = tempchar & 0x0f;

    }

    else {

    tempchar = (tempchar & 0x0f) + 9;

    }

            PDUpack[i/2] = ((PDUpack[i/2] << 4 ) & 0xf0) + tempchar;

    }

        

        NSString* retString = [[NSString alloc] initWithCString:PDUpack encoding:NSUTF8StringEncoding];

        return retString;

    }


    展开全文
  • 简介在iOS开发中,可能会用到发短信、发邮件、打电话及摇一摇等功能,如下我将简单介绍几种功能的具体实现方法。需要注意的是,如下功能的实现必须通过真机调试,模拟器暂不支持如上功能。打电话methods 1:直接跳转...

    简介

    在iOS开发中,可能会用到发短信、发邮件、打电话及摇一摇等功能,比如在应用程序的‘关于’界面,我们可能会留下电话号码或邮箱等联系方式,为了方便用户直接在应用程序中做操作,提升用户体验,我们会设计一些交互动作,让用户轻松的去发短信、打电话或发邮件等。如下我将简单介绍几种功能的具体实现方法。需要注意的是,如下功能的实现必须通过真机调试,模拟器暂不支持如上功能。

    打电话

    methods 1:直接跳转到打电话界面

    NSURL *url = [NSURL URLWithString:[@"tel://电话号码"];
    
    [[UIApplication sharedApplication] openURL:url];

    缺陷:直接拨打,不提示。

    methods 2:直接跳转到打电话界面,有提示

    NSURL *url = [NSURL URLWithString:[@"telprompt://电话号码"];
    
    [[UIApplication sharedApplication] openURL:url];

    methods 3:基于UIWebView实现打电话功能,有提示

    UIWebView *webView = [[UIWebView alloc] init];
    
    NSURL *url = [NSURL URLWithString:[@"tel://电话号码"];
    
    [webView loadRequest:[NSURLRequest requestWithURL:url]];
    
    [self.view addSubview:webView];

    发短信

    methods 1:直接跳转到发送短信界面

    NSURL *url = [NSURL URLWithString:[@"sms://手机号码"];
    
    [[UIApplication sharedApplication] openURL:url];

    缺陷:不能定义发送短信的内容,且发完短信后不能自动回到原应用。

    methods 2:使用 MessageUI 框架发送短信

    注意:需要包含头文件 #import

    MFMessageComposeViewController *msgVc = [[MFMessageComposeViewController alloc] init];
    
    // 设置短信内容
    msgVc.body = @"您好,今天天气不错,一起出去玩么?";
    
    // 设置收件人列表
    msgVc.recipients = @[电话号码];
    
    // 设置代理
    msgVc.messageComposeDelegate = self;
    
    // 显示控制器
    [self presentViewController:msgVc animated:YES completion:nil];
    }

    实现代理方法:

    // 点击取消按钮会自动调用
    - (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result {
    
        [controller dismissViewControllerAnimated:YES completion:nil];
    
    }

    发邮件

    methods 1:用自带的邮件客户端

    NSURL *url = [NSURL URLWithString:[@"mailto://邮箱地址"];
    
    [[UIApplication sharedApplication] openURL:url];

    methods 2:使用 MessageUI 框架发送邮件

    // 异常处理
    if (![MFMailComposeViewController canSendMail]) {
        return;
    }
    
    MFMailComposeViewController *mailVc = [[MFMailComposeViewController alloc] init];
    
    // 设置邮件主题
    [mailVc setSubject:@"部门会议"];
    
    // 设置邮件内容
    [mailVc setMessageBody:@"下午3点半,召开部门会议,请准时参加。" isHTML:NO];
    
    // 设置收件人列表
    [mailVc setToRecipients:@[收件人邮箱地址]];
    
    // 设置抄送人列表
    [mailVc setCcRecipients:@[抄送人邮箱地址]];
    
    // 设置代理
    mailVc.mailComposeDelegate = self;
    
    // 显示控制器
    [self presentViewController:mailVc animated:YES completion:nil];

    实现代理方法

    #pragma mark - MFMailComposeViewControllerDelegate
    - (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
    
        [controller dismissViewControllerAnimated:YES completion:nil];
    
    }

    摇一摇

    iOS本身支持摇一摇功能,在UIResponder中存在如下方法:

    // 1、检测到摇动
    - (void)motionBegan:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(3_0);
    
    // 2、摇动结束
    - (void)motionEnded:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(3_0);
    
    // 3、摇动取消
    - (void)motionCancelled:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(3_0);

    使用摇一摇功能实际很简单,首先你只需调用如下方法让控制器支持摇动即可:

    [[UIApplication sharedApplication] setApplicationSupportsShakeToEdit:YES];

    其次你还需将视图控制器成为第一响应者,如下所示:

    [self becomeFirstResponder];

    代码示例:

    #import "ViewController.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        [[UIApplication sharedApplication] setApplicationSupportsShakeToEdit:YES];
    
        [self becomeFirstResponder];
    }
    
    
    #pragma mark - Motion methos
    - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {
        NSLog(@"检测到摇动");
    }
    
    - (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event {
        NSLog(@"摇动取消");
    }
    
    - (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
        NSLog(@"摇动结束");
    
        if (event.subtype == UIEventSubtypeMotionShake) {
            // 处理业务逻辑
        }
    }
    
    @end

    打电话、发短信、发邮件案例

    效果展示

    这里写图片描述

    代码示例

    #import "ViewController.h"
    #import <MessageUI/MessageUI.h>
    
    #define Screen_Width [UIScreen mainScreen].bounds.size.width
    
    @interface ViewController () <MFMessageComposeViewControllerDelegate, MFMailComposeViewControllerDelegate>
    
    @property (nonatomic, strong) UITextField *textField;
    @property (nonatomic, strong) UIButton *callBtn;
    @property (nonatomic, strong) UIButton *sendMsgBtn;
    @property (nonatomic, strong) UIButton *sendEmailBtn;
    
    - (void)initializeUserInterface; /**< 初始化用户界面 */
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        [self initializeUserInterface];
    }
    
    #pragma mark - Initialize
    - (void)initializeUserInterface {
        self.view.backgroundColor = [UIColor whiteColor];
    
        [self.view addSubview:self.textField];
        [self.view addSubview:self.callBtn];
        [self.view addSubview:self.sendMsgBtn];
        [self.view addSubview:self.sendEmailBtn];
    }
    
    #pragma mark - Events
    - (void)respondsToCallBtn:(UIButton *)sender {
    
        [self.view endEditing:YES];
    
        NSString *phoneNumber = self.textField.text;
    
        // 方法一:
        // NSURL *url = [NSURL URLWithString:[@"tel://" stringByAppendingString:phoneNumber]];
        // [[UIApplication sharedApplication] openURL:url];
    
        // 方法二:
        // NSURL *url = [NSURL URLWithString:[@"telprompt://" stringByAppendingString:phoneNumber]];
        // [[UIApplication sharedApplication] openURL:url];
    
        // 方法三:
        UIWebView *webView = [[UIWebView alloc] init];
        NSURL *url = [NSURL URLWithString:[@"tel://" stringByAppendingString:phoneNumber]];
        [webView loadRequest:[NSURLRequest requestWithURL:url]];
        [self.view addSubview:webView];
    
    }
    
    - (void)respondsToSendMsgBtn:(UIButton *)sender {
        [self.view endEditing:YES];
    
        NSString *phoneNumber = self.textField.text;
    
        // 方法一:直接跳转到发短信界面
        // 缺点:不能定义发送短信的内容,且发完短信后不能自动回到原应用。
    
        // NSURL *url = [NSURL URLWithString:[@"sms://" stringByAppendingString:phoneNumber]];
        // [[UIApplication sharedApplication] openURL:url];
    
        // 方法二:使用MessageUI 框架发送短信,需要包含头文件 #import <MessageUI/MessageUI.h>
    
        MFMessageComposeViewController *msgVc = [[MFMessageComposeViewController alloc] init];
        // 设置短信内容
        msgVc.body = @"您好,今天天气不错,一起出去玩么?";
        // 设置收件人列表
        msgVc.recipients = @[phoneNumber];
        // 设置代理
        msgVc.messageComposeDelegate = self;
        // 显示控制器
        [self presentViewController:msgVc animated:YES completion:nil];
    }
    
    - (void)respondsToSendEamilBtn:(UIButton *)sender {
        [self.view endEditing:YES];
    
        NSString *email = self.textField.text;
    
        // 方法一:用自带的邮件客户端
        // 缺点:发完邮件后不会自动回到原应用
         NSURL *url = [NSURL URLWithString:[@"mailto://" stringByAppendingString:email]];
         [[UIApplication sharedApplication] openURL:url];
    
        // 方法二:类似于发短信的第二种方法
        // 异常处理
        /*
        if (![MFMailComposeViewController canSendMail]) {
            return;
        }
        MFMailComposeViewController *mailVc = [[MFMailComposeViewController alloc] init];
        // 设置邮件主题
        [mailVc setSubject:@"部门会议"];
        // 设置邮件内容
        [mailVc setMessageBody:@"下午3点半,召开部门会议,请准时参加。" isHTML:NO];
        // 设置收件人列表
        [mailVc setToRecipients:@[email]];
        // 设置抄送人列表
        [mailVc setCcRecipients:@[]];
        // 设置代理
        mailVc.mailComposeDelegate = self;
        // 显示控制器
        [self presentViewController:mailVc animated:YES completion:nil];
         */
    }
    
    #pragma mark - Touches
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        [self.view endEditing:YES];
    }
    
    #pragma mark - MFMessageComposeViewControllerDelegate
    // 点击取消按钮会自动调用
    - (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result {
        [controller dismissViewControllerAnimated:YES completion:nil];
    }
    
    #pragma mark - MFMailComposeViewControllerDelegate
    - (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
        [controller dismissViewControllerAnimated:YES completion:nil];
    }
    
    #pragma mark - Getters
    // 打电话布局
    - (UITextField *)textField {
        if (!_textField) {
            _textField = [[UITextField alloc] init];
            _textField.bounds = CGRectMake(0, 0, Screen_Width * 0.85, 45);
            _textField.center = CGPointMake(Screen_Width * 0.5, 64 + CGRectGetMidY(_textField.bounds) + 10);
            _textField.textAlignment = NSTextAlignmentCenter;
            _textField.placeholder = @"请输入手机号码或邮箱";
            _textField.clearButtonMode = UITextFieldViewModeWhileEditing;
            _textField.borderStyle = UITextBorderStyleBezel;
        }
        return _textField;
    }
    
    - (UIButton *)callBtn {
        if (!_callBtn) {
            _callBtn = [UIButton buttonWithType:UIButtonTypeSystem];
            _callBtn.bounds = CGRectMake(0, 0, 100, 30);
            _callBtn.center = CGPointMake(Screen_Width * 0.5, CGRectGetMaxY(self.textField.frame) + CGRectGetMidX(_callBtn.bounds) + 20);
            _callBtn.titleLabel.font = [UIFont boldSystemFontOfSize:20];
            [_callBtn setTitle:@"拨打电话" forState:UIControlStateNormal];
            [_callBtn addTarget:self action:@selector(respondsToCallBtn:) forControlEvents:UIControlEventTouchUpInside];
        }
        return _callBtn;
    }
    
    // 发消息
    - (UIButton *)sendMsgBtn {
        if (!_sendMsgBtn) {
            _sendMsgBtn = [UIButton buttonWithType:UIButtonTypeSystem];
            _sendMsgBtn.bounds = CGRectMake(0, 0, 100, 30);
            _sendMsgBtn.center = CGPointMake(Screen_Width * 0.5, CGRectGetMaxY(self.callBtn.frame) + CGRectGetMidY(_sendMsgBtn.bounds) + 20);
            _sendMsgBtn.titleLabel.font = [UIFont boldSystemFontOfSize:20];
            [_sendMsgBtn setTitle:@"发送信息" forState:UIControlStateNormal];
            [_sendMsgBtn addTarget:self action:@selector(respondsToSendMsgBtn:) forControlEvents:UIControlEventTouchUpInside];
        }
        return _sendMsgBtn;
    }
    
    // 发邮件
    - (UIButton *)sendEmailBtn {
        if (!_sendEmailBtn) {
            _sendEmailBtn = [UIButton buttonWithType:UIButtonTypeSystem];
            _sendEmailBtn.bounds = CGRectMake(0, 0, 100, 30);
            _sendEmailBtn.center = CGPointMake(Screen_Width * 0.5, CGRectGetMaxY(self.sendMsgBtn.frame) + CGRectGetMidY(_sendEmailBtn.bounds) + 20);
            _sendEmailBtn.titleLabel.font = [UIFont boldSystemFontOfSize:20];
            [_sendEmailBtn setTitle:@"发送邮件" forState:UIControlStateNormal];
            [_sendEmailBtn addTarget:self action:@selector(respondsToSendEamilBtn:) forControlEvents:UIControlEventTouchUpInside];
        }
        return _sendEmailBtn;
    }
    
    @end
    展开全文
  • iOS-OC-类和对象

    2018-03-05 17:30:01
    一、面向对象OC语言是面向对象的,c语言是面向过程的,面向对象和面向过程只是解决问题的两种思考方式,面向过程关注的是解决问题涉及的步骤,面向对象关注的是设计能够实现解决问题所需功能的类。术语:OO面向对象...
  • iOS oc页面的跳转

    2016-07-06 16:47:35
    可调用的方法接口:[self.navigationController] 1、popToViewController:跳转至指定页面; 2、pushViewController:将指定页面压入堆栈; 3、popViewController:退出当前页面,显示堆栈里的上一个页面;
  • 1.打开Xcode,点击Create a new Xcode project2.新建项目 3.输入项目名称 4.进入main.m 5.输入NSLog(@”hello world”);并点击左上方三角形按钮,运行程序 6.在右下方输出运行结果
  • 第一种: [UIView animateWithDuration:3 delay:3 options:1 animations:^{ self.btn.transform = CGAffineTransformMakeTranslation(300, 400); } completion:^(BOOL finished) { NSLog(@"view ani...
  • iOS 判断系统版本

    2018-02-12 17:12:18
    由于各种原因,程序需要兼容iOS以前的版本,那么设置一个较低的部署目标和基于特定iOS版本的代码分支,就显得很有必要了。 举个例子: 以前我们判断iOS版本会如下写: if ([[[UIDevice currentDevice].system...
  • 1.导入头文件 #import 2.申明对象 @property(strong,nonatomic) CBCentralManager* CM; 3.遵守代理方法 CBCentralManagerDelegate 4.初始化对象,设置代理 self.CM = [[CBCentralManager...alloc] init
  • iOS 实现简易的计算器

    2018-08-23 14:09:50
    先看效果: 主要代码: NSDecimalNumber * number1 = [NSDecimalNumber decimalNumberWithString :@“12.5”]; NSDecimalNumber * number2 = [NSDecimalNumber decimalNumberWithString :@“2.5”];...
  • 今天遇见一行代码实现打开一个网页,比起印象里的UIWebView控件实现简单很多,很容易使用而且,经过真机测试却是很方便使用,在网上又搜索了一点相关资料: 代码段:[[UIApplication sharedApplication] ...
  • iOS 获取wifi信号强度

    2016-10-28 17:43:15
    虽然各种直接获取信号强度的api都被封杀了。但是还有一个另类的黑魔法可以获取到。那就是遍历UIStatusBar了- (void)getSignalStrength{ UIApplication *app = [UIApplication sharedApplication];...
  • ios 正则表达式替换

    2014-09-29 10:04:52
    1. 不可变字符串 (content 是不可变) NSRegularExpression *regularExpression = [NSRegularExpression regularExpressionWithPattern:  @"" options:0 error:nil];  content =
  • iOS入门一(计算器)

    2018-10-06 10:03:17
    使用xcode创建项目Calculator 然后点开Main.storyboard,在右边最下面拖个Label进画板里面 storyboard就是故事版 ... 如果觉得空间很拥挤,可以把左边和右边的视图隐藏掉 现在来看ViewController.swift ...
  • ios添加的手势传值

    2014-04-16 14:46:43
    手shi接收的参数就是你的手势对象。
  • iOS 拨打电话三种方式总结 转自:http://blog.csdn.net/ouy_huan/article/details/30506925 1,这种方法,拨打完电话回不到原来的应用,会停留在通讯录里,而且是直接拨打,不弹出提示 NSMutableString * ...
  • start: 1.加载二进制 2.检查沙箱 3.Objective-C Class Load Initialize 4._attribute_((constructor))函数,C++全局对象构造函数 5.加载必要的资源(info.plist),并显示启动页(加载framework,动态静态链接库,...
  • IOS四种保存文件的方式 分类: Iphone开发2012-08-01 00:16 306人阅读 评论(0) 收藏 举报 转载地址:http://blog.csdn.net/tianyitianyi1/article/details/7713103  在iOS开发过程中,不管是做什么...
1 2 3 4 5 ... 20
收藏数 61,561
精华内容 24,624
热门标签
关键字:

ocios