ios开发_ios开发教程 - CSDN
  • iOS9程序设计(顶级iOS开发视频课程-Objective-C版) 本课程主要内容包括: iOS9的基础知识 常用控件 屏幕适配 多窗口 导航 表视图 GPS 地图 网络 数据存储、 音频 视频 本地化等内容,并提供了大量的...
  • iOS开发教程之OC语言

    2019-06-21 09:58:34
    Objective-C是扩充C的面向对象编程语言,iOS开发是用的Objective-C语言,本专题更系统的讲解Objective-C语言当中的一些要点,类的封装、基本数据结构(NSString、NSData)、继承、内存管理(retain点语法、MyArray、...
  • iOS开发入门教程

    2016-07-22 21:52:18
    iOS开发入门教程,从创建项目到运行项目,包括OC基础,调试,模拟器设置等相关知识。 程序发轻狂,代码阑珊,苹果开发安卓狂!——写给狂热的编程爱好者们 写在前面的话 学习iOS应用程序开发已有一段...
    摘要
    iOS开发入门教程,从创建项目到运行项目,包括OC基础,调试,模拟器设置等相关知识。

    程序发轻狂,代码阑珊,苹果开发安卓狂!——写给狂热的编程爱好者们

    本文概览

    写在前面的话

    学习iOS应用程序开发已有一段时间,最近稍微闲下来了,正好也想记录一下前阶段的整个学习过程。索性就从最基础的开始,一步一步记录一个最简单的iOS应用从创建到运行的全过程,其中会穿插很多相关知识或是遇到过的问题。其实算不上教程,但希望能够帮助更多的开发爱好者更快、更好的入门。

    iOS开发环境简述

    最友好,最现实,也是最方便的开发环境就是在Mac系统中安装Xcode进行开发。原因在于:第一,开发工具(Xcode)限制。苹果官方只提供Mac版的Xcode,而Xcode内置了Xcode IDE,性能分析工具,iOS SDK,iOS模拟器和最新的OS X,可以方便迅速的进行代码编辑以及应用调试,可谓是Mac和iOS开发工具的不二选择。第二,代码提示和自动补全。iOS开发中用到的类或方法的名称,为了更具语义化,让开发者一目了然,通常会比较长,这往往会让刚刚接触iOS开发的开发者为了记住这些方法而伤透脑经。而Xcode拥有优于其他编辑器的OC代码提示和自动补全功能,这将很大程度降低开发入门的门槛,这决定你开发iOS应用没有理由不使用Xcode。因此,使用非苹果电脑的开发者们最好安装Mac OS X的虚拟机,进行开发学习,否则你不仅会比别人花上多出一倍甚至更多的时间去搭建开发环境,而且代码编写上也会比使用Xcode开发的人花上更多的精力。

    第一步,创建项目

    1.1 新建iOS项目

    打开Xcode,如果是首次打开Xcode,你将会看到一个欢迎界面,如图:

    Welcome to Xcode

    你可以直接在该界面中点击图中1处标记的Create a new Xcode project来创建一个项目,也可以点击图中2处标记的按钮来打开电脑中已经存在的Xcode项目。你还可以修改3处标记的复选框状态设置下次启动Xcode是否显示该欢迎界面。

    本文不演示在此点击1处所示创建项目,首先点击该界面左上角的红色按钮退出该欢迎界面,然后点击屏幕左上角的File->New->Project。截图如下:

    新建项目

    接下来你将看到如下界面:

    选择应用模板

    首先进行系统筛选,iOS应用则选择iOS列表对应项,OS X应用则选择OS X列表对应项。本例为iOS应用,故在此选择iOS中的Application(图中左上角红框所示),然后选择应用模板选择,在界面右边列出了多种最常用的应用模板类型,开发者按照自己的应用需求可自行选择,本例选择Single View Application(图中右上角红框所示)。做完以上选择后点击窗口右下角Next按钮,进入下一个设置窗口:

    应用基础信息设置

    此处内容会根据个人情况而不同,故不做赘述,按照窗口提示,填写相关信息即可。注意窗口下方的三个复选框,其功能分别是使用storyboards使用自动引用计数器包含单元测试,根据个人情况勾选/取消即可。设置完成后点击右下角Next按钮,进入下一个窗口:

    选择保存位置

    按照窗口所示,选择项目存储位置后点击窗口右下角Create按钮,完成应用创建过程。

    1.2 应用程序目录结构说明

    项目创建完成之后,Xcode会进入项目开发界面,界面大致分为三部分,左侧项目及目录结构列表、中间为代码编辑区、右侧属性设置和控件列表等区域。下面是目录结构的截图:

    项目目录结构

    项目初始时包含如图所示三个主要目录,后续开发中开发者可以自行添加目录。其中:

    • FirstIosApp目录与项目名称同名,主要存放应用相关源代码和配置文件;
    • Framework存放项目使用到的框架,默认会添加图示三个必备框架;
    • Products用于存放生成的应用文件,开发中开发者一般不必关心。

    1.3 应用程序初始结构概览

    整个应用程序的入口文件默认为AppDelegate.m,应该可以通过配置文件修改(未尝试)。其内部结构如下:

    应用程序入口结构

    该文件包含应用程序生命周期中各个阶段可以调用的方法接口,以便应用程序在不同的状态阶段能进行相应的操作。这些方法就不一一说明了,开发者几乎可以望名知意。

    1.3.1 iOS应用程序的生命周期

    对于上面图示方法如果还有不解的地方,可以参考下图(来源于网络):

    iOS生命周期

    第二步 代码入门(数据类型)

    做iOS开发,仅仅懂得使用Xcode,仅仅了解目录结构,仅仅了解生命周期,是远远不够的,这些只是基础中的基础。一定的编程能力也是必不可少的。下面就简单的介绍一下iOS开发的编程语言——Objective-C,后面简称OC。

    学习一门语言,往往需要从最基础的数据类型开始(记得大学学习的时候老师就是这么干的),至于编程逻辑,奇技淫巧等则是在开发过程中慢慢积累的。好言归正传。

    2.1 基础数据类型

    OC是C语言的一个超类,因此OC拥有C或C++的几乎所有特性,当然它也有自己独具一格的地方。所以OC也支持C语言的数据类型,诸如int,float等也都可以在OC中使用。基础数据类型不是本文重点,在此就不多言辞了。

    2.2 OC数据类型

    OC不是仅仅只能使用C/C++的数据类型,它也拥有自己的数据类型,虽然与通常人们熟知的各种数据类型看起来有点怪异,但事实上OC的数据类型是个很好玩的东西,也不难理解。下面列举几个常见的OC数据类型。

    2.1.1 NSNumber类和NSInterger

    NSNumber是以对象的形式来包装基础数据类型,它提供以下方法:

    <!-- lang: cpp -->
    + (NSNumber *) numberWithChar: (char) value;
    + (NSNumber *) numberWithInt: (int) value;
    + (NSNumber *) numberWithFloat: (float) value;
    + (NSNumber *) numberWithBool: (BOOL) value;
    

    例如,要从一个int数据初始化一个NSNumber可以这样写:

    <!-- lang: cpp -->
    NSNumber *number = [NSNumber numberWithInt: 100];
    

    而要从NSNumber实例得到NSInteger数据则可以如下操作:

    <!-- lang: cpp -->
    NSInteger integer = [number intValue];
    
    2.1.2 NSString类型

    NSString是OC的字符串类。与普通字符串不同的是NSString的值需要在普通字符串前加上一个@符号。例如要初始化一个'I'm a string.'的OC字符串,我们需要这样做:

    <!-- lang: cpp -->
    NSString *str = [NSString stringWithString: @"I'm a string."];
    

    看起来很麻烦,很复杂的样子,不要担心,OC应该也考虑到了这一点,所以它也提供简写形式:

    <!-- lang: cpp -->
    NSString *str = @"I'm a string.";
    

    NSString类还提供了很多其他形式的创建字符串的方法(比如:stringWithFormat等),这里就不一一列举了,以后在开发中慢慢体会吧。

    2.1.3 NSArray类型

    NSArray是OC的数组类。OC的数组是很强大的,在一个数组中可以允许存在不同类型的数据,这个特性就跟强大的JavaScrit一样。初始化一个数组可以这样操作:

    <!-- lang: cpp -->
    NSArray *arr = [NSArray arrayWithObjects:@"a", @"b", @1, nil];
    

    当然也支持简化形式:

    <!-- lang: cpp -->
    NSArray *arr = @[@"a", @"b", @1];
    

    需要说明一点,使用arrayWithObjects方法创建数组的时候最后需要以nil结尾,而使用简化方式的时候不需要。

    开发中可以使用以下两种形式获取数组对应索引位置(index)的值:

    <!-- lang: cpp -->
    NSString *a = arr[index];
    NSString *b = [arr objectAtIndex: index];
    

    2.1.4 NSDictionary类型

    NSDictionary是OC的字典类。字典类型在使用中以key-value键值对的形式存在。也支持多种初始化方式,下面列举两种:

    <!-- lang: cpp -->
    NSDictionary *dic = [NSDictionary dictionaryWithObjects:@[@"a",@"b", @"c"] forKeys:@[@"first", @"second", @"third"]];
    //或者使用下面的形式
    NSDictionary *dic = @{@"first": @"a", @"second": @"b", @"third": @"c"};
    

    取值方法跟NSArray大同小异:

    <!-- lang: cpp -->
    NSString *a = [dic objectForKey: @"first"];
    NSString *b = dic[@"second"];
    

    2.1.5 NSDate类型

    NSDate是OC的日期类。常见用法举例:

    <!-- lang: cpp -->
    NSDate *date = [NSDate date]; //返回当前时间
    NSDate *date = [[NSDate alloc] init]; //初始化为当前时间,类似date
    

    第三步 OC类的认识(成员变量和方法)

    iOS开发常常伴随着视图,而视图往往离不开视图控制器,在iOS开发中每一个视图控制器就是一个OC的类,因此学习iOS开发就必须了解OC的类。

    OC的类使用@interface ClassName: superClass <protocol> … @end结构来定义,NSObject是所有OC类的父类。与java相比OC的@interface关键字就等同于JAVA的class关键字,OC的protocol就是JAVA中的interface,这一点很据迷惑力,大家在学习时需要特别注意。

    3.1 类的声明

    举例声明一个Person的类(视图控制器)并实现它,拥有nameage两个成员变量,自然需要定义getNamesetNamegetAgesetAge,下面我们看下这个过程。

    首先,类的结构如下:

    <!-- lang: cpp -->
    @interface Person: NSObject {
        NSString *name;
        int age;
    }
    
    @end
    

    然后,我们声明它的setter和getter方法,用来设置和读取它的成员变量的值。按照传统方式应该如下定义:

    <!-- lang: cpp -->
    @interface Person: NSObject {
        NSString *name;
        int age;
    }
    
    - (void) setName: (NSString *) newName;
    - (NSString *) getName;
    
    - (void) setAge: (int) newAge;
    - (int) getAge;
    
    @end
    

    看,是不是很简单?然而,既然上面说了是传统方式,那么肯定OC还提供了更现代的方式:

    <!-- lang: cpp -->
    @interface Person: NSObject {
        NSString *name;
        int age;
    }
    
    @property(nonatomic, strong) NSString *name;
    @property(nonatomic, assign) int age;
    
    @end
    

    没错,你没看错,就这么简单,它的功能和上面的代码是一样的。补充一下,@property本身可以接受参数来指定变量的getter和setter方式,其参数可用值和具体功能如下:

    <!-- lang: cpp -->
    nonatomic //声明变量只在单线程中工作
    atomic //默认值,可能有多个线程会用到这个变量
    
    copy //分配一个新的空间,把原地址的内容复制过来
    assign //简单的传递指针
    retain //传递指针后引用计数器(retainCount)会自加1
    
    strong //强引用
    weak //弱引用
    

    声明就这样就完成了,下面我们看下它的具体实现,在OC中类的实现需要使用另外一个关键字@implementation,格式如下:

    <!-- lang: cpp -->
    @implementation Person
    
    @end
    

    我们还是先看下传统方式声明getter和setter方法该如何实现:

    <!-- lang: cpp -->
    @implementation Person
    
    - (void) setName: (NSString *) newName {
        self.name = newName;
    }
    
    - (NSString *) getName {
        return self.name;
    }
    
    - (void) setAge: (int) newAge {
        self.age = newAge;
    }
    
    - (int) getAge {
        return self.age;
    }
    
    @end
    

    看完传统实现方式,是不是很想一睹现代方式的风采?我们继续往下看:

    <!-- lang: cpp -->
    @implementation Person
    
    @synthesize name;
    @synthesize age;
    //或者直接下面一句
    //@synthesize name,age;
    
    @end
    

    是不是很神奇?在新版的Xcode中,@synthesize是可以省略的,但是建议还是都写上。

    3.2 “+”和“-”

    仔细的读者应该已经发现在上面的传统方式中包含了一个神奇的符号“-”。这个是什么意思呢?首先我们需要说明一下,一个类可以拥有成员变量和方法,而方法可以包含类方法和实例方法。所谓类方法是可以使用类名直接调用的方法,而实例方法是需要该类的实例才可以调用的方法。而在OC中使用“+”表示该方法为类方法,而“-”很简单自然是表示实例方法了。

    至于方法的声明和实现大致和传统方式声明getter和setter是一样的,这部分就不再重复了。

    第四步 运行和调试

    每一个应用的开发过程都是漫长的,而在这个过程中我们免不了需要不时的运行一下程序,看看当前的效果,检查一下代码是否存在异常或者错误。

    4.1 iOS模拟器

    4.1.1 选择设备

    Xcode的强大不是吹出来的,在Xcode中内置了iOS模拟器,能够模拟几乎所有iOS真机的功能,因此开发者可以通过iOS模拟器测试正在开发中的应用程序,提高开发效率,减少错误,节省开发时间。在运行前选择与应用对应的模拟设备是必须的,否则可能导致运行结果出现意外的问题。

    在Xcode的菜单栏下方提供了选择模拟器的地方,如图所示:

    选择模拟器

    选择好模拟器后点击左侧的Run按钮,就可以在指定的模拟器中启动应用了。第一次启动模拟器一般会比较慢,后面就好了。同样可以点击Run旁边的Stop按钮,停止模拟器中的当前应用。也许有些时候你想独立运行iOS模拟器,而不启动当前应用,这也是可以的,请看下图:

    启动模拟器

    也许相同的设备,但是却又多个尺寸,多个屏幕分辨率,例如:iPhone就有4、4S、5等。那怎么选择呢?别当心,有模拟器呢:

    选择不同的分辨率

    真是iOS模拟器在手,开发调试不用愁啊!

    4.1.2 模拟器自定义设置

    看完了上面的介绍,是不是感觉有一种马上动手的冲动?先别急,还有更高级的呢!大家知道,现在很多流行的iOS应用都有定位功能,那么在模拟器怎么测试定位呢?看看下图你就明白了:

    设置模拟器经纬度

    4.1.3 存储屏幕快照

    开发应用程序通常都不是一步到位的,过程中可能会产生各种各样稀奇古怪的现象,也许是显示不正常,也许是出现意外的效果,也或者你想把你当前的显示效果分享给开发团队的其他成员,这个时候作为开发者,你也许想要记录出现的这些现象,比如:截图、录屏什么的。这些都是不错的方法,但是iOS模拟器拥有更加方便的方式,如图所示:

    存储屏幕快照

    4.2 程序调试

    每一个开发者都不能保证他的程序是完美的,所以通常在我们运行程序的时候会出现很多奇怪的警告或者错误,有的可以一目了然,迎刃而解,有的却隐藏得很深,很难发现。这时候断点调试就直观重要了。

    在代码编辑器的左边的行号区,鼠标在这个区域单击可以在对应行上添加/关闭(不是删除)断点。启动断点,当再次运行程序的时候,程序若执行到当前行,则会暂停在当前行上,开发者可以在控制台看到断点处记录的信息。大致如图:

    断点调试

    如图所示,在断点处我们可以在控制台看到变量date的当前值以及内存地址等信息,这样就可以通过这些信息判断程序运行到该处时是否正常,也可以这样查看一些其他信息。

    4.3 NSLog

    有些时候我们可能会遇到一些仅靠断点无法解决的问题,这时我们还可以借助NSLog进行调试。NSLog也用于在控制台输出信息。如图:

    NSLog调试

    展开全文
  • 导读 目前移动端开发市场上引导开发者追求技多不压身,一个全栈开发者至少要懂后台服务器、数据库、Android、web、ios开发等。“一超多强”是指开发者先成为一门技术的专家然后掌握了解多门技术,这是一种好的发展...

    导读

           目前移动端开发市场上引导开发者追求技多不压身,一个全栈开发者至少要懂后台服务器、数据库、Android、web、ios开发等。“一超多强”是指开发者先成为一门技术的专家然后掌握了解多门技术,这是一种好的发展趋势,另外,这种技多不压身我认为当开发者更适合发展成为Leader管理岗位,随着年龄慢慢变大,成家立业后,基层单一码农已晋升之路受到阻碍了,作为项目经理或总监的时候,需要你能够“多才多艺”,才能管理好带领好你的团队。这一篇将掀起 IOS 开发之路,点关注不迷路。
     

    什么是iOS

    iOS是苹果公司为它的移动设备(iPhone、iPad、iWatch等)开发的移动操作系统

    iOS发展史

    • 2007年苹果发布iPhone Runs OS X
    • 2008年更名iPhone OS
    • 2010年更名iOS
    • 2012年WWCD 2012上发布iOS 6
    • 2013年WWCD 2013上发布iOS 7
    • 2014年WWCD 2014上发布iOS 8和Swift
    • 2015年WWCD 2015上发布iOS 9和Watch OS

    IOS开发语言

    ios目前流行两种开发语言:Objective-C 和 Swift 。前者有C语言基础者上手会容易些;后者Swift是iOS/Mac未来开发的主要语言,无论从编程思想还是从api书写,都赏心悦目,但缺点是没有Objective更稳定,且事实上去面试一些公司都要求的是用 Objective-C,只是把 Swift 作为学习语言。

    苹果设备屏幕尺寸

    设备屏幕尺寸分辨率坐标点
    iPhone 3和3s3.5英寸320*480320*480
    iPhone 4和4s(支持Retina)3.5英寸640*960320*480
    iPhone 5和5s(支持Retina)4英寸640*1136320*568
    iPhone 64.7英寸750*1334375*667
    iPhone 6 Plus5.5英寸1080*1920414*736
    iPad 1和2(不支持Retina)9.7768*1024768*1024
    iPad 3和4(支持Retina)9.71536*2048768*1024
    iPad Air9.71536*2048768*1024
    iPad Mini(不支持Retina)7.9768*1024768*1024
    iPad Mini2(支持Retina)7.91536*2048768*1024

    系统基础框架

     1、ios系统架构可以分为如图所示的四层,Cocoa Touch框架的地位不言而喻。 

    这里写图片描述
    • Core OS和Core Service提供了底层支持,包括文件访问、网络协议、低级数据类型等。
    • Media提供了基本绘图和音视频的支持,包括OpenGL、Quartz、Core Audio和Core Animation等。
    • Cocoa Touch包括了开发使用的大部分API,主要由Foundation(文件访问、网络操作、数据和容器类型)和UIKit(UI控件、控制器等)两个部分构成。在进行App开发时,应该由上到下使用这些技术层次,越上层的API封装得越好,开发越方便,但能自己发挥的东西越少。

    2、对比,android系统架构:

    Android其本质就是在标准的Linux系统上增加了Java虚拟机Dalvik,并在Dalvik虚拟机上搭建了一个JAVA的application framework,所有的应用程序都是基于JAVA的application framework之上。

    也分为四个层,从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和linux核心层。

    UIKit继承结构



      实现App开发中的用户界面首先要从UIResponder及其子类开始研究,当然整个过程会覆盖整个UIKit框架,比如UIColor(颜色)、UIEvent(事件)、UIFont(字体)、UIGestureRecognizer(手势识别)、UIImage(图像)、UIScreen(屏幕)等诸多内容。

    UIView和UIWindow

    1、UIWindow和UIView的继承关系

      UIWindow是UIView的子类。UIView定义了一个矩形区域以及操作这个矩形区域中内容的编程接口,除此之外UIView还要处理运行时区域中内容的交互行为(绘图、动画和事件处理)。从上面的图中我们也可以看出,我们要使用的控件都是UIView的子类型。视图会按层次结构排列,位于视图层次结构顶端的就是应用窗体。任何应用都有且仅有一个UIWindow对象,UIWindow对象就像一个容器,负责包含应用中的所有视图。应用需要在启动时创建并设置UIWindow对象,然后为其添加其他的视图,就像上面的代码呈现的那样。加入窗口的视图会成为该窗口的子视图。子视图也可以有自己的子视图从而构成一个以UIWindow作为根的视图层次结构(树形结构)。

    这里写图片描述

    2、UIView的基本属性和方法

    • frame属性:设置视图的坐标和尺寸
    • backgroundColor属性:设置视图的背景色
    • window属性:视图所在的窗口对象
    • -addSubview方法:添加子视图

    Xcode创建iOS项目

      启动Xcode在欢迎页中选择"Create a new Xcode project"。在项目创建向导中选择iOS->Application->Single View Application然后点击下一步。接下来需要设置项目名称、组织名称、组织标识、开发语言(OC或Swift)和设备(iPhone、iPad或Universal)。下一步之后选择项目的位置就可以点击"Create"完成项目创建了。参考我的下一个博文:IOS新手入门第一个HelloWorld项目

    熟悉开发工具Xcode

    这里写图片描述

    IDE布局说明:

    Xcode的上方是工具栏,有很多工具按钮。Xcode的左侧是导航区域,包括:项目导航、符号导航、查询导航、问题导航、测试导航、调试导航、断点导航、报告导航,可以使用Command+1-8的数字键在8种导航之间切换。Xcode的中间是编辑器区域;中间的下面是调试区域。Xcode的右侧上方是检查器(审查)区域;右侧下方是各种库的区域。

    Xcode常用功能和快捷键 (*实用)

    [plain] view plain copy
    1. Command+[ -> 代码块左移  
    2. Comamnd+] -> 代码块右移  
    3. Tab -> 接受代码自动完成提示  
    4. Esc -> 显示代码提示  
    5. Command+B -> 编译  
    6. Command+R -> 运行  
    7. Control+F -> 前移光标  
    8. Control+B -> 后移光标  
    9. Control+P -> 光标移到上一行  
    10. Control+N -> 光标移到下一行  
    11. Control+A -> 光标移到行首  
    12. Control+E -> 光标移到行尾  
    13. Control+T -> 交换光标左右字符  
    14. Control+D -> 删除光标右边的字符  
    15. Control+K -> 删除本行  
    16. Control+L -> 将光标所在位置置于窗口中央  
    17. 按住Option双击鼠标 -> 搜索文档  
    18. Command+Y -> 激活/禁用断电  
    19. Command+Control+Y -> 继续运行  
    20. F6 -> 单步跳过  
    21. F7 -> 单步跳入  
    22. F8 -> 跳出  

    AppDelegate与ViewController的作用与区别:

    AppDelegate是你整个应用的一个代理。当你应用启动的时候,最先被调用到的就是你AppDelegate中的- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法。你可以在这个方法中做些全局初始化。

    一般设计准则是尽量保持AppDelegate干净、简洁。

    AppDelegate中可以做应用退出后台或从后台返回到前台的一些处理。

    ViewController一般作为根视图控制器,把显示相关的都放到这里面去做。

    虚拟机HOME键:

    由于Xcode自带的虚拟机不像真机那样有一个可以用手指按的Home键回到主界面的实体按钮,所以需要用到快捷键:
    command + shift + h    (回到主界面)
    command + shift + hh  (可滑动清理应用)
    展开全文
  • 这个系列,我会选取实际面试过程中会问到的难点问题。几乎都是在面试大公司或者技术要求比较高的公司会问到的问题。希望会给即将找工作或者希望继续提升自己的小伙伴以帮助。
  • 以下都是自己在iOS开发的过程中遇到的问题,自己总结出来的小知识点。 1.UITableViewCell的contenView的superView在iOS8以上是UITableViewCell,在iOS8以下则不是。所以访问contentView的superView的时候需要注意...

    以下都是自己在iOS开发的过程中遇到的问题,自己总结出来的小知识点。


    1.UITableViewCell的contenView的superView在iOS8以上是UITableViewCell,在iOS8以下则不是。所以访问contentView的superView的时候需要注意区分iOS系统版本。


    2.程序中一个UITabBarController控制了四个UINavigationController,在某个页面上点击按钮要让tabbar选中某一个baritem,需要先设置tabbar的selectedIndex再将当前的nav popToRootViewController。顺序相反会导致tabbar隐藏。


    3.在某个界面上有个UITableView,需要在滑动的时候改变另外一个UIView,所以在代码中添加了如下代理方法:

    -(void)scrollViewDidScroll:(UIScrollView *)scrollView

    实现了需求。但是如果当UITableView正在滑动的时候pop了当前视图,程序会奔溃。

    原因:想已经释放的对象发送了消息。。。。

    就是在返回之后,当前视图对象释放了,但是又调用了委托方法。

    应该在dealloc方法中将UITableView的委托设置为nil,避免UITableView正在滑动的时候返回会奔溃。

    -(void)dealloc

    {

        tableView.delegate = nil;

        tableView.dataSource = nil;

    //这里要注意,如果项目使用了arc的话,不要调用super dealloc方法。

    }


    4.十进制数转十六进制数的命令:

    echo 'obase=16;1104129754’|bc   其中1104129754是十进制数

    这个在分享功能中添加URL Scheme的时候有需要。


    5.UITableViewCell自动布局,在cell的最下面自己用UILbel加一个横线。那么添加约束的时候,这个UILabel的宽度要添加跟self的宽度一样。因为如果cell设置了cell.accessoryType =UITableViewCellAccessoryDisclosureIndicator;并且添加UILabel的宽度跟self.contentView的宽度一样的话,就会出现这个UILabel的右边缘到cell上面的向右的箭头的位置就结束了。这说明contentView的右边界是到向右箭头的左边为止的。

    像这样的:



    6.在自动布局的UITableViewCell向下复现的时候(即UITableView向下滚动的时候,已经出现过的Cell重现出现。)带有一跳一跳的效果。检查发现是因为设置tableView.estimatedRowHeight = 40;导致的。因为我这里有两个高度不同的cell,一个高度是10(作为分隔线的),一个高度根据自适应计算的。如果设置了预估高度的话,高度本来应该为10的cell出现的时候会先设置为40然后又变为10,这就导致了跳动效果。

    因此,当UITableView有多个不同高度的UITableViewCell的时候,不应该设置UITableView的estimatedRowHeight属性来只设置一个预估高度值。否则会导致UITableView向下滑动,UITableViewCell复现的时候有一跳一跳的效果。

    不过可以通过委托方法- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath来设置不同样式的UITableViewCell的预估高度。


    7.自动布局中多行UILabel,需要设置其preferredMaxLayoutWidth属性才能正常显示多行内容。


    8.可以使用NSArray或者NSSet的

    - (void)makeObjectsPerformSelector:(SEL)aSelector;  

    - (void)makeObjectsPerformSelector:(SEL)aSelector withObject:(id)argument;  

    这两个相当于for循环的方法来依次让NSArray或者NSSet中的对象执行aSelector方法。


    9.给手势添加新的目标对象和方法:- (void)addTarget:(id)target action:(SEL)action

    在当前视图上面添加了一个自定义的菜单视图menu,menu上面添加了一个单击手势UITapGestureRecognizer(不是menu的公开属性)来展开和收起菜单,具体事件是写在menu里面的.

    现在当前视图上面有文本框,需求是在不改动menu的前提下,点击菜单的时候,释放键盘。

    想过给menu新添加一个UITapGestureRecognizer手势来解决这个问题,但是想想它既然已经有了一个单击手势,何必再新添加一个呢。经查阅文档,发现有这么个解决方案:

    NSArray *gestureArray = menu.gestureRecognizers;

        for(UIGestureRecognizer *gesturein gestureArray)

        {

            if([gestureisKindOfClass:[UITapGestureRecognizerclass]])

            {

                UITapGestureRecognizer *tapGesture = (UITapGestureRecognizer *)gesture;

                [tapGestureaddTarget:selfaction:@selector(menuTaped)];

                break;

            }

        }

    在当前视图中获取自己创建的这个menu上面添加的UITapGestureRecognizer手势,然后给它新增一个目标对象和方法,在方法中处理释放键盘的逻辑。


    10.

    设置导航的返回按钮标题  需求:只显示返回图标,不显示返回标题

    //!!!!:设置导航返回按钮文字的正确姿势!

        UIBarButtonItem *item = [[UIBarButtonItemalloc] initWithTitle:@""style:UIBarButtonItemStylePlaintarget:nilaction:nil];

        self.navigationItem.backBarButtonItem = item;


    网上有人说可以用下面的方法,但是实践发现下面这种方法在VC的标题很短的时候不会出现问题,一旦标题变长,这种方法会导致标题向右偏移,看起来很不好。。。。

    [[UIBarButtonItemappearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -60)

                                                                forBarMetrics:UIBarMetricsDefault];


    偏移效果图如下:



    11.页面下拉刷新箭头有时候在加载过程中push进新页面然后再返回的时候收不起来的问题

    self.edgesForExtendedLayout=UIRectEdgeNone;是因为self.view addSubView:添加的第一个子视图不是UIScrollView的子类,而没有设置这个导致的。

    12.在当前页面A中有一个UITextField文本框,并添加了UITextFieldTextDidChangeNotification通告,当文本框内容改变时进行动态搜索匹配,在收到通知之后改变这个文本框的内容。但是,如果现在push进来了一个新的带有文本框的页面B,当在B中文本框内输入内容之后再返回A,这时候发现A中的文本框的内容是B中文本框所填的内容。

    这是因为通告的问题,在监听通告的地方没有判断是不是当前A中的文本框触发的,只需在方法中判断一下即可。

    13.tabaritem的标题默认跟它对应的nav的rootviewcontroller的self.title是一样的。如果要tbbaritem的文字跟self.title不一样,可以在rootviewcontroller中设置self.naigationItem.title@“标题”;而不是直接用self.title属性。

    14.当给一个UIImageView添加固定宽高约束,但是当加载的网络图片比约束的宽高大很多的时候,显示的图片内容会撑出UIImageView的边界,设置了UIImageView的contentMode也不行。这个给UIImage添加一个Resize分类,并添加一个新的方法:

    -(instancetype)resizeToSize:(CGSize)size

    {

    UIGraphicsBeginImageContext(size);

    [selfdrawInRect:CGRectMake(0,0, size.width, size.height)];

    UIImage*newImage =UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    returnnewImage;

    }

    对UIImageView的imag进行重绘就不会出现这种情况了。

    15.在自定义单元格上面,左边一个UILabel右边对齐显示标题,右边一个UITextField供用户输入内容。给UILabel添加了固定宽度约束,给UITextFiled添加了边距约束。但是当UITextField中输入内容很长的时候会发现UITextFiled会把左边的UILabel挤压到左边(比如UILabel显示的文字是@“姓名”给它加的宽度约束是100,但是实际显示的时候会显示到单元格的最左边,只有刚刚好能显示全@“姓名”的宽度,剩下的单元格宽度都给了UItextFiled。)这种效果不是我们想要的效果,我们想要UILabel固定宽度。只需要将右边的UITextField也添加一个宽度约束即可,添加lessThanOrEqualTo(这里加上cell的宽度减去左边UILabel的宽度以及它们之间的间隔)这样当文本框输入内容很长的时候就不会挤压左边的UILabel了。



    展开全文
  • 以后的文章中,笔者会根据自己在开发中遇到的一些重点难点,进行简单的总结和梳理,并且不会过多的解释相关概念。 里面可能会设置到Objective-C或者swift相关的各种技术,虽然比较杂,所以需要有一定的开发或者...

     

    以后的文章中,笔者会根据自己在开发中遇到的一些重点难点,进行简单的总结和梳理,并且不会过多的解释相关概念。

    里面可能会设置到Objective-C或者swift相关的各种技术,虽然比较杂,所以需要有一定的开发或者相关基础,或者看起来比较杂,看的时候也可能会很乱的感觉,但是只要你能认真看完,相信您一定能发现意外的收获!

     

    好了,下面我们就开始干!

     

    OC2.0新特性:

    • Nullability:(为兼容swift中可选类型)
      • - (void)startWithCompletionBlock:(nullable void (^)(NSError * __nullable error))block;
      • nullable 可空 __nullable 不可空,当修饰的事变量的时候需要使用__
    • Lightweight Generics *:轻量级范性:
      • -(ObjectType)popObject;@interface 
      • Stack<objecttype: id> : NSObject</objecttype: id>
    • __kindof:返回值与强转:
    • - (__kindof UITableViewCell *)dequeueReusableCellWithIdentifier

     

    编程模式:

    面向对象编程OOP(最基本,最原始的编程模式)

    函数式编程(响应式)ReactiveCocoa(请查看相关文档)

    面向值的编程VOP

    向协议的编程POP

    面向协议(简单介绍):

    复制代码
     1 protocol ErrorPopoverRenderer {
     2 
     3     func presentError()
     4 
     5 } 
     6 
     7 extension ErrorPopoverRenderer where Self: UIViewController {
     8 
     9     func presentError() {
    10 
    11         //在这里加默认实现,并提供ErrorView的默认参数。
    12 
    13     }
    14 
    15 }
    复制代码

     

     

     

    关联对象:分类中增加属性

    头文件声明一个属性

     1 @property (nonatomic, copy) NSString *name; 

    实现文件

    导入<objc/message.h>

     定义一个静态变量

     1 static void *key = (void *)@“iCocos”; 

     

    重写getter方法

     1 return objc_getAssociatedObject(self, key) 

     

    重写setter方法

     1 objc_setAssociatedObject(self, key, name, OBJC_ASSOCIATION_COPY_NONATOMIC) 

     

    swift中的写法:

    直接在拓展中(swift中的分类就是拓展)

      

     

    循环引用

    • Blocks可以访问局部变量,但是不能修改
    • 如果修改局部变量,需要加__block 
    复制代码
    1  __block int multiplier = 7;
    2 
    3      int (^myBlock)(int) = ^(int num) {
    4 
    5          multiplier ++;//这样就可以了
    6 
    7          return num * multiplier;
    8 
    9      };
    复制代码

     

     

    __weak __typeof(&*self)weakSelf =self; 等同于__weak UIViewController *weakSelf =self;

    类似之前的__unsafe_unretain(MRC中)

    为什么不用__block 是因为通过引用来访问self的实例变量 ,self被retain,block也是一个强引用,引起循环引用,用__week是弱引用,当self释放时,weakSelf已经等于nil。

     

    注意点:

    weakSelf是为了block不持有self,避免循环引用,而再声明一个strongSelf是因为一旦进入block执行,就不允许self在这个执行过程中释放。block执行完后这个strongSelf会自动释放,没有循环引用问题

      

    1 __weak __typeof(self)weakSelf = self; 
    2 
    3 self.backgroundTaskIdentifier = [application beginBackgroundTaskWithExpirationHandler:^{ 
    4     __strong __typeof(weakSelf)strongSelf = weakSelf; 
    5 
    6 }];

     

    关于Block这里提醒一下,在使用block的时候除了要注意循环引用问题,还需要注意关于返回值和参数的传递!

     

    三种常见循环引用:

      

    一、parent-child相互持有、委托模式

    复制代码
    1 @interface FTAppCenterMainViewController ()
    2 
    3 {
    4 
    5 }
    6 
    7  @property(weak,nonatomic) UITableView* myTableView;
    8 
    9 @end
    复制代码

     

    这里面的myTableView就使用了weak修饰符。

      1 @property (nonatomic, weak) iddelegate; 2 3  

    【推荐方法】:

    child只有parent的对象为weak类型:

     1 @property (nonatomic, weak) iddelegate; 

     

    二、block

    看下面的代码:

    复制代码
    1 typedef void (^RequestNaviCallBack)(NSInteger naviCode,NSInteger httpCode,NSError * error);
    2 
    3 @interface FtNaviManager : NSObject
    4 
    5 {
    6 
    7 }
    8 
    9 @property (nonatomic, strong)   RequestNaviCallBack naviCallBack;
    复制代码

    这是一个请求导航的类,类属性持有了RequestNaviCallBack,这时,如果RequestNaviCallBack再持有self,必然造成循环引用。

    【推荐方法】:

    如果有循环引用,编译器会提示警告。

    如果对象没有持有Block对象,那么不会产生循环引用。如果对象持有了block对象,那么在block引用self的时候这么定义:

      1 __weak typeof(self) weakSelf = self;  

    三、NSTimer 

    复制代码
    @interface FtKeepAlive : NSObject
    
    {
    
        NSTimer*              _keepAliveTimer; // 发送心跳timer
    
    } 
    复制代码

    //实现文件

     1 _keepAliveTimer = [NSTimer scheduledTimerWithTimeInterval:_expired target:self selector:@selector(keepLiveStart) userInfo:nil repeats:YES];  

    类持有了_keepAliveTimer,_keepAliveTimer又持有了self,造成循环引用。

    【推荐方法】:

    NSTimer会持有对象,所以:在删除对象之前,需要将timer的invalidate方法。

      

    复制代码
    1 -(void)stopKeepAlive{
    2 
    3     [_keepAliveTimer invalidate];
    4 
    5     _keepAliveTimer = nil;
    6 
    7 }
    复制代码

     

    @dynamic

      

    转载于:https://www.cnblogs.com/stronger-ios-lcx/p/5635044.html

    展开全文
  • 百思不得姐Swift版总结(一)   最近在着手做一个关于新闻类的项目:百思不得姐 由于本人对swift有着独特的爱好,所以在OC写完之后空余的时间也在努力使用swift实现一下,但是中间遇到了不少的问题,就总结了几...

    百思不得姐Swift版总结(一)

     

    最近在着手做一个关于新闻类的项目:百思不得姐

    由于本人对swift有着独特的爱好,所以在OC写完之后空余的时间也在努力使用swift实现一下,但是中间遇到了不少的问题,就总结了几个重要的地方。

    这里只有三个比较麻烦的,后面文章中笔者会陆续更新相关技术总结

     


    swift中没有宏的概念,pch文件也没有OC中这么简单
    所以如果我们要定义一个全局变量,比如颜色,一般使用let直接定义
     
        /**
        *  颜色定义
        */
        let iCocosCommonBgColor = UIColor(red: (215)/255.0, green: (215)/255.0, blue: (215)/255.0, alpha: 1.0)

     

     

     
    使用字典的方法设置导航栏的主题
    在swift中设置导航栏的主题我们同样使用字典实现,但是却和OC大不一样,笔者也是弄了很久才成功,因为之前都只是简单的使用字典,下面就来看看咱们应该怎么做:

          
    复制代码
     1  //获取tabBarItem主题
     2         var tabBar : UITabBarItem = UITabBarItem.appearance()
     3         
     4         //设置文字不同状态的颜色
     5         let dictNor = NSDictionary(object: UIColor.grayColor(), forKey: NSForegroundColorAttributeName)
     6         let dictHigh = NSDictionary(object: UIColor.orangeColor(), forKey: NSForegroundColorAttributeName)
     7         
     8         //设置文字的大小
     9         let dictFont = NSDictionary(object: UIFont.systemFontOfSize(12.0), forKey: NSFontAttributeName)
    10         
    11         //使用上面的字典设置主题属性
    12         tabBar.setTitleTextAttributes(dictNor as [NSObject : AnyObject], forState: UIControlState.Normal)
    13         tabBar.setTitleTextAttributes(dictHigh as [NSObject : AnyObject], forState: UIControlState.Selected)
    14         
    15         tabBar.setTitleTextAttributes(dictFont as [NSObject : AnyObject], forState: UIControlState.Normal)
    复制代码

     

     

     
    实现每个子控制器左边返回按钮,还原手势返回功能
     
    1:首先遵守协议
    •     UIGestureRecognizerDelegate

    2:设置代理
           //设置手势代理
    •         self.interactivePopGestureRecognizer.delegate = self
    3:实现push方法
    复制代码
     1     //实现push方法,处理后面的业务逻辑
     2     override func pushViewController(viewController: UIViewController, animated: Bool) {
     3         
     4         //判断是否是根控制器
     5         if self.childViewControllers.count > 0 {
     6             
     7             //如果不是根控制器,则隐藏底部的tabBar
     8             viewController.hidesBottomBarWhenPushed = true
     9  
    10             /**
    11              * 创建一个按钮,并且设置对应的属性
    12              */
    13             
    14             //初始化
    15             var btn: UIButton = UIButton.buttonWithType(UIButtonType.Custom) as! UIButton
    16             
    17             //frame
    18             btn.frame = CGRectMake(0, 2, 70, 30)
    19             
    20             //设置位子及文字不同状态的颜色
    21             btn.setTitle("返回", forState: UIControlState.Normal)
    22             btn.setTitleColor(UIColor.grayColor(), forState: UIControlState.Normal)
    23             btn.setTitleColor(UIColor.redColor(), forState: UIControlState.Highlighted)
    24             
    25             //设置不同状态的图片
    26             btn.setImage(UIImage(named: "navigationButtonReturn"), forState: UIControlState.Normal)
    27             btn.setImage(UIImage(named: "navigationButtonReturnClick"), forState: UIControlState.Highlighted)
    28             
    29             //设置内容和图片的边距
    30             btn.contentEdgeInsets = UIEdgeInsetsMake(0, -15, 0, 0)
    31             btn.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 10)
    32             
    33             //设置每一个子控制器的左边为我们自定义的放回按钮
    34             viewController.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: btn)
    35             
    36             //添加点击事件
    37             btn.addTarget(self, action: "backClcik", forControlEvents: UIControlEvents.TouchUpInside)
    38         }
    39         
    40         //设置全局背景颜色
    41         viewController.view.backgroundColor = iCocosCommonBgColor
    42         
    43         //push进入下一个控制器
    44         super.pushViewController(viewController, animated: true)
    45     }
    复制代码

     

     
    4:实现返回按钮方法
        //点击放回按钮返回到上一个控制器
        func backClcik() {
            self.popViewControllerAnimated(true)
        }

    5:实现子控制器的手势返回
        //根据上面遵守的协议和设置的代理,在这个方法中设置子控制器可以实现点手势返回功能
        func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
            return self.childViewControllers.count > 0
        }
         }

     


     
    swift控制器切换
     
    关于控制器的切换swift喝Objective—C中并没有太多的区别(这里只说两种,其他的在下面的文章中会介绍到),最大的也就是布尔值的写法
    1. Objective—C:YES和NO
    2. swift:true和false
    下面来看看两者的实现
    OC版
    •     模态方式
        [self presentViewController:vc animated:YES completion:nil];
        [self dismissViewControllerAnimated:YES completion:nil];
    •     push方式
        [self.navigationController pushViewController:vc animated:YES];
        [self.navigationController popViewControllerAnimated:YES];

     

    Swift版
    •      模态方式
            self.presentViewController(vc, animated: true, completion: nil)
            self.dismissViewControllerAnimated(true, completion: nil)
    •   push方式
            self.navigationController?.pushViewController(vc, animated: true)
            self.navigationController?.popViewControllerAnimated(true)

     


     
     
     最后看看基本的界面实现

                              


           
     

    版权声明:欢迎转载,请贴上源地址: http://www.cnblogs.com/iCocos/(iOS梦工厂)

    更多精彩请关注github:https://github.com/al1020119?tab=repositories



     
     
    本博文由博主(iCocos)独立编写或者借鉴别人的好文章进行修改而成,如果不对的地方望指正,谢谢! 笔者所有相关博客已转至git博文:http://al1020119.github.io/此博文不会再更新,也很少会回复,如有疑问请联系我!Q Q:2211523682/790806573微信:18370997821/13148454507微博WB:http://weibo.com/u/3288975567?is_hot=1git博文:http://al1020119.github.io/github:https://github.com/al1020119
    展开全文
  • 一、创建一个OS X项目 第一个Swift程序: 1、创建步骤:启动Xcode->创建新Xcode项目(Create a new Xcode project)->选择“OS X/Application/Command Line Tool” ->输入项目名称等信息 ->...
  • 看什么看!点我呀!全栈程序员,免费入门到精通!作者丨开发之家https://www.jianshu.com/p/1fd231cfe54b前言iOS开发语言有哪些?OS开发...
  • ios开发知识汇总

    2018-06-11 09:30:10
    1.技术基础1、为什么说Objective-C是一门动态的语言?这里的动态和静态是相对的,动态的意思是不需要在编译时确定所有的东西,在运行时也可以动态添加变量,属性,方法和类. Objective-C 可以通过Runtime这个运行时机制,...
  • 作为iOS开发老司机们,我们肯定有各种各样的开发利器,以追求着最高效率。 此篇分享下我们常用的各种神兵利器。如果有朋友能推荐更好的欢迎补充,分享我!文章地址 Mac 常用的工具集 iTerm2 iTerm2 + Oh My Zsh 打造...
  • iOS开发流程

    2020-06-07 19:47:14
    此流程适用给对iOS开发啥都不清楚的小白 iOS开发首先需要申请苹果开发者帐号, 来上线项目, 可供用户在app store下载, 开发者帐号费用为人民币688元每年, 以下为流程. 1.申请公司邓白氏编码 【申请链接】: ...
  • 以下是 100offer 整理的关于 iOS 开发就业形势的报告,看完就你知道做 iOS 开发多有“钱”途了。在创业约等于做APP的互联网市场,几乎每一家...这也与100offer的拍卖经验吻合,iOS开发与Android开发、前端开发并列为...
  •  需要iOS视频资料可以加我微信: 1914532832 验证信息请注明:IOS开发  很多新人对IOS开发很迷茫,不知道从何下手?看完本系列,你将会觉得IOS入门其实很简单。要学习IOS开发,当然是先学习Swift语言,特别是小白...
  • 如果你对怎么开始IOS开发都不懂的话,请看点下面的链接,先学习关于IOS开发环境的配置以及Swift语言入门:  IOS开发入门之一——Swift语言基础  本章将教大家创建一个标准的苹果手机应用并让它在手机模拟器上运行...
  • 现在是人是鬼都想着做iOS开发,等你们都挤进来了这个供需平衡了甚至供过于求了,你们就是花那么多精力挤进了一个烧脑费神的普通行业,btw,现在北上广已经呈现出iOS开发近饱和状态果然那句话是真理,中国人总是能够...
  • iOS开发本身不难学,不需要你有很高的智力,只需要你能够坚持下去。只要你心中有信念,坚持下去就会有收获。不管你是学哪一种编程语言,不用怀疑你能不能学会,只要你肯下工夫,坚持下去就一定会成,学不会只有一个...
  • 如果你app都不懂得怎么创建,或者连怎么搭建IOS开发环境Swift语言都还不熟悉,请先看本系列的前两节: IOS开发入门之一——Swift语言基础 IOS开发入门之二——第一个App 需要iOS开发视频资料可以加我微信: ...
  • Demo源码:https://github.com/EmyWong/PersonalUITech前言作为一名iOS开发人员,我觉得第一步是能够基本模仿一个APP,完成别人APP的界面搭建;第二步,是尽量学会转载,学习别人的博客和技术;第三步,是学会原创,...
1 2 3 4 5 ... 20
收藏数 401,772
精华内容 160,708
关键字:

ios开发