NSData与NSMutableData

  • 代表数据缓存区,作用有两个①对数据读取NSData、②输出NSData的数据
    • 初始化方法(类方法以data开头,实例方法以init开头)
      • data::创建一个不包含任何数据的、空的NSData对象
      • dataWithBytes:length:/initWithBytesNoCopy:length::复制C数组所包含的数据类初始化NSData的数据
      • dataWithBytesNoCopy:length:/initWithBytesNoCopy:length::直接利用C数组所包含数据来初始化NSData对象。当该对象呗执行malloc方法销毁自己时,程序会释放该数组
      • dataWithBytesNoDopy:length:freeWhenDone:/initWithBytesNoCopy:length:freeWhenDone::直接利用C数组所包含的数据来初始化NSData对象。只有当最后一个参数为YES,且该对象被执行malloc方法销毁自己时,程序才会释放该C数组
      • dataWithContentsOfFile:/initWithContentsOfFile::直接读取文件内容,并利用文件内容来初始化NSData
      • dataWithContentOfURL:/initWithContentOfURL::直接读取URL关联的内容,并利用该URL关联的内容初始化NSData
      • dataWithData:/initWithData::直接使用另一个NSData所包含的数据来初始化先创建的NSData
    • 常用方法
      • bytes::获取该NSData所包含的数据
      • getBytes:length::获取NSData所包含的指定长度的数据
      • getBytes:range::获取NSData所包含的指定范围的数据
      • subdataWithRange::获取NSData所包含的指定范围的数据组成的NSData对象
      • writeToFile:atomically::将NSData的数据写入文件
      • writeToURL:atomically::将NSData的数据写入URL对应的资源

NSFileManager

  • NSFileManager代表文件管理器,可以执行文件的移动、复制、链接、删除文件或目录,同时提供一个配套的事件委托(NSFileManagerDelegate),确保文件操作后调用相对应的处理方法。文件名作为文件的唯一标识,可使用绝对路径或相对路径。
  • NSFileManager访问属性和内容提供如下方法:
方法名 说明
fileExistsAtPath: 判断指定文件名对应的文件是否存在
fileExistsAtPath:isDirectoy: 判断指定文件名对应的文件或者目录是否存在,最后一个参数可用于返回该文件名是否为目录
isReadableFileAtPath: 判断指定目录下的文件是否可读
isWritableFileAtPath: 判断指定目录下的文件是否可写
isExcutableFileAtPath: 判断指定目录下的文件是否可执行
isDeletableFileAtPath: 判断指定目录下的文件是否可删除
componentsToDisplayForPath: 获取指定文件名对应文件的各个路径组件
displayNameAtPath: 获取指定文件名对应文件的简单文件名
attributesOfItemAtPath:error: 获取指定文件名对应文件的属性
attributesOfFileSystemForPath:error: 获取指定文件名对应的文件所在文件系统的属性
setAttributes:ofItemAtPath:error: 设置指定文件名对应文件的属性
contentsAtPath: 获取指定文件名对应文件的内容
contentsEqualAtPath:andPath: 判断两个文件名指定的内容是否相同
  • NSFileManager为创建、删除、移动、复制文件或目录提供了如下方法
方法名 说明
createDirectoryAtURL:withIntermediateDirectories:attributes:error: 根据指定的URL创建目录
createDirectoryAtPath:withIntermediateDirectories:attributes:error: 根据指定的路径创建目录
createFileAtPath:contents:attributes: 根据指定的文件路径、内容创建文件
removeItemAtURL:error: 删除指定URL对应的文件
removeItemAtPath:error: 删除指定路径对应的文件
copyItemAtURL:toURL:error: 根据指定的URL复制文件或目录
copyItemAtPath:toPath:error: 根据指定的路径复制文件或目录
moveItemAtURL:toURL:error: 根据指定URL移动文件或目录
moveItemAtPath:toPath:error: 根据指定路径移动文件或目录
  • NSFileManager查看目录包含内容提供了如下方法
方法名 说明
contentsOfDirectoryAtPath:error:
enumeratorAtPath:
subpathsOf

NSURL

  • URL(Uniform Resource Locator)对象表示同意资源定位器,它是指向互联网“资源”的指针。通常情况下,URL由协议名、主机、端口和资源路径组成,格式如下:

    scheme://host:port/path

../cocos2d-x/tools/project-creator目录下的create_project.py
输入./create_project.py -project Name -package PackageName -language cpp命令,创建一个名为Name,包名为PackageName,编程语言为c++的一个工程。

