ps尺寸 swift_swift 刻度尺寸 - CSDN
  • Swift语言IOS8开发战记27 Sketch初探

    千次阅读 2015-06-19 17:45:52
    在之前我们新建了一个计算器项目,现在我...相对于PS这样的软件,Sketch简直就是为移动平台量身定做的。 打开Sketch,然后在右侧选择新建一个DeskTop HD,主页面有点像我们的Xcode,中间是画布,右侧是检查器。 可以

    在之前我们新建了一个计算器项目,现在我想要给这个计算器项目制作一个桌面图标,可以使用Sketch,这是一款非常棒的软件。要想详细地学习这个软件请访问“Sketch中国”,里面有很多专业的Demo和教材。

    相对于PS这样的软件,Sketch简直就是为移动平台量身定做的。

    打开Sketch,然后在右侧选择新建一个DeskTop HD,主页面有点像我们的Xcode,中间是画布,右侧是检查器。

    可以使用快捷键A建立画板,你可以把画板当做图层的顶层,在上面自由发挥。然后我们使用U新建一个圆角矩形的底板。底板也可以使用辅助线对齐,或者直接使用快捷键对齐:


    尺寸设为800*800,修改这里的Radius为200,现在画板上的图像为:


    检查器界面分为几部分,最上面是通用属性,比如位置、尺寸、透明度、圆角等等。


    然后是边框和填充属性:



    然后选个背景色,这里我们使用渐变色,也就是框中的模式,你也可以选择第一个模式:纯色模式。此外还有径向、环形和图案、杂色,看个人喜好了。


    编辑完之后按ESC就可以退出编辑模式。然后复制一个刚才的圆角矩阵,修改尺寸和背景放到底板中间:


    现在时这个样子:


    然后可以修改这个小号圆角矩形的阴影:


    接下来用两条线分割这个小圆角矩阵,使用快捷键L,注意保持横平竖直:


    在检查器中把这两条线加粗一下,Thickness。在画布上不好选中的话在左侧的导航栏中选中也是可以的,跟Xcode中的文本大纲是一样的。


    修改线条颜色为接近底板的颜色现在的样式如下:


    然后快捷键T生成文本,修改文字大小,最后修改颜色,成品如下:



    最后来点击右上角的export导出并保存成png就好了,将图标名称保存为icon.png,保存到工程中就会自动添加为图标了。以后自己编了个什么APP自己动手也可以配上一个炫酷的桌面图标了。



    展开全文
  • swift 根据文字自动计算Label大小

    千次阅读 2017-07-17 15:28:08
    //方法 func textSize(text : String , font : UIFont , maxSize : CGSize) -> CGSize{ return text.boundingRect(with: maxSize, options: [.usesLineFragmentOrigin], attributes: [NSFontAttributeName : f
    //方法
    func textSize(text : String , font : UIFont , maxSize : CGSize) -> CGSize{
            return text.boundingRect(with: maxSize, options: [.usesLineFragmentOrigin], attributes: [NSFontAttributeName : font], context: nil).size
        }
    
    let textFont = UIFont.systemFont(ofSize: 14)
    let textString = "儿子中考考试考差了,被老婆骂了一顿。
      我去安慰儿子:“你要努力学习,以后一定要超越爸爸。”
      儿子愣了一下,弱弱来了一句:“别的我不敢保证。但是,以后找个比你好的老婆还是很有把握的。”‍‍‍‍ "
    let textMaxSize = CGSize(width: 240, height: CGFloat(MAXFLOAT))
    let textLabelSize = self.textSize(text:textString , font: self.textFont, maxSize: textMaxSize)    //获得根据文字计算的到的Size
    

    OC 写法

    -(CGSize)getLabelSiex:(NSString *)text font:(UIFont *)font maxSize:(CGSize)maxSize{
        
        CGSize size = [text boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:font} context:nil].size;
        
        return size;
    }

    ps.label一定设置为自动换行 (labe.numberOfLines = 0)才能生效;


    展开全文
  • 升级xcode8,swift3的注意点和变化

    千次阅读 2016-09-28 23:39:33
    过去每一版的Xcode 都和固定版本的Swift编程语言绑定在一起, Xcode 8中将不再如此,Swift 3给 Swift编程语言带来大量的语法变化,这些改变会让基于以前Swift版本的程序编译失败。 Xcode 8 中新创建的项目默认地使用...


    1. Swift 2 and 3


    过去每一版的Xcode 都和固定版本的Swift编程语言绑定在一起, Xcode 8中将不再如此,Swift 3给 Swift编程语言带来大量的语法变化,这些改变会让基于以前Swift版本的程序编译失败。

    Xcode 8 中新创建的项目默认地使用Swift 3, 幸运地Xcode 8 在编译设置中支持开发者明确地选择Swift 2或Swift 2.3 进行编译。


    支持Swift语言以往版本

    这就是说你可以选择适合的时候迁移项目到Swift 3, 如果一个目标(Target)需要支持Swift 2.3, 需要在目标(Target)的编译设置里把Use Legacy Swift Language Version 设置成Yes。

    Xcode 8 也提供了迁移工具帮你把项目升级到Swift 3, 不过Xcode提供的迁移工具让人喜忧参半,这次Swift 3 升级比上次升级有太多的变化,希望Xcode 8 的迁移工具会有所改善吧。

    2. 源码编辑器扩展


    Xcode 8 最让人惊喜的是支持源码编辑器第三方扩展,开发者对于本地插件系统已经翘首企盼了很多年,源码编辑器扩展算是沿着插件系统方向迈出坚实的第一步吧。

    源码编辑器扩展很类似于Xcode的扩展,但苹果一再强调当前的扩展专注于源码的操作和导航,也就是为什么会叫做源码编辑器扩展,Xcode 8 甚至提供了编辑器扩展模板让你快速上手。


    Xcode 源码编辑器扩展模板

    对于当前扩展架构中我最喜欢的一点就是每个扩展都运行在不同的进程中,这就意味着扩展的异常崩溃不会引起Xcode的意外终止,随着本地插件的越来越多,特别是苹果发布了新版的Xcode, 分进程运行的优势会显得越来越突出。

    扩展对比插件另一个优点是安全,你可以通过开发账号登录和发布扩展程序,苹果也提到开发者可以通过Mac 应用商店销售扩展,对于想通过销售扩展赚钱的开发者来说是很不错机会。

    我对于源码编辑器扩展是非常兴奋的,虽然我是 Alcatraz 的粉丝,但苹果的本地扩展更贴近于未来正确的方向。非常期待开发者们未来会提供什么样的扩展,其实已经有人在GitHub 上发布了插件。

    3. 调试


    即使最好的开发者每天都要花费大量的时间进行调试程序,懂你的苹果提供了更好的工具让调试更简单,Xcode 8中针对调试做了不少显著的优化。

    界面调试

    Xcode 8中的界面调试非常强大,界面调试可以展示运行时(runtime)问题,改善后的界面调试对于调试不清晰或者不满意的布局变得更加简单。

    运行时问题?没错,Xcode 8中除了编译时问题还提供了运行时问题,如果在运行时遇到自动布局的问题,Xcode会在左面导航面板把这些问题展示为运行时问题,这将会是个非常受欢迎的功能。


    运行时问题

    内存调试

    Xcode 8 的内存调试功能针对查找内存泄漏和循环引用的问题也做了显著优化,我还不太确定在实际项目中效果如果,但看起来很棒。

    内存调试

    4. 代码签名


    代码签名对于那些对苹果平台有兴趣开发者来说是非常不幸的,但幸运的是苹果没有做把头埋在沙子里的鸵鸟,苹果看到了开发者们遇到的问题并尝试解决,一些经验非常丰富的开发者也会不时遇到签名的问题,在今年的 Platforms State of the Union视频中, 苹果甚至自嘲自己的 修复问题(Fix Issue) 按钮,不仅很少时候能修复真正的问题,有时候会把问题弄得更糟。

    修复问题(Fix Issue) 按钮通常不能修复问题

    代码签名问题在Xcode 8 中将成为过去式,对于每一个目标(Target), 你可以勾选复选框让Xcode帮你管理代码签名,这个选项对于新项目默认是勾选的。在勾选的情况下,Xcode帮你管理证书,配置文件 和 应用标示等。

    Code Signing Done for You

    希望苹果这次能解决签名问题,数以万记的开发者们和我一起祈祷吧。

    5. 其他改善和增强


    San Francisco Mono字体

    如果你非常享受使用精雕细琢的软件,你应该会很喜欢Xcode 8中的San Francisco Mono 字体,请参看下图:

    San Francisco Mono

    高亮当前行

    你有没有注意到上面截图中的当前行被标示为高亮? 这是Xcode8中另一个受欢迎的功能,当前我在Xcode 7 中使用 Backlight for Xcode 实现类似功能,在Xcode 8 中将不再需要这个插件了。

    图片代码自动完成

    说到一些将被废弃的插件, 目前我在使用 Kent Sutherland开发的插件 KSImageNamed 能够在Xcode中帮助图片代码自动完成, 在Xcode 8 我将不需要这个插件,因为这个功能已经内置在Xcode 8 中。

    图片自动完成

    6. 文档


    相信每个开发者都会在浏览和阅读文档上会花费很多时间,好的文档对于开发者有很大帮助,其实苹果的文档是非常优秀的,但提供的浏览方式却没有那么友好。

    这个问题在 Xcode 8 将会被解决,新的文档格式看起来漂亮极了,且文档浏览会变得简单和快捷。苹果也针对内存问题做了相关优化,新版的内存占用会少很多。

    下面是两张关于文档的截图,是不是极有设计感?

    新文档浏览器图1

    新文档浏览器图2


    Xcode 8 的 6 大新功能一览

    原文链接 作者:豆照建(译)

    在2016 苹果全球开发者大会(WWDC)期间, 苹果一如既往地给开发者们披露了新版的集成开发工具 – Xcode, 在过去的每一次大版本发布中,苹果都会积极地改进开发工具,添加一些极具吸引力的新功能,今年也不例外。

    1. Swift 2 and 3


    过去每一版的Xcode 都和固定版本的Swift编程语言绑定在一起, Xcode 8中将不再如此,Swift 3给 Swift编程语言带来大量的语法变化,这些改变会让基于以前Swift版本的程序编译失败。

    Xcode 8 中新创建的项目默认地使用Swift 3, 幸运地Xcode 8 在编译设置中支持开发者明确地选择Swift 2或Swift 2.3 进行编译。


    支持Swift语言以往版本

    这就是说你可以选择适合的时候迁移项目到Swift 3, 如果一个目标(Target)需要支持Swift 2.3, 需要在目标(Target)的编译设置里把Use Legacy Swift Language Version 设置成Yes。

    Xcode 8 也提供了迁移工具帮你把项目升级到Swift 3, 不过Xcode提供的迁移工具让人喜忧参半,这次Swift 3 升级比上次升级有太多的变化,希望Xcode 8 的迁移工具会有所改善吧。

    2. 源码编辑器扩展


    Xcode 8 最让人惊喜的是支持源码编辑器第三方扩展,开发者对于本地插件系统已经翘首企盼了很多年,源码编辑器扩展算是沿着插件系统方向迈出坚实的第一步吧。

    源码编辑器扩展很类似于Xcode的扩展,但苹果一再强调当前的扩展专注于源码的操作和导航,也就是为什么会叫做源码编辑器扩展,Xcode 8 甚至提供了编辑器扩展模板让你快速上手。


    Xcode 源码编辑器扩展模板

    对于当前扩展架构中我最喜欢的一点就是每个扩展都运行在不同的进程中,这就意味着扩展的异常崩溃不会引起Xcode的意外终止,随着本地插件的越来越多,特别是苹果发布了新版的Xcode, 分进程运行的优势会显得越来越突出。

    扩展对比插件另一个优点是安全,你可以通过开发账号登录和发布扩展程序,苹果也提到开发者可以通过Mac 应用商店销售扩展,对于想通过销售扩展赚钱的开发者来说是很不错机会。

    我对于源码编辑器扩展是非常兴奋的,虽然我是 Alcatraz 的粉丝,但苹果的本地扩展更贴近于未来正确的方向。非常期待开发者们未来会提供什么样的扩展,其实已经有人在GitHub 上发布了插件。

    3. 调试


    即使最好的开发者每天都要花费大量的时间进行调试程序,懂你的苹果提供了更好的工具让调试更简单,Xcode 8中针对调试做了不少显著的优化。

    界面调试

    Xcode 8中的界面调试非常强大,界面调试可以展示运行时(runtime)问题,改善后的界面调试对于调试不清晰或者不满意的布局变得更加简单。

    运行时问题?没错,Xcode 8中除了编译时问题还提供了运行时问题,如果在运行时遇到自动布局的问题,Xcode会在左面导航面板把这些问题展示为运行时问题,这将会是个非常受欢迎的功能。


    运行时问题

    内存调试

    Xcode 8 的内存调试功能针对查找内存泄漏和循环引用的问题也做了显著优化,我还不太确定在实际项目中效果如果,但看起来很棒。

    内存调试

    4. 代码签名


    代码签名对于那些对苹果平台有兴趣开发者来说是非常不幸的,但幸运的是苹果没有做把头埋在沙子里的鸵鸟,苹果看到了开发者们遇到的问题并尝试解决,一些经验非常丰富的开发者也会不时遇到签名的问题,在今年的 Platforms State of the Union视频中, 苹果甚至自嘲自己的 修复问题(Fix Issue) 按钮,不仅很少时候能修复真正的问题,有时候会把问题弄得更糟。

    修复问题(Fix Issue) 按钮通常不能修复问题

    代码签名问题在Xcode 8 中将成为过去式,对于每一个目标(Target), 你可以勾选复选框让Xcode帮你管理代码签名,这个选项对于新项目默认是勾选的。在勾选的情况下,Xcode帮你管理证书,配置文件 和 应用标示等。

    Code Signing Done for You

    希望苹果这次能解决签名问题,数以万记的开发者们和我一起祈祷吧。

    5. 其他改善和增强


    San Francisco Mono字体

    如果你非常享受使用精雕细琢的软件,你应该会很喜欢Xcode 8中的San Francisco Mono 字体,请参看下图:

    San Francisco Mono

    高亮当前行

    你有没有注意到上面截图中的当前行被标示为高亮? 这是Xcode8中另一个受欢迎的功能,当前我在Xcode 7 中使用 Backlight for Xcode 实现类似功能,在Xcode 8 中将不再需要这个插件了。

    图片代码自动完成

    说到一些将被废弃的插件, 目前我在使用 Kent Sutherland开发的插件 KSImageNamed 能够在Xcode中帮助图片代码自动完成, 在Xcode 8 我将不需要这个插件,因为这个功能已经内置在Xcode 8 中。

    图片自动完成

    6. 文档


    相信每个开发者都会在浏览和阅读文档上会花费很多时间,好的文档对于开发者有很大帮助,其实苹果的文档是非常优秀的,但提供的浏览方式却没有那么友好。

    这个问题在 Xcode 8 将会被解决,新的文档格式看起来漂亮极了,且文档浏览会变得简单和快捷。苹果也针对内存问题做了相关优化,新版的内存占用会少很多。

    下面是两张关于文档的截图,是不是极有设计感?

    新文档浏览器图1

    新文档浏览器图2

    Notification(通知)

    自从Notification被引入之后,苹果就不断的更新优化,但这些更新优化只是小打小闹,直至现在iOS 10开始真正的进行大改重构,这让开发者也体会到UserNotifications的易用,功能也变得非常强大。

    • iOS 9 以前的通知

    1.在调用方法时,有些方法让人很难区分,容易写错方法,这让开发者有时候很苦恼。

    2.应用在运行时和非运行时捕获通知的路径还不一致。

    3.应用在前台时,是无法直接显示远程通知,还需要进一步处理。

    4.已经发出的通知是不能更新的,内容发出时是不能改变的,并且只有简单文本展示方式,扩展性根本不是很好。

    • iOS 10 开始的通知

    1.所有相关通知被统一到了UserNotifications.framework框架中。

    2.增加了撤销、更新、中途还可以修改通知的内容。

    3.通知不在是简单的文本了,可以加入视频、图片,自定义通知的展示等等。

    4.iOS 10相对之前的通知来说更加好用易于管理,并且进行了大规模优化,对于开发者来说是一件好事。

    5.iOS 10开始对于权限问题进行了优化,申请权限就比较简单了(本地与远程通知集成在一个方法中)。

    ATS的问题

    iOS 9中默认非HTTS的网络是被禁止的,当然我们也可以把NSAllowsArbitraryLoads设置为YES禁用ATS。不过iOS 10从2017年1月1日起苹果不允许我们通过这个方法跳过ATS,也就是说强制我们用HTTPS,如果不这样的话提交App可能会被拒绝。但是我们可以通过NSExceptionDomains来针对特定的域名开放HTTP可以容易通过审核。

    NSExceptionDomains方式 设置域。可以简单理解成,把不支持https协议的接口设置成http的接口。

    具体方法:

    1.在项目的info.plist中添加一个Key:App Transport Security Settings,类型为字典类型。

    2.然后给它添加一个Exception Domains,类型为字典类型;

    3.把需要的支持的域添加給Exception Domains。其中域作为Key,类型为字典类型。

    4.每个域下面需要设置3个属性:

    NSIncludesSubdomains
    NSExceptionRequiresForwardSecrecy
    NSExceptionAllowsInsecureHTTPLoads

    细节提示:在iOS9以后的系统中如果使用到网络图片,也要注意网络图片是否是HTTP的哦,如果是,也要把图片的域设置哦!

    iOS 10 隐私权限设置

    iOS 10 开始对隐私权限更加严格,如果你不设置就会直接崩溃,现在很多遇到崩溃问题了,一般解决办法都是在info.plist文件添加对应的Key-Value就可以了。


    以上Value值,圈出的红线部分的文字是展示给用户看的,必须添加。

    Xcode 8 运行一堆没用的logs解决办法



    上图我们看到,自己新建的一个工程啥也没干就打印一堆烂七八糟的东西,我觉得这个应该是Xcode 8的问题,

    具体也没细研究,解决办法是设置OS_ACTIVITY_MODE : disable如下图:


    iOS 10 UIStatusBar方法过期:


    在我们开发中有可能用到UIStatusBar一些属性,在iOS 10 中这些方法已经过期了,如果你的项目中有用的话就得需要适配。

    上面的图片也能发现,如果在iOS 10中你需要使用preferredStatusBar比如这样:

    - (UIStatusBarStyle)preferredStatusBarStyle { 
       return UIStatusBarStyleDefault;
    }

    iOS 10 UICollectionView 性能优化

    随着开发者对UICollectionView的信赖,项目中用的地方也比较多,但是还是存在一些问题,比如有时会卡顿、加载慢等。所以iOS 10 对UICollectionView进一步的优化。

    • UICollectionView cell pre-fetching预加载机制
    • UICollectionView and UITableView prefetchDataSource 新增的API 针对self-sizing cells 的改进
    • Interactive reordering

    在iOS 10 之前,UICollectionView上面如果有大量cell,当用户活动很快的时候,整个UICollectionView的卡顿会很明显,为什么会造成这样的问题,这里涉及到了iOS 系统的重用机制,当cell准备加载进屏幕的时候,整个cell都已经加载完成,等待在屏幕外面了,也就是整整一行cell都已经加载完毕,这就是造成卡顿的主要原因,专业术语叫做:掉帧.
    要想让用户感觉不到卡顿,我们的app必须帧率达到60帧/秒,也就是说每帧16毫秒要刷新一次.

    iOS 10 之前UICollectionViewCell的生命周期是这样的:

    • 1.用户滑动屏幕,屏幕外有一个cell准备加载进来,把cell从reusr队列拿出来,然后调用prepareForReuse方法,在这个方法里面,可以重置cell的状态,加载新的数据;
    • 2.继续滑动,就会调用cellForItemAtIndexPath方法,在这个方法里面给cell赋值模型,然后返回给系统;
    • 3.当cell马上进去屏幕的时候,就会调用willDisplayCell方法,在这个方法里面我们还可以修改cell,为进入屏幕做最后的准备工作;
    • 4.执行完willDisplayCell方法后,cell就进去屏幕了.当cell完全离开屏幕以后,会调用didEndDisplayingCell方法.

     iOS 10 UICollectionViewCell的生命周期是这样的:

    • 1.用户滑动屏幕,屏幕外有一个cell准备加载进来,把cell从reusr队列拿出来,然后调用prepareForReuse方法,在这里当cell还没有进去屏幕的时候,就已经提前调用这个方法了,对比之前的区别是之前是cell的上边缘马上进去屏幕的时候就会调用该方法,而iOS 10 提前到cell还在屏幕外面的时候就调用;
    • 2.在cellForItemAtIndexPath中创建cell,填充数据,刷新状态等操作,相比于之前也提前了;
    • 3.用户继续滑动的话,当cell马上就需要显示的时候我们再调用willDisplayCell方法,原则就是:何时需要显示,何时再去调用willDisplayCell方法;
    • 4.当cell完全离开屏幕以后,会调用didEndDisplayingCell方法,跟之前一样,cell会进入重用队列.
    • 在iOS 10 之前,cell只能从重用队列里面取出,再走一遍生命周期,并调用cellForItemAtIndexPath创建或者生成一个cell.
      在iOS 10 中,系统会cell保存一段时间,也就是说当用户把cell滑出屏幕以后,如果又滑动回来,cell不用再走一遍生命周期了,只需要调用willDisplayCell方法就可以重新出现在屏幕中了.
    • iOS 10 中,系统是一个一个加载cell的,二以前是一行一行加载的,这样就可以提升很多性能;
    • iOS 10 新增加的Pre-Fetching预加载
    • 这个是为了降低UICollectionViewCell在加载的时候所花费的时间,在 iOS 10 中,除了数据源协议和代理协议外,新增加了一个UICollectionViewDataSourcePrefetching协议,这个协议里面定义了两个方法:
    - (void)collectionView:(UICollectionView *)collectionView prefetchItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths NS_AVAILABLE_IOS(10_0);
    
    - (void)collectionView:(UICollectionView *)collectionView cancelPrefetchingForItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths  NS_AVAILABLE_IOS(10_0);

       在ColletionView prefetchItemsAt indexPaths这个方法是异步预加载数据的,当中的indexPaths数组是有序的,就是item接收数据的顺序;
       CollectionView cancelPrefetcingForItemsAt indexPaths这个方法是可选的,可以用来处理在滑动中取消或者降低提前加载数据的优先级.
       注意:这个协议并不能代替之前读取数据的方法,仅仅是辅助加载数据.
       Pre-Fetching预加载对UITableViewCell同样适用.   

    iOS 10 UIColor 新增方法

    以下是官方文档的说明:

    Most graphics frameworks throughout the system, including Core Graphics, Core Image, Metal, and AVFoundation, have substantially improved support for extended-range pixel formats and wide-gamut color spaces. By extending this behavior throughout the entire graphics stack, it is easier than ever to support devices with a wide color display. In addition, UIKit standardizes on working in a new extended sRGB color space, making it easy to mix sRGB colors with colors in other, wider color gamuts without a significant performance penalty.

    Here are some best practices to adopt as you start working with Wide Color.

    • In iOS 10, the UIColor class uses the extended sRGB color space and its initializers no longer clamp raw component values to between 0.0 and 1.0. If your app relies on UIKit to clamp component values (whether you’re creating a color or asking a color for its component values), you need to change your app’s behavior when you link against iOS 10.
    • When performing custom drawing in a UIView on an iPad Pro (9.7 inch), the underlying drawing environment is configured with an extended sRGB color space.
    • If your app renders custom image objects, use the new UIGraphicsImageRenderer class to control whether the destination bitmap is created using an extended-range or standard-range format.
    • If you are performing your own image processing on wide-gamut devices using a lower level API, such as Core Graphics or Metal, you should use an extended range color space and a pixel format that supports 16-bit floating-point component values. When clamping of color values is necessary, you should do so explicitly.
    • Core Graphics, Core Image, and Metal Performance Shaders provide new options for easily converting colors and images between color spaces.

      因为之前我们都是用RGB来设置颜色,反正用起来也不是特别多样化,这次新增的方法应该就是一个弥补吧。所以在iOS 10 苹果官方建议我们使用sRGB,因为它性能更好,色彩更丰富。如果你自己为UIColor写了一套分类的话也可尝试替换为sRGB,UIColor类中新增了两个Api如下:

      ```objc

    • (UIColor *)colorWithDisplayP3Red:(CGFloat)displayP3Red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha NS_AVAILABLE_IOS(10_0);
    • (UIColor *)initWithDisplayP3Red:(CGFloat)displayP3Red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha NS_AVAILABLE_IOS(10_0);

      ```

    iOS 10 UITextContentType

    // The textContentType property is to provide the keyboard with extra information about the semantic intent of the text document.@property(nonatomic,copy) UITextContentType textContentType NS_AVAILABLE_IOS(10_0); // default is nil

    在iOS 10 UITextField添加了textContentType枚举,指示文本输入区域所期望的语义意义。

    使用此属性可以给键盘和系统信息,关于用户输入的内容的预期的语义意义。例如,您可以指定一个文本字段,用户填写收到一封电子邮件确认uitextcontenttypeemailaddress。当您提供有关您期望用户在文本输入区域中输入的内容的信息时,系统可以在某些情况下自动选择适当的键盘,并提高键盘修正和主动与其他文本输入机会的整合。

    iOS 10 字体随着手机系统字体而改变

    当我们手机系统字体改变了之后,那我们App的label也会跟着一起变化,这需要我们写很多代码来进一步处理才能实现,但是iOS 10 提供了这样的属性adjustsFontForContentSizeCategory来设置。因为没有真机,具体实际操作还没去实现,如果理解错误帮忙指正。

     UILabel *myLabel = [UILabel new];   /*
        UIFont 的preferredFontForTextStyle: 意思是指定一个样式,并让字体大小符合用户设定的字体大小。
       */
        myLabel.font =[UIFont preferredFontForTextStyle: UIFontTextStyleHeadline]; /*
     Indicates whether the corresponding element should automatically update its font when the device’s UIContentSizeCategory is changed.
     For this property to take effect, the element’s font must be a font vended using +preferredFontForTextStyle: or +preferredFontForTextStyle:compatibleWithTraitCollection: with a valid UIFontTextStyle.
     */
         //是否更新字体的变化
        myLabel.adjustsFontForContentSizeCategory = YES;

    iOS 10 UIScrollView新增refreshControl


    iOS 10 以后只要是继承UIScrollView那么就支持刷新功能:

    @property (nonatomic, strong, nullable) UIRefreshControl *refreshControl NS_AVAILABLE_IOS(10_0) __TVOS_PROHIBITED;

    iOS 10 判断系统版本正确姿势

    判断系统版本是我们经常用到的,尤其是现在大家都有可能需要适配iOS 10,那么问题就出现了,如下图:


    我们得到了答案是:

    //值为 1 [[[[UIDevice currentDevice] systemVersion] substringToIndex:1] integerValue]
    
    //值为10.000000 [[UIDevice currentDevice] systemVersion].floatValue,
    
    //值为10.0 [[UIDevice currentDevice] systemVersion]

    所以说判断系统方法最好还是用后面的两种方法,哦~我忘记说了[[UIDevice currentDevice] systemVersion].floatValue这个方法也是不靠谱的,好像在8.3版本输出的值是8.2,记不清楚了反正是不靠谱的,所以建议大家用[[UIDevice
    currentDevice] systemVersion]这个方法!

    Swift判断如下:

       if #available(iOS 10.0, *) {
                // iOS 10.0
                print("iOS 10.0");
            } else { }

    Xcode 8 插件不能用的问题

    大家都升级了Xcode 8,但是对于插件依赖的开发者们,一边哭着一边去网上寻找解决办法。那么下面是解决办法:
    让你的 Xcode8 继续使用插件(http://vongloo.me/2016/09/10/Make-Your-Xcode8-Great-Again/?utm_source=tuicool&utm_medium=referral )

    但是看到文章最后的解释,我们知道如果用插件的话,可能安全上会有问题、并且提交审核会被拒绝,所以建议大家还是不要用了,解决办法总是有的,比如在Xcode中添加注释的代码块也是很方便的。

    iOS 10开始项目中有的文字显示不全问题

    我用Xcode 8 和Xcode 7.3分别测试了下,如下图:

    xcode7


    xcode7


    xcode8


    xcode8

    创建一个Label然后让它自适应大小,字体大小都是17最后输出的宽度是不一样的,我们再看一下,
    下面的数据就知道为什么升级iOS 10 之后App中有的文字显示不全了:


    英文字母会不会也有这种问题,我又通过测试,后来发现英文字母没有问题,只有汉字有问题。
    目前只有一个一个修改控件解决这个问题,暂时没有其他好办法来解决。

    Xcode 8使用Xib awakeFromNib的警告问题

    在Xcode 8之前我们使用Xib初始化- (void)awakeFromNib {}都是这么写也没什么问题,但是在Xcode 8会有如下警告:


    官方解释:
    You must call the super implementation of awakeFromNib to give parent classes the opportunity to perform any additional initialization they require.
    Although the default implementation of this method does nothing, many UIKit classes provide non-empty implementations.
    You may call the super implementation at any point during your own awakeFromNib method.

    你必须调用父类实现awakeFromNib来给父类来执行它们需要的任何额外的初始化的机会。
    虽然这种方法的默认实现不做任何事情,许多UIKit类提供非空的实现。
    你可以调用自己的awakeFromNib方法中的任何时候超级实现




    1推送 

    xcode 升级到8之后很多人的推送接收不到了.获取不到token了 一朋友搞了一小时没找到原因. 只因看下图吧....我发觉xcode 我不打开他也能收到通知. 但是到了8(必须打开了才能收到推送) . 貌似不行了    大家对号入座吧.

    技术分享

    下面普及下ios10跟之前的推送的区别

    • iOS 9 以前的通知

       

      1.在调用方法时,有些方法让人很难区分,容易写错方法,这让开发者有时候很苦恼。

      2.应用在运行时和非运行时捕获通知的路径还不一致。

      3.应用在前台时,是无法直接显示远程通知,还需要进一步处理。

      4.已经发出的通知是不能更新的,内容发出时是不能改变的,并且只有简单文本展示方式,扩展性根本不是很好。

    • iOS 10 开始的通知 

      1.所有相关通知被统一到了UserNotifications.framework框架中。

      2.增加了撤销、更新、中途还可以修改通知的内容。

      3.通知不在是简单的文本了,可以加入视频、图片,自定义通知的展示等等。

      4.iOS 10相对之前的通知来说更加好用易于管理,并且进行了大规模优化,对于开发者来说是一件好事。

      5.iOS 10开始对于权限问题进行了优化,申请权限就比较简单了(本地与远程通知集成在一个方法中)。

     

     

    2 字体适配的问题

    ios 9 之前的lab 字体可以显示全,但是到了ios10 发觉字体显示不全了.得适配啊.app 会跟随手机系统字体大小而改变了.

    简单粗暴地方法就是不让他跟着手机系统的字体改变而改变.

    label.adjustsFontForContentSizeCategory = YES;

     

    3 xcode 8运行打印一堆没用的东西Xcode 8的问题,解决办法是设置OS_ACTIVITY_MODE : disable如下图:

    技术分享

     

     

    4  xcode8的注释快捷键是什么,   command+/ 不行了

    解决办法:

    因为苹果解决xcode ghost。把插件屏蔽了。解决方法
    命令运行: sudo /usr/libexec/xpccachectl 
    然后必须重启电脑后生效

    5 颜色问题, iOS 10 苹果官方建议我们使用sRGB,因为它性能更好,色彩更丰富。

    UIColor类中新增了两个Api如下: 

    + (UIColor *)colorWithDisplayP3Red:(CGFloat)displayP3Red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha NS_AVAILABLE_IOS(10_0); - (UIColor *)initWithDisplayP3Red:(CGFloat)displayP3Red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha NS_AVAILABLE_IOS(10_0);

     

     

    6 判断版本问题 

    建议用   [[UIDevice currentDevice] systemVersion]

    swift用

    if #available(iOS 10.0, *) {

               // iOS 10.0啊            

    print("iOS 10.0");        

    } else

    {

    }

    ;

     

    7 https的问题

    iOS 9中默认非HTTS的网络是被禁止的,当然我们也可以把NSAllowsArbitraryLoads设置为YES禁用ATS。不过iOS 10从2017年1月1日起苹果不允许我们通过这个方法跳过ATS,也就是说强制我们用HTTPS,如果不这样的话提交App可能会被拒绝。但是我们可以通过NSExceptionDomains来针对特定的域名开放HTTP可以容易通过审核。

     

    8  隐私权限 

    iOS 10 开始对隐私权限更加严格,如果你不设置就会直接崩溃,现在很多遇到崩溃问题了,一般解决办法都是在info.plist文件添加对应的Key-Value就可以了。

    技术分享

    <!-- 相册 --> 
    <key>NSPhotoLibraryUsageDescription</key> 
    <string>App需要您的同意,才能访问相册</string> 
    <!-- 相机 --> 
    <key>NSCameraUsageDescription</key> 
    <string>App需要您的同意,才能访问相机</string> 
    <!-- 麦克风 --> 
    <key>NSMicrophoneUsageDescription</key> 
    <string>App需要您的同意,才能访问麦克风</string> 
    <!-- 位置 --> 
    <key>NSLocationUsageDescription</key> 
    <string>App需要您的同意,才能访问位置</string> 
    <!-- 在使用期间访问位置 --> 
    <key>NSLocationWhenInUseUsageDescription</key> 
    <string>App需要您的同意,才能在使用期间访问位置</string> 
    <!-- 始终访问位置 --> 
    <key>NSLocationAlwaysUsageDescription</key> 
    <string>App需要您的同意,才能始终访问位置</string> 
    <!-- 日历 --> 
    <key>NSCalendarsUsageDescription</key> 
    <string>App需要您的同意,才能访问日历</string> 
    <!-- 提醒事项 --> 
    <key>NSRemindersUsageDescription</key> 
    <string>App需要您的同意,才能访问提醒事项</string> 
    <!-- 运动与健身 --> 
    <key>NSMotionUsageDescription</key> <string>App需要您的同意,才能访问运动与健身</string> 
    <!-- 健康更新 --> 
    <key>NSHealthUpdateUsageDescription</key> 
    <string>App需要您的同意,才能访问健康更新 </string> 
    <!-- 健康分享 --> 
    <key>NSHealthShareUsageDescription</key> 
    <string>App需要您的同意,才能访问健康分享</string> 
    <!-- 蓝牙 --> 
    <key>NSBluetoothPeripheralUsageDescription</key> 
    <string>App需要您的同意,才能访问蓝牙</string> 
    <!-- 媒体资料库 --> 
    <key>NSAppleMusicUsageDescription</key> 
    <string>App需要您的同意,才能访问媒体资料库</string>

    或者

    技术分享


    1,iOS10 新增的privacy settings

    iOS10添加了新的权限控制范围 如果你尝试访问这些隐私数据时得到如下错误:

    > This app has crashed because it attempted to access privacy-sensitive
    > data without a usage description.  The app's Info.plist must contain
    > an NSCameraUsageDescription key with a string value explaining to the
    > user how the app uses this data

    因为它企图访问敏感数据时没有在应用程序的Info.plist
    设置privacy key 新增的privacy setting如下:


    2, OS_ACTIVITY_MODE

    更新Xcode 8 如果控制台出现  enable_level: 0, persist_level: 0, default_ttl: 0, info_ttl: 0, debug_ttl: 0, generate_symptoms: 0 enable_oversize: 可通过如下方法设置:

    Edit Scheme-> Run -> Arguments, 
    在Environment Variables里边添加
    OS_ACTIVITY_MODE = Disable

    3,iOS10 layoutIfNeed

    iOS10 在一个控件上调用layoutIfNeed是只会单独计算约束,它所约束的控件不会生效,想要达到之前的效果需要在父级控件上调用layoutIfNeed

    4, NSDate

    Swift3.0会将oc的NSDate转为Data类型,有些操作NSDate的第三方库会闪退

    5, Notification

    Swift3.0字符串类型的通知常量被定义为struct

    static let MyGreatNotification = Notification.Name("MyGreatNotification")
    
    // Use site (no change)
    NotificationCenter.default().post(name: MyController.MyGreatNotification, object: self)'

    6, Zip2Sequence(::) 被移除

    在Swift3.0 Zip2Sequence(_:_:)方法被替换为zip(_:_:)

    7, Range<>.reversed 被移除

    在Swift3.0 Range<>.reversed方法被移除,被替换为<Collection>[<Range>].indices.reversed().

    var array = ["A","B","C","D"]
    
    for i in array.indices.reversed() {
    
        print("\(i)")
    }
    
    输出:3 2 1 0

    8, Range新增至四种类型

    Range
    CountableRange
    ClosedRange
    CountableClosedRange

    不同的表达式会生成不同的Range

    var countableRange = 0..<20 'CountableRange(0..<20)'
    
    var countableClosedRange = 0...20 'CountableClosedRange(0...20)'

    9, Collection 新增 index(_:)系列方法

    Index的successor(), predecessor(), advancedBy(_:), advancedBy(_:limit:), or distanceTo(_:)方法被移除,这些操作被移动到Collection

    myIndex.successor()  =>  myCollection.index(after: myIndex)
    myIndex.predecessor()  =>  myCollection.index(before: myIndex)
    myIndex.advance(by: …) => myCollection.index(myIndex, offsetBy: …)

    10, iOS10 UIStatusBar过期

    如果你需要操作UIStatusBar,在iOS10需要改为

    - (UIStatusBarStyle)preferredStatusBarStyle {
        return UIStatusBarStyleDefault;
    }

    11, iOS10 UICollectionView 性能优化

    在iOS10 UICollectionView 最大的改变是增加了Pre-Fetching(预加载),
    如果你翻看UICollectionView的最新API你可以发现新增了如下属性:

     @property (nonatomic, weak, nullable) id<UICollectionViewDataSourcePrefetching> prefetchDataSource 
    
    @property (nonatomic, getter=isPrefetchingEnabled) BOOL 
    

    在iOS10 Pre-Fetching 是默认开启的,如果出于某些原因你不想开启Pre-Fetching,可以通过如下设置禁用:

    collectionView.isPrefetchingEnabled = false

    UICollectionViewDataSourcePrefetching协议定义如下:

    @protocol UICollectionViewDataSourcePrefetching <NSObject>
    @required
    // indexPaths are ordered ascending by geometric distance from the collection view
    - (void)collectionView:(UICollectionView *)collectionView prefetchItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths NS_AVAILABLE_IOS(10_0);
    
    @optional
    // indexPaths that previously were considered as candidates for pre-fetching, but were not actually used; may be a subset of the previous call to -collectionView:prefetchItemsAtIndexPaths:
    - (void)collectionView:(UICollectionView *)collectionView cancelPrefetchingForItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths  NS_AVAILABLE_IOS(10_0);
    
    @end

    12, iOS10 UITableView 性能优化

    和UICollectionView一样UITableView也增加了Pre-Fetching技术,UITableView新增了如下属性:

    @property (nonatomic, weak) id<UITableViewDataSourcePrefetching> prefetchDataSource NS_AVAILABLE_IOS(10_0);

    奇怪的是UITableView并没有找到 isPrefetchingEnabled属性的定义

    13,iOS10 UIScrollView 新增 refreshControl 属性

    UIScrollView新增了refreshControl属性

    @property (nonatomic, strong, nullable) UIRefreshControl *refreshControl NS_AVAILABLE_IOS(10_0) __TVOS_PROHIBITED;

    这意味着 UICollectionViewUITableView 都支持refresh功能了。

    我们也可以脱离UITableViewController使用UIRefreshControl了。

    14, Swif3.0 新增作用域访问级别 fileprivate

    目前有如下访问级别:

    • 公开(public)

    • 内部(internal)

    • 文件外私有(fileprivate)

    • 私有(private)

    15,Swift3.0 允许关键字作为参数标签

    Swift3.0开始我们将能使用除inout var let关键字作为参数标签

       // Swift 3 calling with argument label:
        calculateRevenue(for sales: numberOfCopies,
                         in .dollars)
    
        // Swift 3 declaring with argument label:
        calculateRevenue(for sales: Int,
                         in currency: Currency)
    
    
        func touchesMatching(phase: NSTouchPhase, in view: NSView?) -> Set<NSTouch>

    如果你坚持要使用inout var let关键字可以使用 `` 包裹参数标签

    func addParameter(name: String, `inout`: Bool)

    一、证书管理

    用Xcode8打开工程后,比较明显的就是下图了,这个是苹果的新特性,可以帮助我们自动管理证书。建议大家勾选这个Automatically manage signing(Ps.但是在beat2版本我用的时候,完全不可以,GM版本竟然神奇的又好了。)

    QQ20160913-8.png-96.9kB

    下面我来说说可能会出现的问题:

    1.Xcode未设置开发者账号情况下的截图

    QQ20160913-0.png-38.5kB


    解决办法是:大家在Xcode的偏好设置中,添加苹果账号,即可。

    2.设备机器未添加进开发者的Device情况下的截图

    QQ20160913-2.png-33.7kB


    解决办法是:大家在官网将设备添加进开发机后,陪下描述文件重新下个描述文件即可。

    3.正常情况:Xcode配置登录开发者账号后的图片,耐心等待即可。

    QQ20160913-1.png-25.1kB


    等待完成之后的图

    QQ20160913-3.png-27kB

    二、Xib文件的注意事项

    使用Xcode8打开xib文件后,会出现下图的提示。

    QQ20160913-9.png-41.7kB


    大家选择Choose Device即可。
    之后大家会发现布局啊,frame乱了,只需要更新一下frame即可。如下图

    QQ20160913-11.png-113.2kB

    • 注意:如果按上面的步骤操作后,在用Xcode7打开Xib会报一下错误,

    QQ20160913-12.png-32.3kB

    • 解决办法:需要删除Xib里面 
      <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
      这句话,以及把< document >中的toolsVersion和< plugIn >中的version改成你正常的xib文件中的值
      ,不过不建议这么做,在Xcode8出来后,希望大家都快速上手,全员更新。这就跟Xcode5到Xcode6一样,有变动,但是还是要尽早学习,尽快适应哟!

    三、代码及Api注意

    使用Xcode8之后,有些代码可能就编译不过去了,具体我就说说我碰到的问题。
    1.UIWebView的代理方法:
    **注意要删除NSError前面的 nullable,否则报错。

    - (void)webView:(UIWebView *)webView didFailLoadWithError:(nullable NSError *)error
    {
        [self hideHud];
    }

    四、代码注释不能用的解决办法

    这个是因为苹果解决xcode ghost,把插件屏蔽了。
    解决方法
    打开终端,命令运行: sudo /usr/libexec/xpccachectl
    然后必须重启电脑后生效

    注意:Xcode8内置了开启注释的功能,位置在这里

    QQ20160914-3.png

    快捷键的设置在这里

    QQ20160914-2.png

    貌似Xcode8取消了三方插件的功能,具体可以查阅下Xcode8 Source Editor

    五、权限以及相关设置

    注意,添加的时候,末尾不要有空格
    我们需要打开info.plist文件添加相应权限的说明,否则程序在iOS10上会出现崩溃。
    具体如下图:

    QQ20160914-0.png

    麦克风权限:Privacy - Microphone Usage Description 是否允许此App使用你的麦克风?
    相机权限: Privacy - Camera Usage Description 是否允许此App使用你的相机?
    相册权限: Privacy - Photo Library Usage Description 是否允许此App访问你的媒体资料库?通讯录权限: Privacy - Contacts Usage Description 是否允许此App访问你的通讯录?
    蓝牙权限:Privacy - Bluetooth Peripheral Usage Description 是否许允此App使用蓝牙?

    语音转文字权限:Privacy - Speech Recognition Usage Description 是否允许此App使用语音识别?
    日历权限:Privacy - Calendars Usage Description 是否允许此App使用日历?

    定位权限:Privacy - Location When In Use Usage Description 我们需要通过您的地理位置信息获取您周边的相关数据
    定位权限: Privacy - Location Always Usage Description 我们需要通过您的地理位置信息获取您周边的相关数据
    定位的需要这么写,防止上架被拒。

    六、字体变大,原有frame需要适配

    经有的朋友提醒,发现程序内原来2个字的宽度是24,现在2个字需要27的宽度来显示了。。
    希望有解决办法的朋友,评论告我一下耶,谢谢啦

    七、推送

    如下图的部分,不要忘记打开。所有的推送平台,不管是极光还是什么的,要想收到推送,这个是必须打开的哟✌️

    QQ20160914-4.png

    之后就应该可以收到推送了。另外,极光推送也推出新版本了,大家也可以更新下。

    PS.苹果这次对推送做了很大的变化,希望大家多查阅查阅,处理推送的代理方法也变化了。

    // 推送的代理
    [<UNUserNotificationCenterDelegate>]

    iOS10收到通知不再是在
    [application: didReceiveRemoteNotification:]方法去处理, iOS10推出新的代理方法,接收和处理各类通知(本地或者远程)

    - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler { //应用在前台收到通知 NSLog(@"========%@", notification);}- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler { //点击通知进入应用 NSLog(@"response:%@", response);}

    稍后我会更新文章,对推送做一个详细的讲解。

    8.屏蔽杂乱无章的bug

    更新Xcode8之后,新建立工程,都会打印一堆莫名其妙看不懂的Log.
    如这些

    subsystem: com.apple.UIKit, category: HIDEventFiltered, enable_level: 0, persist_level: 0, default_ttl: 0, info_ttl: 0, debug_ttl: 0, generate_symptoms: 0, enable_oversize: 1,

    屏蔽的方法如下:
    Xcode8里边 Edit Scheme-> Run -> Arguments, 在Environment Variables里边添加
    OS_ACTIVITY_MODE = Disable

    QQ20160914-8.png

    如果写了之后还是打印log,请重新勾选对勾,就可以解决了

    Ps.考虑到添加上述内容在Xcode8后,真机调试可能出现异常,大家可以自定义一个宏定义,来做日志输出。

    #ifdef DEBUG
    
    #define DDLOG(...) printf(" %s\n",[[NSString stringWithFormat:__VA_ARGS__]UTF8String]);
    #define DDLOG_CURRENT_METHOD NSLog(@"%@-%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd))
    
    #else
    
    #define DDLOG(...) ;
    #define DDLOG_CURRENT_METHOD ;
    
    #endif

     


    写在前面

    收到一些小伙伴的来信,觉得可能下边没有表达清楚,先把大家关心的要点在此进行总结,有兴趣的可以看看下边的研究过程,没兴趣的直接看这段即可。

    • Xcode8支持Swift2.3和Swift3.0两种语编译,但是在整个工程中只能使用一种语法。
    • 如果想用Swift2.3版本开发,当弹出是否迁移到Swift3.0的对话框一律选择Later。所有的target(包括自己创建的和Cocoapods自动生成的)的Use Legacy Swift Language Version选择Yes。
    • 如果想用Swift3.0版本开发,当迁移到Swift3.0的界面选择target时,只要选择自己创建的target即可,Cocoapods导入的第三方不要勾选。所有的target(包括自己创建的和Cocoapods自动生成的)的Use Legacy Swift Language Version选择No.
    • Alamofire最新正式版本(4.0.0)只支持Swift3.0,想用Swift2.3开发的请选择3.5.0版本;
    • SnapKit的最新正式版本(3.0.0)同时支持Swift2.3和Swift3.0,请根据需求选择Use Legacy Swift Language Version的选项。
    • ReactiveCocoa的最新正式版本(4.2.2)只支持Swift2.3,凡是用到这个框架的项目只能使用Swift2.3开发。所有target包括自己创建的和Cocoapods自动生成的)的Use Legacy Swift Language Version选择Yes。

    探究过程

    Xcode8发布了,随着Xcode8一起到来的还有Swift3.0。相信好多小伙伴已经兴冲冲的下载了Xcode8,并且打开了自己的Swift项目想要尽快将自己的项目切换到Swift3.0吧。

    Tip:

    首先郑重提示,如果是Swift的项目:

    1. Xcode不要覆盖安装,最好保留Xcode7和Xcode8两个开发工具;
    2. 请先备份自己的项目,请先备份自己的项目,请先备份自己的项目;
    3. 如果项目迁移到Swift3.0失败,请用Xcode7打开自己备份项目继续开发,凡是用Xcode8打开过的Swift项目,Xcode7打开都会报错。

    我也是这么想的,用Xcode8打开自己的项目,首先提示我们Swift语法修改了,询问我们是否要迁移到Swift3.0,如图所示:


    是否转变当前的Swift语法

    当然选择Convert了,选择后,如图所示:


    转换到哪个版本的Swift

    选择转换到Swift3.0,一路Next之后,发现,发现依然报错,然后我就傻眼了。


    依然报错

    仔细观察错误信息,发现报错大部分集中在了第三方框架SnapKit中,难道是SnapKit不支持Swift3.0,我们在GitHub上看到:


    SnapKit最新版本支持Swift3.0

    难道是由于我们项目中的SnapKit不是最新版本导致的?
    更新后依然报错,这就尴尬了,人家明明说支持了,但是项目中就报错,这是为什么?

    这个时候我们应该去百度一下,发现好多人说要设置这个选项:


    是否使用旧版本的Swift语言

    设置之后,有些小伙伴可能就编译成功了,有些小伙伴可能依然编译出错。那么编译未成功如何解决呢?下面我们就来研究一下这个编译选项到底该怎么设置。

    正常来说,我们可以随便改自己写的代码,但是对于第三方的代码,如果我使用Cocopods导入的,一般会在代码的右上角看到这个锁形标志:


    lock


    这个标志表示当前文件被锁住,你没有修改的权限。所以我们最好不要修改第三方中的代码。但是主要问题又出在第三方框架中,所以我们优先解决第三方框架的Swift3.0的适配。

    SnapKit适配Swift3.0

    既然SnapKit的作者说SnapKit已经支持Swift3.0了,那么我们就先来适配SnapKit,首先用Xcode8新建一个空项目,利用Cocoapods导入SnapKit.


    Podfile

    打开工程,依然弹出这个选项:


    是否转换到Swift3.0

    刚才选择了Convert依然报错,可见不靠谱,这次我们全部选择Later。

    编译后,报错:


    报错

    错误提示我们依然是“Use Legacy Swift Language Version”这个选项的问题。
    我们来看看这个选项怎么设置,如图所示:


    设置SnapKit的编译选项

    因为SnapKit已经支持了Swift3.0,所以我们选择No,不支持旧的Swift版本,即使用Swift3.0的语法。编译通过。我们再来看看我们写的代码生成的target的编译选项:


    自己的target的编译选项


    由于Xcode8新建的工程默认使用Swift3.0的语法,所以此处默认选择为No。

    ReactiveCocoa适配Swift3.0

    相信在好多人在Swift中使用了响应式编程,提到响应式编程,就不得不说说RAC了,RAC是一个重型的OC框架,但是为了在Swift中可以使用,作者提供了Swift的桥接文件,所以,在Swift项目中导入了RAC,都会包含一些Swift的文件,这些Swift的文件也需要适配。

    GitHub上RAC的作者在readme中写到:


    readme


    RAC 5 支持Swift3.0.x,RAC 4支持Swift2.x。我们在Cocoapods中搜索ReactiveCocoa这个库:


    pod search ReactiveCocoa

    只找到了4.2.2版本的库,我不知道上边提到的RAC 5 和 RAC 4 分别指什么。只能先用这个版本了。同样的,新建一个工程:


    默认使用Swift3.0

    使用Cocoapods导入RAC:


    Podfile

    是否迁移到Swift3.0依然选择Later,编译,报错:


    报错

    和SnapKit的错误一样,同样的,我们去设置ReactiveCocoa的targetsh设置一下参数:


    编译设置


    和SnapKit同样设置为No,编译,报错。我们可以看到,安装ReactiveCocoa同时安装了一个Result,看看它的target设置:


    Result的便已设置


    设置的为Yes,那我们也把ReactiveCocoa的设置为Yes。编译,依然报错:


    依然报错

    我们尝试着把自己的target设置修改一下:


    修改自己工程的target设置

    编译成功。

    同时导入SnapKit和RAC

    现在分别导入SnapKit和RAC都编译成功了,但是可以看出SnapKit支持Swift3.0。RAC不支持。那么如果两个同时导入该选什么呢?

    经过测试,如果同事导入两个框架,所有的target的设置都得选择Yes。(大家可以自己试一下,在此不做赘述。)

    可以看到SnapKit既支持Swift3.0,也支持Swift2.3。那么它是如何做到的呢?通过查看源代码可以看到:


    源代码示例

    通过这样的宏来判断当前的Swift的编译版本来编译不同的代码段,从而实现兼容Swift2.3和Swift3.0。

    Alamofire

    经过测试,Alamofire的4.0.0版本仅支持iOS9+和Swift3.0.x,如果想使用Swift2.3开发的同学可以安装Alamofire的3.5.0版本,设置所有的Use Legacy Swift Language Version为Yes。

    总结

    • target的Build Setting的Use Legacy Swift Language Version选项的作用是设置当前target对应的文件是采用Swift2.3的语法编译还是Swift3.0的语法编译。当选择为Yes时,采用Swift2.3的语法编译;当选择是No时,采用Swift3.0的语法编译。
    • 新建的项目中,编译设置的原则为:所有的第三方中只要有一个第三方使用了Swift2.3的语法,那么所有的target的编译设置都应为Yes。如果都支持Swift3.0的语法,那么就可以设置为No。并且不能选择Unspecified。
    • 当Use Legacy Swift Language Version的选项设置为Yes时候,我们的工程只能使用Swift2.3来进行开发,当然你也可以像SnapKit那样利用宏来判断当前Swift的编译版本来实现适配Swift3.0,这样当以后迁移到Swift3.0也方便一些。

    思考

    既然每个target有自己单独的编译设置,理论上应该在编译的时候按照各自的target的编译设置来按照不同的Swift的版本编译,这样我们就可以自己的代码使用3.0编写,第三方根据各自不同进行不同的编译设置。以后想要迁移到完全的Swift3.0也更容易一些。但是目前看来编译的时候是统一按照我们缩写的target来编译的,这样的话单独设置各自的target还有什么意义呢?或许还需要一些别的设置才可以实现各自独立编译?对此有了解的同学麻烦告知一下,在此先谢过了。



    1,iOS10 新增的privacy settings

    iOS10添加了新的权限控制范围 如果你尝试访问这些隐私数据时得到如下错误:

    > This app has crashed because it attempted to access privacy-sensitive
    > data without a usage description.  The app's Info.plist must contain
    > an NSCameraUsageDescription key with a string value explaining to the
    > user how the app uses this data

    因为它企图访问敏感数据时没有在应用程序的Info.plist
    设置privacy key 新增的privacy setting如下:


    privacy setting

    2, OS_ACTIVITY_MODE

    更新Xcode 8 如果控制台出现 enable_level: 0, persist_level: 0, default_ttl: 0, info_ttl: 0, debug_ttl: 0, generate_symptoms: 0 enable_oversize: 可通过如下方法设置:

    Edit Scheme-> Run -> Arguments, 
    在Environment Variables里边添加
    OS_ACTIVITY_MODE = Disable

    3,iOS10 layoutIfNeed

    iOS10 在一个控件上调用layoutIfNeed是只会单独计算约束,它所约束的控件不会生效,想要达到之前的效果需要在父级控件上调用layoutIfNeed

    4, NSDate

    Swift3.0会将oc的NSDate转为Data类型,有些操作NSDate的第三方库会闪退

    5, Notification

    Swift3.0字符串类型的通知常量被定义为struct

    static let MyGreatNotification = Notification.Name("MyGreatNotification")
    
    // Use site (no change)
    NotificationCenter.default().post(name: MyController.MyGreatNotification, object: self)'

    6, Zip2Sequence(::) 被移除

    在Swift3.0 Zip2Sequence(_:_:)方法被替换为zip(_:_:)

    7, Range<>.reversed 被移除

    在Swift3.0 Range<>.reversed方法被移除,被替换为<Collection>[<Range>].indices.reversed().

    var array = ["A","B","C","D"]
    
    for i in array.indices.reversed() {
    
        print("\(i)")
    }
    
    输出:3 2 1 0

    8, Range新增至四种类型

    Range
    CountableRange
    ClosedRange
    CountableClosedRange

    不同的表达式会生成不同的Range

    var countableRange = 0..<20 'CountableRange(0..<20)'
    
    var countableClosedRange = 0...20 'CountableClosedRange(0...20)'

    9, Swift3.0 Collection 新增 index(_:)系列方法

    Index的successor(), predecessor(), advancedBy(_:), advancedBy(_:limit:), or distanceTo(_:)方法被移除,这些操作被移动到Collection

    myIndex.successor()  =>  myCollection.index(after: myIndex)
    myIndex.predecessor()  =>  myCollection.index(before: myIndex)
    myIndex.advance(by: …) => myCollection.index(myIndex, offsetBy: …)

    10, iOS10 UIStatusBar过期

    如果你需要操作UIStatusBar,在iOS10需要改为

    - (UIStatusBarStyle)preferredStatusBarStyle {
        return UIStatusBarStyleDefault;
    }

    11, iOS10 UICollectionView 性能优化

    在iOS10 UICollectionView 最大的改变是增加了Pre-Fetching(预加载),
    如果你翻看UICollectionView的最新API你可以发现新增了如下属性:

     @property (nonatomic, weak, nullable) id<UICollectionViewDataSourcePrefetching> prefetchDataSource 
    
    @property (nonatomic, getter=isPrefetchingEnabled) BOOL

    在iOS10 Pre-Fetching 是默认开启的,如果出于某些原因你不想开启Pre-Fetching,可以通过如下设置禁用:

    collectionView.isPrefetchingEnabled = false

    UICollectionViewDataSourcePrefetching协议定义如下:

    @protocol UICollectionViewDataSourcePrefetching <NSObject>
    @required
    // indexPaths are ordered ascending by geometric distance from the collection view
    - (void)collectionView:(UICollectionView *)collectionView prefetchItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths NS_AVAILABLE_IOS(10_0);
    
    @optional
    // indexPaths that previously were considered as candidates for pre-fetching, but were not actually used; may be a subset of the previous call to -collectionView:prefetchItemsAtIndexPaths:
    - (void)collectionView:(UICollectionView *)collectionView cancelPrefetchingForItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths  NS_AVAILABLE_IOS(10_0);
    
    @end

    12, iOS10 UITableView 性能优化

    和UICollectionView一样UITableView也增加了Pre-Fetching技术,UITableView新增了如下属性:

    @property (nonatomic, weak) id<UITableViewDataSourcePrefetching> prefetchDataSource NS_AVAILABLE_IOS(10_0);

    奇怪的是UITableView并没有找到 isPrefetchingEnabled属性的定义

    13,iOS10 UIScrollView 新增 refreshControl 属性

    UIScrollView新增了refreshControl属性

    @property (nonatomic, strong, nullable) UIRefreshControl *refreshControl NS_AVAILABLE_IOS(10_0) __TVOS_PROHIBITED;

    这意味着 UICollectionViewUITableView 都支持refresh功能了。

    我们也可以脱离UITableViewController使用UIRefreshControl了。

    14, Swif3.0 新增作用域访问级别 fileprivate

    目前有如下访问级别:

    • 公开(public)
    • 内部(internal)
    • 文件外私有(fileprivate)
    • 私有(private)

    15,Swift3.0 允许关键字作为参数标签

    Swift3.0开始我们将能使用除inout var let关键字作为参数标签

       // Swift 3 calling with argument label:
        calculateRevenue(for sales: numberOfCopies,
                         in .dollars)
    
        // Swift 3 declaring with argument label:
        calculateRevenue(for sales: Int,
                         in currency: Currency)
    
    
        func touchesMatching(phase: NSTouchPhase, in view: NSView?) -> Set<NSTouch>

    如果你坚持要使用inout var let关键字可以使用 `` 包裹参数标签

    func addParameter(name: String, `inout`: Bool)

    private和fileprivate

    自动转换代码以后把我大部分(不知道是不是全部,没统计)private都改成了fileprivate。本来不用private也不会对程序的编译运行有任何影响,private只是为了保证代码外部可读性而准备的,而现在有了fileprivate以后,private变得更加“私有”。现在的private方法和对象,只能在大括号中访问,即便是这个类的extension中,也不能访问private。而fileprivate的作用域,则和以前的private一样,顾名思义,在这个文件中都能访问。

    NSData和Data

    Data是swift的产物,和Array,Dictionary,Set等类似。NSData的初始化是NSData(XXX),而Data用起来更方便,在需要获取数据的对象后面加上.data,即可获得数据,方便是方便,老代码的修改就比较麻烦了。

    NSURLSession和URLSession

    URLRequest终于把烦人的Mutable去掉了,那些强迫症不用再因为let xxx = NSMutableXXX是可变的而纠结了。

    # Any和AnyObject
    现在Any貌似可以和AnyObject互相转换了,以前Any对应struct而AnyObject对应class,一些不太复杂的模型用struct编写,和某些方法(参数需要传AnyObject或者class类型的数据)兼容性不好,不得不改为用class编写,这就不符合struct设计的初衷了。

    # 闭包的escaping和non-escaping类型
    这个类型决定了闭包是否在调用他的函数(或其他)返回时就销毁(?),escaping是不销毁的意思,non-escaping是保留的意思。一般在网络方法中,闭包一般在其他线程中执行,并且在函数返回时还没有执行完毕,这里种情况应该使用escaping类型。使用方法是在闭包前面加@escaping。反之同理。
    那么为什么在swift2之前都不需要加呢,因为swift2之前默认都是escaping类型,而swift3以后默认是non-escaping。在合理的情况下,使用non-escaping类型的闭包更节省内存,而且,在闭包内可以不用再加self关键字了。
    参考文章

    awakeFromNib方法中获取frame

    原来在xib文件中设置约束定宽高约束,在awakeFromNib方法中是可以直接获取到view.frame.size的值的,现在可能因为xib文件中加入了多设备的尺寸设置,已经不能再获取size了。原来frame还跟xib的实际大小有关,现在xib所有的布局都是相对的了,不能再过分依赖frame。顺带说一下,现在如果直接获取size,得到的是(1000.0, 1000.0)。

    plist中的privacy key

    在iOS旧版本中都会,凡是涉及到隐私相关权限(例如录音、摄像之类的)的访问,都会提示是否允许访问。在plist有一系列privacy - XXXDescription的key作为权限询问提示的文字,旧版iOS中这些是选填的,iOS10里面如果没有填写又访问了相关权限,程序会崩溃。

    形如"\(XXX)"在字符串中引用其他对象

    在之前的版本中,只有当XXX的类型是optional?,打印结果才会带有"optional",例如:

    var XXX: Int? = 1
    print("XXX的结果为:\(XXX))  //XXX的结果为:optional(1)

    但如果XXX类型为optional!,就不会打印"optional"。
    在新版本中,无论类型为!还是?,打印结果都会带有optional,可以在打印时加上!,或者声明时不要声明为optional解决。例如:

    //错误示范:
    var XXX: Int! = 1
    print("XXX的结果为:\(XXX))  //XXX的结果为:optional(1)
    //正确示范:
    var XXX: Int! = 1
    print("XXX的结果为:\(XXX!))  //XXX的结果为:1
    //或者
    var XXX: Int = 1
    print("XXX的结果为:\(XXX))  //XXX的结果为:1




    展开全文
  • UIKit框架-高级控件Swift版本: 4.UICollectionView全属性详解

    前面我们讲解完了iOS的第一个列表控件UITableView以及它的表格空间UITableViewCell, 这次让我们继续来讲解iOS的第二个列表控件UICollectionView.


    1.UICollectionView的常用属性

    // 1.设置位置和大小
    init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout)
    
    // 2.设置子视图的布局方式
    var collectionViewLayout: UICollectionViewLayout
    
    // 3.设置UICollectionView的代理对象
    unowned(unsafe) var delegate: UICollectionViewDelegate?
    
    // 4.设置UICollectionView的数据源对象
    unowned(unsafe) var dataSource: UICollectionViewDataSource?
    
    // 5.设置UICollectionView的背景视图
    var backgroundView: UIView?
    
    // 6.设置 UICollectionView 的 Cell 是否可以点击
    var allowsSelection: Bool
    
    // 7.设置 UICollectionView 的 Cell 是否可以多选
    var allowsMultipleSelection: Bool

    UICollectionViewCell显示的样式

    struct UICollectionViewScrollPosition : RawOptionSetType {
        init(_ rawValue: UInt)
        init(rawValue: UInt)
    
        // 1.没有样式
        static var None: UICollectionViewScrollPosition { get }
    
        // 2.垂直居中显示
        static var CenteredVertically: UICollectionViewScrollPosition { get }
    
        // 3.向下显示
        static var Bottom: UICollectionViewScrollPosition { get }
    
        // 4.向左显示
        static var Left: UICollectionViewScrollPosition { get }
    
        // 5.水平居中显示
        static var CenteredHorizontally: UICollectionViewScrollPosition { get }
    
        // 6.向右显示
        static var Right: UICollectionViewScrollPosition { get }
    }
    

    2.UICollectionView常用的方法

    // 1.设置UICollectionView的注册类, 以及标示符
        func registerClass(cellClass: AnyClass?, forCellWithReuseIdentifier identifier: String)
    
    // 2.设置 UICollectionView的注册Nib, 以及标示符
        func registerNib(nib: UINib?, forCellWithReuseIdentifier identifier: String)
    
    // 3.设置 UICollectionView 的注册类, 以及辅助视图名称, 标示符
        func registerClass(viewClass: AnyClass?, forSupplementaryViewOfKind elementKind: String, withReuseIdentifier identifier: String)
    
    // 4.设置 UICollectionView的注册Nib, 以及辅助视图名称, 标示符
        func registerNib(nib: UINib?, forSupplementaryViewOfKind kind: String, withReuseIdentifier identifier: String)
    
    // 5.设置 UICollectionView 可重用的 Cell 以及所以路径
        func dequeueReusableCellWithReuseIdentifier(identifier: String, forIndexPath indexPath: NSIndexPath!) -> AnyObject
    
    // 6.设置 UICollectionView 可重用的的辅视图, 标示符, 以及索引路径
        func dequeueReusableSupplementaryViewOfKind(elementKind: String, withReuseIdentifier identifier: String, forIndexPath indexPath: NSIndexPath!) -> AnyObject
    
    // 7.选择 Item 的索引路径
        func indexPathsForSelectedItems() -> [AnyObject] 
    
    // 8.选择 Item 的索引路径, 以及是否使用动画, 显示样式
        func selectItemAtIndexPath(indexPath: NSIndexPath?, animated: Bool, scrollPosition: UICollectionViewScrollPosition)
    
    // 9.取消选择 Item 的索引路径, 以及是否使用动画
        func deselectItemAtIndexPath(indexPath: NSIndexPath?, animated: Bool)
    
    // 10.刷新数据
        func reloadData()
    
    // 11.设置 UICollectionView 的集合视图布局, 及是否使用动画
        func setCollectionViewLayout(layout: UICollectionViewLayout, animated: Bool)
    
    // 12.设置 UICollectionView 的集合视图布局, 及是否使用动画, 以及完成之后的闭包方法
        func setCollectionViewLayout(layout: UICollectionViewLayout, animated: Bool, completion: ((Bool) -> Void)!)
    
    // 13.设置 UICollectionView 显示多少个 Item
        func numberOfSections() -> Int
    
    // 14.设置 UICollectionView 显示多少组 Item
        func numberOfItemsInSection(section: Int) -> Int
    
    // 15.设置 UICollectionView 滚动到第几个 Item 的索引路径, 以及显示样式和是否启用动画
        func scrollToItemAtIndexPath(indexPath: NSIndexPath, atScrollPosition scrollPosition: UICollectionViewScrollPosition, animated: Bool)
    
    // 16.在 UICollectionView 中插入某个 Item
        func insertSections(sections: NSIndexSet)
    
    // 17.在 UICollectionView 中删除某个 Item
        func deleteSections(sections: NSIndexSet)
    
    // 16.在 UICollectionView 中刷新某个 Item
        func reloadSections(sections: NSIndexSet)
    
    // 17.移动 UICollectionView 中某个 Item 到某个位置
        func moveSection(section: Int, toSection newSection: Int)
    

    UICollectionView代理方法

    // 1.点击 Item 时调用的方法
        optional func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)
    
    // 2.取消选中 Item 时调用的方法
        optional func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath)

    UICollectionView数据源方法

    // 1.设置UICollectionView有多少个Item
        func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
    
    // 2.设置 UICollectionViewCell 所显示的内容, 以及索引路径
        func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
    
    // 3.设置 UICollectionView 有多少组 Cell
        optional func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int

    UICollectionView的集视图布局方法

    // 1.该方法是用来设置 UICollectionView 的 Item 尺寸大小
        optional func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
    
    // 2.该方法是用来设置 UICollectionView 的 Item 四周的边界
        optional func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets
    
    // 3.该方法是用来设置 UICollectionView 的 Item 上下之间的最小间距(如果在自定义UICollectionView中实现了该属性, 那么该方法就会覆盖掉原来的属性)
        optional func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat
    
    // 4.该方法是用来设置 UICollectionView 的 Item 左右之间的最小间距(如果在自定义UICollectionView中实现了该属性, 那么该方法就会覆盖掉原来的属性)
        optional func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat
    
    // 5.该方法是用来设置 UICollectionView 的页头尺寸(如果在自定义UICollectionView中实现了该属性, 那么该方法就会覆盖掉原来的属性)
        optional func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize
    
    // 6.该方法是用来设置 UIcollectionView 的页尾尺寸(如果在自定义UICollectionView中实现了该属性, 那么该方法就会覆盖掉原来的属性)
        optional func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize
    

    3.代码演示

    首先我们要遵守以下协议

    class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
    }

    自定义UICollectionView

        func myCollectionView() {
            // 1.自定义 Item 的FlowLayout
            let flowLayout = UICollectionViewFlowLayout()
    
            // 2.设置 Item 的 Size
            flowLayout.itemSize = CGSizeMake(90, 120)
    
            // 3.设置 Item 的排列方式
            flowLayout.scrollDirection = UICollectionViewScrollDirection.Vertical
    
            // 4.设置 Item 的四周边距
            flowLayout.sectionInset = UIEdgeInsetsMake(20, 20, 20, 20)
    
            // 5.设置同一竖中上下相邻的两个 Item 之间的间距
            flowLayout.minimumLineSpacing = 20
    
            // 6.设置同一行中相邻的两个 Item 之间的间距
            flowLayout.minimumInteritemSpacing = 20
    
            // 7.设置UICollectionView 的页头尺寸
            flowLayout.headerReferenceSize = CGSizeMake(100, 50)
    
            // 8.设置 UICollectionView 的页尾尺寸
            flowLayout.footerReferenceSize = CGSizeMake(100, 50)
    
            // 1.自定义 UICollectionView 的位置大小, 以及 Item 的显示样式为 flowLayout
            var collection = UICollectionView(frame: CGRectMake(0, 64, self.view.frame.width, self.view.frame.height - 64), collectionViewLayout: flowLayout)
    
            // 2.设置 UICollectionView 的背景颜色
            collection.backgroundColor = UIColor.whiteColor()
    
            // 3.设置 UICollectionView 垂直滚动是否滚到 Item 的最底部内容
            collection.alwaysBounceVertical = true
    
            // 4.设置 UICollectionView 垂直滚动是否滚到 Item 的最右边内容
            collection.alwaysBounceHorizontal = true
    
            // 5.设置 UICollectionView 的数据源对象
            collection.dataSource = self
    
            // 6.设置 UICollectionView 的代理对象
            collection.delegate = self
    
            // 7.设置 UICollectionView 的单元格点击(默认是 true)
            collection.allowsSelection = true
    
            // 8.设置 UICollectionView 的单元格多选(默认是 false)
            collection.allowsMultipleSelection = false
    
            // 9.开启 UICollectionView 的分页显示效果
            collection.pagingEnabled = true
    
            // 10.注册 UICollectionViewCell
    collection.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
            // 11.添加到 self.view 上
            self.view.addSubview(collection)
        }

    自定义UINavigationBar

        func myNavigationBar() {
            // 1.自定义 NavigationBar, 设置它的位置大小
            var navigationBar = UINavigationBar(frame: CGRectMake(0, 0, self.view.frame.width, 64))
            // 2.设置 NavigationBar 的背景色
            navigationBar.backgroundColor = UIColor.redColor()
            // 3.自定义 NavigationItem 设定它的 Title
            let navigationItem = UINavigationItem(title: "UICollectionView演示")
            // 4.自定义 UIBarButtonItem 的Title, Style, Target 的对象, 已经监听的方法
            let leftButton = UIBarButtonItem(title: "返回", style: UIBarButtonItemStyle.Plain, target: self, action: "back")
            // 5.设置 Navigation 左边的按钮为 leftButton
            navigationItem.leftBarButtonItem = leftButton
            // 6.把 NavigationItem 添加到 NavigationBar
            navigationBar.pushNavigationItem(navigationItem, animated: true)
            // 7.添加到到 self.view 上
            self.view.addSubview(navigationBar)
        }
    
        // 8.NavigationBar监听方法
        func back() {
            println("点击了返回")
        }

    UICollectionView的代理方法, 数据源方法, FlowLayout 方法

        // 1.该方法是用来设置返回 CollectionViewCell 的组数
        func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
            return 1
        }
    
        // 2.该方法是用来设置返回 CollectionViewCell 的个数
        func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            return 15
        }
    
        // 3.该方法是用来设置 CollectionViewCell 的内容
        func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
            var collectionCell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! UICollectionViewCell
            collectionCell.backgroundColor = UIColor.redColor()
    
            return collectionCell
        }
    
        // 4.该方法是点击了 CollectionViewCell 时调用的监听方法
        func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
            println("aaa")
        }
    
        // 5.该方法是用来设置 CollectionViewCell 的大小
        func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
            return CGSizeMake(90, 120)
        }
    
        // 6.该方法是用来设置 CollectionViewCell 四周的边距
        func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
            return UIEdgeInsetsMake(20, 20, 20, 20)
        }
    
        // 7.该方法是用来设置同一行 CollectionViewCell 之间的间距
        func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
            return 20
        }
    
        // 8.该方法是用来设置同一列 CollectionViewCell 之间的间距
        func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
            return 20
        }
    
        // 9.该方法是用来设置 CollectionView 的页头尺寸
        func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
            return CGSizeMake(100, 50)
        }
    
        // 10.该方法是用来设置 CollectionView 的页尾尺寸
        func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
            return CGSizeMake(100, 50)
        }

    4.最终效果

    1

    2

    3

    PS: UIColleCtionView 是继承于 UIScrollView 的, 所以 UIScrollView 里的属性, 以及方法都是可以用的.


    好了这次我们就讲到这里, 下次我们继续~~

    展开全文
  • Swift 自定义UITableView

    2020-07-01 10:21:44
    UITableView是我们开发过程中比较常用的,用于显示一系列对象,UITableView继承自UIScrollView,UIScrollView可以在任意方向滑动,而UITableView只在垂直方向上滑动。UITableView中的内容是由UITableViewCell负责...
  • Swift的存储属性, 计算属性, 属性监视器
  • 对图片压缩这一块之前也没具体研究过,...在网上搜索一番,发现一篇不错的文章讨论了微信的图片尺寸转换规则,微信缩小尺寸基本上是围绕1280的pixel来展开的,还有些文章也提到了pixel最好是8的倍数之类的内容
  • 序言 最近由于写多了业务逻辑的软件,让人很烦闷啊。...那用这个做swift 游戏避免不了角色移动吧,移动就会需要虚拟摇杆。那如何实现呢? 基本介绍 1.节点 熟悉JS的同学应该很了解节点这个东西,Nod...
  • Core Image是一个可以让你轻松使用图形过虑器的强力框架。在这里你几乎可以获得所有不同种类的效果,比如修改图像饱和度,色彩范围,亮度等。它甚至也可以利用CPU或者GPU来处理图像数据并且它的速度很快,快到可以对...
  • 前言:网上一直没有找到用Swift开发IOS的好的教程,所以找了官网的文档翻译一下算了。如有错误欢迎指正。 原文链接:Work with View Controllers —————————————————————————————— 在...
  • 前言:网上一直没有找到用Swift开发IOS的好的教程,所以找了官网的文档翻译一下算了。如有错误欢迎指正。 原文链接:Create a Table View —————————————————————————————— 在本次课程...
  • 转自:http://www.111cn.net/sj/iOS/104115.htm 应网友要求,我这里总结了下 as、as!、as? 这三种类型转换操作符的异同,以及各自的使用场景。 1,as使用场合 (1)从派生类转换为基类...let cat = Cat()
  • Masonry的简单使用 首先,在正式使用Masonry之前,我们先来看看在xib中我们是如何使用AutoLayout ...从图中我们可以看出,只要设置相应得局限,控制好父视图与子视图之间的关系就应该很ok的拖出你需要的需求。...
  • 前言:网上一直没有找到用Swift开发IOS的好的教程,所以找了官网的文档翻译一下算了。如有错误欢迎指正。 原文链接:Build a Basic UI —————————————————————————————— 上一篇文章写...
  • 想象一下你已经完成了你的app并且运行的很好,但是界面看上去太土,你可以在PS里面画好多不同尺寸的自定义控件,Apple并没有4x的retina屏幕。 或者你已经未雨绸缪,在代码中使用Core Graphics创建一个图形并且缩放...
  • swift数据类型

    2016-06-07 09:51:26
    1.常量和变量的定义。 常量使用let 进行约束, 变量使用var来约束,相信大家对var并不陌生,如早期...swift对常量,和变量的约束,编译更加精确,有时候用户可以不需要声明某个常量是什么类型,像通常 声明一...
  • 前言:学了三个月的时候,就打算写一个教程的,但是后来一直忙于开发。直到11.30号提交了上一个游戏,这才腾出一小段时间,打算整理一下过去所学的,结合自己的经历,出一个简单的教程抛砖引玉,希望能帮助到那些...
  • swift问题集--未完待续

    2019-07-03 13:47:08
    由于 swift 是一个静态语言, 所以没有 Objective-C 中的消息发送这些动态机制, dynamic 的作用就是让 swift 代码也能有 Objective-C 中的动态机制, 常用的地方就是 KVO 了, 如果要监控一个属性, 则必须要标记为 ...
1 2 3 4 5 ... 19
收藏数 371
精华内容 148
关键字:

ps尺寸 swift