环境配置

  • .bash_profile中加上以下几个路径:

    1
    2
    3
    4
    5
    6
    export COCOS2DX_ROOT=/Users/zhaitao/Documents/cocos2d-x-2.2.2
    export ANDROID_SDK_ROOT=/Users/zhaitao/Documents/Android/sdk
    export ANDROID_NDK_ROOT=/Users/zhaitao/Documents/Android/android-ndk-r9c
    export NDK_ROOT=/Users/zhaitao/Documents/Android/android-ndk-r9c
    export PATH=$PATH:$ANDROID_NDK_ROOT
    export PATH=$PATH:$ANDROID_SDK_ROOT
  • 修改build_native.sh文件

  1. 在路径/Users/user/Documents/cocos2d-x-2.2.2/samples/Cpp/TestCpp/proj.android下找到build_native.sh
  2. 在APPNAME=”TestCpp”下添加NDK_ROOT=”/Users/user/Documents/android-ndk-r9c”
  3. 命令行执行build_native.sh

  • 使用Quartz 2D绘图的关键步骤有两步:获取CGContextRef,调用CGContextRef的方法进行绘图。
  1. 自定义UIView获取CGContextRef

    1
    CGContextRef ctx = UIGraphicsGetCurrentContext();
  2. 创建位图获取CGContextRef

    1
    2
    3
    4
    // 创建内存中的图片
    UIGraphicsBeginImageContext(CGSizeMake(320,480));
    // 获取想内存中图片执行绘制的CGContextRef
    CGContextRef ctx = UIGraphicsGetCurrentContext();

Quart2D的绘图相关函数

函数签名 简要说明
void CGContextClearRect(CGContextRef c,CGRect rect) 擦除指定矩形区域上绘制的图形
void CGContextDrawPath(CGContextRef c,CGPathDrawingMode mode) 使用指定模式绘制当前CGContextRef中所包含的路径。第二个参数支持kCGPathFill、kCGPathEOFill、kCGPathStroke、kCGPathFillStroke、kCGPathEOFillStroke
void CGContextEOFillPath(CGContextRef c) 用奇偶规则来填充该路径包围的区域,奇偶规则指:如果某个点被路径包围了奇数次,系统绘制该点:如果被路径包围偶数次,系统不绘制该点
void CGContextFillPath(CGContextRef c) 填充该路径包围的区域
void CGContextFillPath(CGContextRef c,CGRect rect) 填充rect代表的矩形
void CGContextFillRects(CGContextRef c,const CGRect rects[],size_t_count) 填充多个矩形
void CGContextFillElipseInRect(CGContextRef context,CGRect rect) 填充rect矩形的内切椭圆
void CGContextStrokePath(CGContextRef c) 使用当前CGContextRef设置的线宽绘制路径
void CGContextStrokeRect(CGContextRef c,CGRect rect) 使用当前CGContextRef设置的线宽绘制矩型
void CGContextStrokeRectWillWidth(CGContextRef c,CGRect rect,CGFloat width) 使用指定线宽绘制矩形框
void CGContextReplacePathWillStrokePath(CGContextRef c) 使用绘制当前路径时覆盖的区域作为当前CGContextRef中的新路径
void CGContextStokrEllipseInRect(CGContextRef context,CGRect rect) 使用当前CGContextRef设置的线宽绘制rect矩形的内切椭圆
void CGContextStrokeLineSegments(CGContextRef c,const CGPoint points[],size_t count) 使用当前CGContextRef设置的线宽绘制多条线段,其中1、2点组成一个线段,3、4组成一条限度,以此类推

设置绘图属性的相关函数

函数签名 简要说明
void CGContextSavaGState(CGContextRef c); 保存CGContextRef当前的绘图状态,以便以后恢复该状态
void CGContextRestoreGState(CGContextRef c); 把CGContextRef的状态恢复到最近一次保存时的状态
CGInterpolationQuality CGContextGetInterpolationQuality(CGContextRef c); 获取当前CGContextRef在放大图片时差值质量
void CGContextSetInterpolationQuality(CGContextRef c,CGInterpolationQuality quality); 设置当前CGContextRef在放大图片时差值质量
void CGContextSetLineCap(CGContextRef c,CGLineCap cap); 设置线段端点的绘制形状,该属性支持如下三个值:kCGLineCapButt:该属性不会只端点,线条结尾处直接结束,此为默认值;kCGLineCapRound:该属性指定绘制原点端点,线条结尾处绘制一个直径为线条宽度的半圆;kCGLineCapSquare:该属性指定绘制方形端点。线条结尾处绘制半个边长为线条宽度的正方形。
void CGContextSetLineDash(CGContextRef c,CGFloat phase,const CGFloat lengths[],size_t count); 设置绘制边框时所用的点线模式
void CGContextSetLineJoin(CGContextRef c,CGLineJoin join); 设置线条连接点的风格支持以下三个值:kCGLineJoinMeter,kCGLineJoinRound,kCGLineJoinBevel
void CGContextSetLineWidth(CGContextRef c,CGFloat width); 设置绘制直线、边框时的线条宽度
void CGContextSetMiterLimit(CGContextRef c,CGFloat limit); 当把连接点风格设置为meter风格时,该方法用于控制锐角箭头的长度
void CGContextSetPatternPhase(CGContextRef c,CGSize phase); 设置该CGContextRef采用位图填充的相位
void CGContextSetFillPattern(CGContextRef c,CGPatternRef pattern,const CGFloat components[]); 设置该CGContextRef使用位图填充
void CGContextSetShouldAntialias(CGContextRef c,bool shouldAnitialias); 设置该CGContextRef是否应该抗锯齿
void CGContextSetStrokePattern(CGContextRef c,CGPatternRef pattern,const CGFloat components[]); 设置该CGContextRef使用位图绘制线条、边框
void CGContextSetBlendMode(CGContextRef context,CGBlendMode mode); 设置CGContextRef的叠加模式
void CGContextSetAllowsAntialiasing(CGContext context,bool allowsAntialiasing); 设置该CGContextRef是否允许抗锯齿
void CGContextSetAllowsFontSmoothing(CGContext context,bool allowsFontSmoothing); 设置该CGcontextRef是否允许光滑字体
void CGContextSetShouldSmoothFonts(CGContext c,bool shouldSmoothFonts); 设置该CGcontextRef是否允许光滑字体
void CGContextSetAlpha(CGContext c,CGFloat alpha); 设置全局透明度
void CGContextSetCMKYFillColor(CGContextRef c,CGFloat cyan,CGFloat magenta,CGFloat yellow,CGFloat black,CGFloat alpha); 使用CMYK颜色模式来设置该CGContextRef的填充颜色
void CGContextSetCMYKStrokeColor(CGContextRef c,CGFloat cyan,CGFloat magenta,CGFloat yellow,CGFloat black,CGFloat alpha) 使用CMYK颜色模式来设置该CGContextRef的线条颜色
void CGContextSetFillColorWithColor(CGContextRef c,CGColorRef color); 使用指定颜色来设置该CGContextRef的填充颜色
void CGContextSetStrokeColorWithColor(CGContextRef c,CGColorRef color); 使用指定颜色来设置该CGContextRef的线条颜色
void CGContextSetGrayFillColor(CGContextRef c,CGFloat gray,CGFloat alpha); 使用灰色来设置该CGContextRef的填充颜色
void CGContextSetGrayStrokeColor(CGContextRef c,CGFloat gray,CGFloat alpha); 使用灰色来设置该CGContextRef的线条颜色
void CGContextSetRGBFillColor(CGContextRef c,CGFloat red,CGFloat green,CGFloat blue,CGFloat alpha); 使用RGB颜色模式来设置该CGContextRef的填充颜色
void CGContextSetRGBStoreColor(CGContextRef c,CGFloat red,CGFloat green,CGFloat blue,CGFloat alpha); 使用GRB颜色模式来设置该CGContextRef的线条颜色
void CGContextSetShadow(CGContext context,CGSize offset,CGFloat blur); 设置阴影在X,Y方向上的偏移,以及模糊度(blur值越大,阴影越模糊),默认模糊颜色为RGBA(0,0,0,1/3.0)
void CGContextSetShadowWithColor(CGContextRef context,CGSize offset,CGFloat blur,CGColorRef color); 设置阴影在X、Y方向上的偏移,以及模糊度和阴影颜色

点线模式

  • Quartz 2D绘制线段或边框时,默认总是使用实线,使用点线进行绘制,可调用CGContextRefLineDash(CGContextRef c,CGFloat phase,const CGFloat lengths[],size_t count)进行设置。

绘制文本

  • CGContextRef为绘制文字提供了如下函数
    • CGAffineTransform CGContextGetTextMartix(CGContextRef c)::获取当前对文本执行变换的变换矩阵。
    • CGPoint CGContextGetTextPosition(CGContextRef c)::获取该CGContextRef中当前绘制文本的位置。
    • CGContextSelectFont(CGContextRef c,const char *name,CGFloat size,CGTextEncoding textEncoding)::设置该CGContextRef当前绘制文本的字体、字体大小。
    • void CGContextSetCharacterSpacing(CGContextRef c,CGFloat spacing)::设置该CGContextRef中绘制文本的字符间距。
    • void CGContextSetFont(CGContextRef c,CGFonRef font)::设置该CGContextRef中绘制文本的字体。
    • void CGContextSetFontSize(CGContextRef c,CGFloat size)::设置该CGContextRef中绘制文本的字体大小。
    • CGContextSetTextDrawingMode(CGContextRef c,CGTextDrawingMode mode)::设置该CGContextRef绘制文本的绘制模式。该函数支持kCGTextFill、kCGTextStroke、kCGTextFillStroke等绘制模式。
    • void CGContextSetTextMatrix(CGContextRef c,CGAffineTransform t)::设置对将要绘制的文本执行指定的变换。
    • void CGContextSetTextPosition(CGContextRef c,CGFloat x,CGFloat y)::设置CGContextRef的一个文本绘制位置。
    • void CGContextShowText(CGContextRef c,const char* string,size_t length)::控制CGContextRef在当前绘制点绘制指定文本。
    • void CGContextShowTextAtPoint(CGContextRef c,CGFloat x,CGFloat y,const char *string,size_t length)::控制CGContextRef在指定绘制点绘制文本。
  • 使用CGContextRef绘制文本的步骤:
  1. 获取绘图的CGContextRef
  2. 设置绘制文本的相关属性
  3. 如果只是绘制不需要进行变换的文本,直接调用NSString的drawAtPoint:withAttributes:、drawInAttrubutes:withFont:等方法绘制即可。如果需要绘制文本进行变换,则需要先调用CGContextSetTextMatrix()函数设置变换矩阵,再调用CGContextShowTextAtPoint()方法绘制文本。

使用路径

-绘制复杂的图形,需要使用路径

  • 创建路径的相关函数
    |函数签名|简要说明|
    |—|:—|
    |void CGContextBeginPath(CGContextRef c);|开始定义路径|
    |void CGContextClosePath(CGContextRef c);|关闭前面定义的路径|
    |void CGContextAddArc(CGContextRef c,CGFloat x,CGFloat y,CGFloat radius,CGFloat startAngle,CGFloat endAngle,int clockwise);|向CGContextRef的当前路径添加一段弧|
    |void CGContextAddArcToPoint(CGContextRef c,CGFloat x1,CGFloat y1,CGFloat x2,CGFloat y2,CGFloat radius);|向CGContextRef的当前路径添加一段贝塞尔曲线|
    |void CGContextAddCurveToPoint(CGContextRef c,CGFloat cp1x,CGFloat cp1y,CGFloat cp2x,CGFloat cp2y,CGFloat x,CGFloat y);|向CGContextRef的当前路径添加一段贝塞尔曲线|
    |void CGContextAddLines(CGContextRef c,const CGPoint points[],size_t count);|向CGContextRef的当前路径上添加多条线段。该方法需要传入N个CGPoint组成的数组,其中1、2点组成第一条线段,2、3点组成一条线段……|
    |void CGContextAddLineToPoint(CGContextRef c,CGFloat x,CGFloat y);|把CGContextRef的当前路径从当前结束点连接到x、y对应的点|
    |void CGContextAddQuadCurveToPoint(CGContextRef c,CGFloat cpx,CGFloat cpy,CGFloat x,CGFloat y);|向CGContextRef的当前路径从当前结束点连接到x、y对应的点|
    |void CGContextAddRect(CGContextRef c,CGRect rect);|向CGContextRef的当前路径添加一个矩形|
    |void CGContextAddRects(CGContextRef c,const CGRect rects[],size_t count);|向CGContextRef的当前路径添加多个矩形|
    |void CGContextMoveToPoint(CGContextRef c,CGFloat x,CGFloat y);|向CGContextRef的当前结束点移动到x、y对应的点|
    |void GCContextAddEllipseInRect(CGContextRef c,CGRect rect);|向CGContextRef的当前路径添加一个椭圆|
    |CGPathRef CGContextCopyPath(CGContextRef context);|复制当前CGContextRef包含的路径,该函数返回的CGPathRef代表当前CGContextRef包含的路径|
    |void CGContextAddPath(CGContextref context,CGPathRef path);|将已有的CGPathRef代表的路径添加到当前CGContextRef的路径中|
  • 获取CGContextRef所包含的路径信息的函数
    • bool CGContextIsPathEmpty(CGContextRef c)::该函数用于判断指定CGContextRef包含的路径是否为空。
    • CGPoint CGContextGetPathCurrentPoint(CGContextRef c)::该函数用于返回指定CGContextRef包含的路径的当前点。
    • CGRect CGContextGetPathBoundingBox(CGContextRef c)::该函数用于返回指定CGContextRef中能完整包围所有路径的最小矩形。
    • bool CGContextPathContainsPoint(CGContextRef context,CGPoint point,CGPathDrawingMode mode)::该函数判断指定CGContextRef包含的路径按指定绘制模式进行绘制时,是否需要绘制point点。
  • 使用路径绘制步骤
  1. 调用CGContextBeginPath()函数开始定义路径
  2. 添加子路径
  3. 调用CGContextClosePath()函数关闭路径
  4. 调用CGContextDrawPath()、CGContextEOFFillPath()、CGContextFillPath()、CGContextStrokePath()函数来填充路径或绘制路径边框。
    • CGContextDrawPath() 可以代替其他三个方法,它可以使用特定的模式绘制图形
      • kCGPathFill:指定填充路径
      • kCGPathEOFill:指定采用even-odd模式填充路径
      • kCGPathStroke:指定只绘制路径
      • kCGPathFillStroke:指定既绘制路径,也填充路径
      • kCGPathEOFillStroke:指定既绘制路径,也采用even-odd模式填充路径

Core Image滤镜

  • IOS5新增框架,可以对图像进行各种特效处理,包括进行色彩调节、降噪、扭曲等。
  • Core Image的三个核心API:
    • CIContext:处理的核心API,所有图片的处理都在它的管理下完成。
    • CIFilter:过滤器,所有的过滤器都由该CIFilter代表,在创建CIFilter时,需要传入不同的参数即可创建不同类型的过滤器。
    • CIImage:被处理的图片,可通过UIImage、图片文件或像素数据来创建CIImage。
  • 使用CoreImage的步骤
  1. 创建CIContext对象

    • 创建基于CPU的CIContext对象

      1
      ctx = [CIContext contextWithOptions:[NSDicationary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:kCIContextUseSoftwareRenderer]];
    • 创建基于GPU的CIContext对象

      1
      ctx = [CIContext contextWithOptions:nil]
    • 创建基于OpenGL优化CIContext对象,可获得实时性能

      1
      2
      EAGLContext * eaglctx = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
      ctx = [CIContext contextWithEAGLContext:eaglctx];
  2. 创建CIFilter过滤器,CIFilter提供了filterWithName:类方法来创建CIFilter对象。该方法需要传入过滤器的名字,根据不同名字创建不同的过滤器,可在在此处查看。

  3. 创建CIImage对象,该CIImage将要作为过滤器处理的源图片。
  4. 调用CIFilter的[filter setValue:behinImage for:@”inputImage”]方法为inputImage属性赋值,该属性用于指定该过滤器将要处理的源图片。
  5. 根据需要,为不同的过滤器设置不同的过滤参数。
  6. 调用CIFilter的outputImage属性获取该过滤器处理后的图片,程序返回的是CIImage对象。
  7. 调用CIContext的不同方法将CIImage转换成CGImageRef或将CImage绘制到指定区域中。

iOS应用状态

  • Not running(未运行):应用程序未启动或者应用被系统终止
  • Inactive(不活动):程序在前台运行,但不能接受事件处理。当应用从一个状态切换到另一个状态时,中途过渡会短暂停留在此状态。
  • Active(活动):程序在前台运行且能接收到事件,这是应用在前台运行时所处的正常状态。
  • Background(后台):应用处在后台运行,并且还在执行代码。大多数将要进入Suspended做状态的应用,会先短暂进入状态。如果一个应用要求启动时直接进入后台运行,这样应用会直接从Not running状态进入Background状态,中途不会经过Inactive状态。
  • Suspended(挂起):应用处在后台,并且没有执行任何代码。系统会自动将应用转入该状态,并且不会发出任何通知。当处在该状态时,应用依然驻留内存,但不执行任何程序代码。

    App Delegate对应的回调方法

  • application:willFinishLaunchingWithOptions:程序将要启动时自动调用该方法,该方法是应用程序启动时第一次执行自定义代码的机会。
  • application:didFinishLaunchingWithOptions:应用程序启动时自动调用该方法,开发者可以在该方法中执行初始化相关的代码。
  • applicationDidBecomeActive:应用在转入前台,并进入活动状态时回调该方法(当应用从启动到进入前台,或从后台转入前台都会调用该方法),可重写该方法执行最后的准备工作。
  • applicationWillResignActive:应用正要从前台运行状态离开时将会调用该方法。
  • applicationDidEnterBackground:应用在正处于Background状态,且随时可能进入Suspended状态时将会调用该方法。
  • applicationWillEnterForeground:应用正从后台转入前台运行状态,但暂时还没有到达Active状态时将会调用该方法。
  • applicationWillTerminate:该应用程序即将被终止时调用该方法,如果应用当前处在Suspended状态,此方法将不会被调用。

  • UITableView支持对表格行执行移动、删除和插入操作。
  • UITableView提供了editing属性来判断该表格控件是否处于编辑状态。可以使用setEdting:animated:方法切换表格的编辑状态。
  • UITableView提供了如下的方法来插入、删除和移动表格栏
    • -beginUpdates:在执行多个连续编辑之前,先调用该方法开始更新。
    • -endUpdates:在执行多个连续编辑之后,调用该方法提交更新。
    • -insertRowsAtIndexPaths:withRowAnimation:在一个或多个NSIndexPath处插入表格行。
    • -deleteRowsAtIndexPaths:withRowAnimation:删除一个或多个NSIndexPath处的表格行。
    • -moveRowAtIndex:toIndexPath:将指定NSIndexPath处的表格行移动到另一个NSIndexPath处。
    • -insertSections:withRowAnimation:在指定NSIndexPath所包含的一个或多个分区号对应的位置插入分区。
    • -deleteSections:withRowAnimation:删除指定NSIndexPath所包含的一个或多个分区对应的分区。
    • -moveSection:toSection:将指定区域移动到另一个位置。
  • 动态编辑表格,必须实现UITableView对应dataSource对象中的如下方法:
    • -tableView:canEditRowAtIndexPath:该方法的返回值决定指定NSIndexPath对应的表格行是否可编辑。
    • -tableView:commitEditingStyle:forRowAtIndexPath:该方法的返回值决定指定表格行编辑完成时激发。
    • -tableView:canMoveRowAtIndexPath:该方法的返回值决定指定的NSIndexPath对应的表格栏是否可移动。
    • -tableView:moveRowAtIndexPath:toIndexPath:该方法告诉该DataSource将指定的表格行移动到另一个位置。
  • UITableViewDelegate协议为编辑表格定义了如下方法:
    • -tableView:willBeginEditingRowAtIndexPath:开始编辑某个表格行时激发委托对象的该方法。
    • -tableView:didEndEditingRowAtIndexPath:当编辑完某个表格行是激发委托对象的该方法。
    • -tableView:editingStyleForRowAtIndexPath:该方法的返回值决定了该表格行的编辑状态。可以返回UITableViewCellEditingStyleNone、UITableViewCellEditingStyleDelete、UITableViewCellEditingStyleInsert这三个枚举值之一。
    • -tableView:titleForDeleteConfirmationButtonForRowAtIndexPath:该方法返回的NSString将会作为删除指定表格行时确定按钮的文本。
    • -tableView:shouldIndetWhileEditingRowAtIndexPath:该方法返回的BOOL值决定指定表格行处于编辑状态时,该表格行是否应该缩进。默认编辑状态都会缩进。
  • 多分区表格以及分区索引
    • UITableView生成表格控件包含更多的分区,需要为表格的dataSource对象实现更多的方法。
      • -numberOfSectionsInTableView:该方法的返回值决定表格包含多少个分区。
      • -sectionIndexTitlesForTableView:该方法的返回值用于在表格右边建立一列浮动的索引。
      • -tableView:titleForHeaderInSection:该方法的返回值决定指定分区的页眉。
      • -tableView:titleForFooterInSection:该方法的返回值决定分区的页脚。
  • 直接使用UITableViewController
    • 只显示一个表格的话,可以之间继承UITableViewController,其已经实现了UITableViewDataSource和UITableViewDelegate协议。

  • UITabBarController的基本概念
    • UITabBarController和UINavigationController一样是用来管理视图控制器的。
    • UINavigationController是用来管理视图之间的导航,UITabBarController是管理固定的几个视图控制器,子控制器是并列的。可以任意切换显示。
  • UITabBarController基本样式
  • UITabBarController初始化

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

    UIViewController *viewCtrl1 = [[UIViewController alloc] init];
    viewCtrl.title = @"主页";

    UIViewController *viewCtrl2 = [[UIViewController alloc] init];
    viewCtr2.title = @"消息";

    UIViewController *viewCtrl3 = [[UIViewController alloc] init];
    viewCtr3.title = @"搜索";

    UIViewController *viewCtrl4 = [[UIViewController alloc] init];
    viewCtr4.title = @"设置";

    NSArray *viewControllers = [NSArray arrayWitjObjects:viewCtr1,viewCtrl2,viewCtrl3,viewCtrl3,viewCtrl4,nil];
    UITabBarController *mainViewController = [[UITabBarController alloc] init];
    mainViewController.viewControllers = viewControllers;
    [self.window setRootViewController:mainViewController];
  • 示例代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    /* ... */
    /*
    * 1.创建若干个子视图控制器,它们是并列关系
    * 2.创建一个数组,将已创建的子视图控制器,添加到数组中
    * 3.创建UITabBarContrller实例
    * 4.tabBarController.viewContrllers = viewContollers;
    * 5.添加到window的rootViewController
    */
    UIViewController *vc1 = [[UIViewController alloc]init];
    vc1.title = @"首页";
    vc1.view.backgroundColor = [UIColor redColor];

    UIViewController *vc2 = [[UIViewController alloc]init];
    vc2.title = @"新闻";
    vc2.view.backgroundColor = [UIColor blueColor];

    UIViewController *vc3 = [[UIViewController alloc]init];
    vc3.title = @"历史";
    vc3.view.backgroundColor = [UIColor yellowColor];

    UIViewController *vc4 = [[UIViewController alloc]init];
    vc4.title = @"搜索";
    vc4.view.backgroundColor = [UIColor purpColor];

    UIViewController *vc5 = [[UIViewController alloc]init];
    vc5.title = @"设置";
    vc5.view.backgroundColor = [UIColor orangeColor];

    NSArray *viewControllers = @[vc1,vc2,vc3,vc4,vc5];
    UITabBarController tabBarController = [[UITabBarController alloc] init];
    [UITabBarController setViewContronllers:viewControllers animated:YES];
    self.window.rootViewController = tabBarController;
  • UITabBarController结构图

    • Tab控制器用数组管理视图,视图间是平级的。
  • TabBarController类图分析

    • 一个分栏视图控制器控制着若干视图控制器,由一个数组管理
    • 每个分栏控制器只有一个UITabBar视图,用于显示UITabItem实例
    • UITabBarItem由当前的视图控制器管理
  • UITabBarController系统样式
    +TabBar只能显示5个Tab Item,超过5个则会自动生成个More标签显示剩余的Tab,这些Tab可以通过编辑显示在UITabBar上。如果将视图添加到导航控制器中,默认出现编辑按钮,可以自由移动item实例。

实例代码

  • 创建系统自带的TabBarController
    1
    2
    3
    4
    5
    6
    7
    8
    TabBarViewController *tabBarController = [[UITabBarViewController alloc]init];
    FirstViewController *firstItem = [[FirstViewController alloc] init];
    UITabBarItem *firstItem = [[UITabBarItem alloc]initWithTabBarSystemItem:UITabBarSystemItemFavorites tag:1];
    firstViewController.tabBarItem = firstItem;
    // ......
    NSArray *viewControllers = @[firstItem,secondItem,thirdItem];
    [tabBarController setViewControllers:viewControllers animated:YES];
    self.window.rootViewController = tabBarController;

自定义UITabBarItem

  • 图片大小3030px(视网膜屏6060)
  • 图片需要使用淡灰色或者半透明效果,选择系统自动填充蓝色

    1
    2
    3
    FirstViewController *firstVC = [[FirstViewController alloc]init];
    UITabBarItem *firstItem = [[UITabBarItem alloc] initWithTitle:@"主页" image:[UIImage imageNamed:@"image.ong"]tag:1];
    firstVC.tabBarItem = firstItem;
  • UITabBarController代理方法

    1
    2
    3
    4
    5
    6
    7
    8
    -(BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
    {
    // 视图将被切换时调用,viewController为将被显示的控制器
    }
    - (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
    {
    // 视图已经被切换后调用,viewController为已经显示的控制器
    }

基层分栏控制器和导航控制器

  • 在Tab Bar控制器中某一个Tab中使用Navigation控制器。
  • 实现代码
    1
    2
    3
    4
    5
    6
    7
    8
    FirstViewController *firstVC = [[FirstViewController alloc] init];
    UINavigationController * fNav = [[UINavigation alloc] initWithRootViewController:firstVC];
    SecondViewController * secondVC = [[SecondViewController alloc] init];
    //......
    NSArray *viewControllers = [NSArray arrayWithObjects:firstVC,secondVC,nil];
    UITabBarController*tabController = [[UITabBarController alloc] init];
    tabController.viewControllers = viewControllers;
    self.window.rootViewController = tabController;

  • 设置背景需要通过类别修改drawRect方法。5.0以上SDK提供了设置背景图片的方法。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // 5.0之前,类别扩展给UINavagationBar设置图片背景
    @implementation UINavigationBar (CustomNavigationBar)
    - (void)drawRect:(CGRect)rect{
    UIImage * image = [UIImage imageNamed:@"image.png"];
    [image drawInRect:rect];
    }
    @end
    // 5.x新增了serBackgroundImage方法来设定图片背景
    UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:viewController];
    [navigation.navigationBar setBackgroundImage:[UIImage imageNamed:@"image.png"] forBarMetrics:UIBarMetricsDefault];
  • 小结

    • 一个UINavigationController对应一个NavigationBar实例
    • 一个UINavigationController可以包含多个UIViewController
    • 每一个UIViewController对应一个UINavigationItem实例
    • UINavagationItem控制多个UIBarButtonItem
    • 一个UINavigationController控制着一个UIToolBar实例
    • UIToolBar中的UIBarButtonItem由当前的视图控制器管理,而不是由导航控制器控制

UIProgressView

  • 属性
    • Style
      • Default:默认风格
      • Bar:工具条风格
        +Progress
      • 设置0.0~1.0之间的浮点值,1.0代表全部完成。
        +Progress Tint
      • 已完成进度的颜色
    • Track Tink
      • 设置进度条轨迹颜色。
      • progressImage:设置该进度条完成部分的图片
      • tracjImage:设置进度条的轨道图片
  • ImageView图像拉伸
    • 默认情况下,iOS将会对该图像整体缩放,从而让图片被拉伸、变形。
      +为了精确地控制只对制定区域进行缩放,可通过uIImage来创建“可拉伸”图片。当通过一个UIEdgeInsets结构体(包括left、top、right、bottom)定义图片的拉伸区域。

  • 在NDk的目录下有一个例子\android-ndk\samples\hello-jni
  1. 将它导入到eclipse开发环境中(最好选择cpoy到自己的工作空间)
  2. 在命令行进入该项目的路径,执行ndk-build命令,编译程序
  3. 在eclipse上试运行(注:在4.x的版本要将Dependencies包去掉,貌似这个包是做低版本支持的,在高版本中会出错)
  4. 运行成功

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//hello-jni.c
# include <string.h>
# include <jni.h>
// <jni.h>用于java的调用
jstring
// 名字即包名加函数名
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz )
{
# if defined(__arm__)
# if defined(__ARM_ARCH_7A__)
# if defined(__ARM_NEON__)
# define ABI "armeabi-v7a/NEON"
# else
# define ABI "armeabi-v7a"
# endif
# else
# define ABI "armeabi"
# endif
# elif defined(__i386__)
# define ABI "x86"
# elif defined(__mips__)
# define ABI "mips"
# else
# define ABI "unknown"
# endif
// env为java与C交互的结构,返回UTF编码的字符串
return (*env)->NewStringUTF(env, "Hello from JNI ! Compiled with ABI " ABI ".");
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class HelloJni extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
tv.setText(stringFromJNI() );
setContentView(tv);
}
// 声明一个native方法,即.c的函数
public native String stringFromJNI();
public native String unimplementedStringFromJNI();
static {
System.loadLibrary("hello-jni");
}
}

在adb shell中运行c程序

  • \android-ndk\samples\test-libstdc++下有这样一个例子,我们进行修改后然后在设备上运行它。
  1. 将jni目录下的test-libstl.cpp的文件进行修改
1
2
3
4
5
6
7
8
# include <cerrno>
# include <cstddef>
# include <stdio.h>
int main(void)
{
printf("Zoe\n");
return 0;
}
  1. 在命令行下使用ndk-build编译该项目
  2. 将项目目录下的\libs\armeabi\test-libstl文件拷贝到设备的/data/data目录下(你需要该目录的写权限)
  3. 进入设备的shell,并获取权限
  4. 切换到/data/data目录,修改test-libstl文件的权限,并执行它

编写自己的程序

  1. 在任意目录下,创建jni文件夹
  2. 创建一个你的程序,如:MyDemo.c

    1
    2
    3
    4
    5
    6
    7
    # include <stdio.h>
    void main()
    {
    int a,b,c;
    scanf("%d %d %d",&a,&b,&c);
    printf("%d+%d+%d=%d\n",a,b,c,a+b+c);
    }
  3. 创建Android.mk文件,注意LOCAL_MODULELOCAL_SRC_FILES属性

    1
    2
    3
    4
    5
    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    LOCAL_MODULE := MyDemo
    LOCAL_SRC_FILES := MyDemo.c
    include $(BUILD_EXECUTABLE)
  4. 按上一个例子编译、拷贝、执行

  • 继承了UIScrollView:UIView控件,默认带有滚动条
  • UITextView与UITextField的区别
    • UITextView是一个多行文本框,UITextField只是单行文本
    • UITextView没有继承UIControl控件
    • UITextView继承了UIScrollView,所以它具有UISrollView的功能和行为。

      UIScrollView支持的属性

  • 控制显示区域的属性
    • contentSize:该属性是一个CGSize类型的值,制定显示内容的完整宽度和完整高度。
    • contentInset:该属性是一个UIEdgeInsets类型的值,表示所需要内容在上下左右的留白。
    • contentOffset:该属性是一个CGPoint值,表示可视区域在显示内容上滚动的距离。
  • 属性设置
    1.Scrollers
    • Shows Horizontal Scrllers:当用户水平滚动该控件时,该控件会显示水平滚动条。
    • Shows Vertical Scrollers: 当用户垂直滚动该控件时,该控件会显示垂直滚动条。
    • Scrolling Enabled:控件能否滚动。
    • Paging Enabled:是否分页。
    • Direction Lock Enabled:第一次滚动后,不允许向其他方向滚动。
  1. Bounce
    • Bounce :弹回效果。
    • Bounce Horizontally:水平弹回效果。
    • Bounce Vertically:垂直弹回效果。
  2. Zoom
    • Min 最小的可缩放比例。
    • Max 最大的可缩放比例。
  3. Touch
    • Bounces Zoom:内容缩放是否有弹性。
    • Delays Content Touches:真正确定滚动意图才去处理触碰手势。
    • Cancellable Content Touches:勾选后,如果该UIScrollView中的内容已经跟踪用户手势触碰动作的情况下,且用户拖动手指足以启动一个滚动事件,该UISrollView控件会调用touchesCancelled:withEvent:方法,并将该手指拖动事件当成滚动该UISroll控件。如果不勾选,UIScrollView控件已经跟踪某个手指动作,将不会理会其他的手指动作。
  • 使用委托对象处理UITextView事件
    • 委托对象必须实现UITextViewDelegate协议,协议定义了如下方法。
    1. -textViewShouldBeginEdting:将要开始编辑内容时回调。
    2. -textViewDidBeginEdting:开始编辑内容时回调。
    3. -textViewShouldEndEdting:将要结束时回调。
    4. -textViewDidEndEdting:结束编辑时回调。
    5. -textView:shouldChangeTextInRange:replacementText:指定范围内的文本内容将要被替换是回调。
    6. -textViewDidChange:文本内容发生改变时回调。
    7. -textViewDidChangeSelection:文本内某些文本改变时回调。
  • 实例