苹果四,好几个横屏游戏,启动之后都是小腹左下角隐痛一个小屏幕。设置里面也没有什么大小设置

让 iOS 10 更好用的 20 个小技巧 - 少数派
让 iOS 10 更好用的 20 个小技巧
让 iOS 10 更好用的 20 个小技巧
距离 iOS 10 正式版发布已经一个月了,相信绝大多数人都已经更新了新版系统,在系统发布之初我们就向大家介绍了 ,并且在之后对一些重要功能也进行了。
和以往的历代 iOS 系统一样,除了一些大功能点变化之外,新系统还加入了很多实用的小技巧,在经过了一个多月的使用之后,我们为大家整理了一部分 iOS 10 的小技巧,之后我们也将根据情况继续为大家汇总更多的实用技巧。
找回 iOS 9 的指纹解锁方式
从 iOS 10 Beta 版开始直到正式版推出,我都忘了已经在文章和微博中提到过多少次这个技巧了,但是每次还都有人像发现新大陆一样欣喜不已,所以这里还是再说一次吧。
苹果把经典的「滑动解锁」改成了「按下 Home 键」解锁,即使已经通过 Touch ID 验证,手机也不会立刻解锁,而是需要再按一下 Home 键才行。你可以在「设置 - 通用 - 辅助功能 - 主屏幕按钮」中找到「轻触打开」的选项,激活这个功能后,你就可以像以前一样快速解锁手机了。
一键清除所有通知
这个功能之前已经介绍过,不过还是有很多人不知道,重按通知中心的「清除」,就可以一键清除所有的通知,如果你的通知中心经常堆满了各种通知,这个功能对你非常有帮助。
通过 3D Touch 控制应用下载
在应用下载过程中,你可以通过在桌面重按应用图标进行「暂停 / 继续下载」或者「取消下载」的操作,同时如果有多款应用同时在进行安装 / 更新,你还可以调整应用下载的优先级,让某些应用优先进行下载。
快速添加 Widget
对于支持 Widget 的应用,你现在也可以通过重按应用图标的方法快速添加应用的 Widget,不过并不是所有支持 Widget 的应用都支持了这个功能。
控制中心和 Spotlight 也支持 3D Touch
通知中心最下方的四个快捷应用也是支持 3D Touch 功能的,你可以利用 3D Touch 调整手电筒的亮度、设定倒计时、拷贝计算器的计算结果,或者快速启动相机的不同拍摄方式。
同样的,新版的 Spotlight 搜索功能也增加了对 3D Touch 的支持,在 Spotlight 搜索到的应用可以直接实用 3D Touch 调用弹出菜单,效果和在桌面上相同。
升级为「查询」的「定义」功能
之前用来查单词的「定义」功能升级成了「查询」,现在在文章中看到想要查询的词条可以直接通过「查询」快速跳转到网页搜索,提高了搜索的效率。
输入法智能补全个人信息
如果你使用系统原生输入法,并且在通讯录完善了个人信息,那么当你输入「我是」「我的电话号码 / 邮箱地址是」的时候,输入法会自动在联想框中显示你的名字和号码 / 邮箱地址。
相册中内建的标注功能
这是一个之前内建在原生邮件应用中的功能,iOS 10 把这个实用的功能也加入了相册,不过入口藏的有点深,你要在相册的修图功能下面找到它。
自带的图片标注功能主要提供了三种标注工具:画框、放大镜、文字。它同时还具备线框自动识别能力,当你在图片上随手画一个形状时,它会自动识别你是否想画的是某个规则形状。
关联阅读:
快速在日历中添加重复事项
在新建事件的「标题」中输入一些内容(文字、字母、emoji),日历就会识别出过往事件中相同的内容,并作为候选事件显示在屏幕上。用户只要一次点击,就可以将事件详情重新添加,你只需要修改时间就可以快速建立一个新事件,效果等同于复制粘贴,非常方便。
开关锁屏农历显示
iOS 10 的锁屏上默认会显示一行农历日期,如果不需要,可以在「设置 - 日历 - 其它历法」中关闭它。
自动下载音乐
Apple Music 提供了自动下载音乐的功能,激活后,你此后添加到音乐库的歌曲都会自动下载到本地。这个功能在你第一次使用 Apple Music 添加播放列表时会自动弹出提示,如果你当时选择了取消,之后你可以在「系统设置 - 音乐」中找到「自动下载」功能。
同时你也可以在「已下载的音乐」中清楚地看到歌曲的占用空间和使用情况。
管理 Apple Music 存储空间 & 下载方式
同时你可以在音乐设置中查看已下载的音乐,也可以使用「优化存储空间」让系统自动移除长时间未播放的音乐,并且选择移动数据的使用方式。
一键关闭 Safari 标签页
当你在 Safari 浏览器中打开多个标签页的时候,长按右下角的「标签切换」图标,就可以一次性关闭全部页面。
Safari 浏览器支持标签搜索功能
在 iOS 9 中,Safari 同时打开的标签页的上限是 36 个,而在 iOS 10 中苹果取消了这一限制,理论上你现在可以打开无限多个标签页。当你打开多个标签页时,在横屏模式下,你可以使用搜索功能找到你想要查看的标签页,不过只能搜索标签页的标题,不能搜索文中内容。
信息可以单独设置已读回执
在使用 iMessage 的时候开启「已读回执」功能就可以让对方知道你是否已经查看了信息,iOS 10 之前这个功能只能全局设定,现在你可以在对话中点击右上角,单独开启 / 关闭已读回执功能。
设置发送图片的质量
如果担心通过短信发送图片太费流量,可以在「设置 - 信息」中打开「低质量图像模式」,这样图片将会经过压缩后再进行发送。
备忘录协作功能
你现在可以和朋友协作编辑备忘录内容了,点击备忘录右上角的协作按钮,你可以通过多种方式向好友发送邀请链接,好友接受邀请之后你也会收到提示。
直接将文件保存到 iCloud Drive
iOS 10 还在文件分享菜单中加入了「添加到 iCloud Drive」的选项,现在你可以在 Safari、邮件等应用中直接把文件保存到 iCloud Drive 中。
一键取消邮件订阅 & 快速筛选邮件
iOS 10 的原生邮箱应用提供了一键取消邮件订阅的功能,当你收到一些会员或者广告邮件时,你可以在邮件内容的最上方看到「取消订阅」的选项,在这里就可以直接取消邮件订阅。
同时你也可以在原生邮箱中快速筛选想要查看的邮件,点击左下角的「过滤器」图标即可开启,筛选功能默认显示「未读」邮件,你也可以通过点击「未读」来调整过滤规则。
更改邮件主题显示方式
新版邮件默认排列来往邮件的方式是按照正序时间排列的(最早的邮件在最前面),但是对于多数人来说这可能是不符合使用习惯的,你可以在「系统设置 - 邮件 - 邮件主题」中开启「最新邮件显示在最上方」选项,邮件就会倒序排列了。
如果你有发现哪些实用或者有趣的 iOS 小技巧,也欢迎在评论区留言和大家分享。
分享到微信
Email 登录
商务&合作:
投稿&报道:
微信订阅二维码iOS 适配的几种模式 - 简书
下载简书移动应用
写了224074字,被61人关注,获得了52个喜欢
iOS 适配的几种模式
1.尺寸适配1.原因 iOS7中所有导航栏都为半透明,导航栏(height=44)和状态栏(height=20)不再单独占用高度,即View的(0,0)坐标是从屏幕左上角开始的;而在iOS7之前的系统中,导航栏和状态栏单独占用高度,即View的(0,0)的坐标从导航栏下面开始的。解决方案:
1& 修改window的frame坐标这个思路是在iOS7系统里面把windows下拉20个pixel,这样可以让开status bar的位置,于是一切都恢复了正常。好处是不用每个viewController来逐个修改,一般在AppDelegate.m一个文件里面修改即可。坏处是现实比想象的残酷,看起来简单方便的方法总有各种各样的问题,网上这样做的也各种吐槽,多次努力没结果后我也放弃了继续钻研。2&. 手动修改坐标这个方法对于不使用XIB文件的学院派极客是唯一的方法,也没有任何问题,就是工作量大。另外,对于使用IB来辅助做UI的应用来说就不太适合了。3& 修改Delta值作为苹果公司来说,推出iOS7时显然可以预计到这样的困境,它也确实给大家提供了解决方案。这个方案是苹果在官方文档里面介绍过的方案。首先是选择需要适配的IB文件,把Interface Builder Document里面的View as选择成iOS 6.1 and Earlier。
图片加载中...
这样在IB里面各个控件都会变成iOS6的样式,但此时在iOS7上运行系统仍然会用iOS7的控件来显示,坐标也仍然不正确——貌似一点作用都没有。恩,这只是第一步,不用急,再做一步就可以实现适配了!修改DeltaY的值,修改成什么值是根据你的实际情况定的,我这里显然就是status bar的高度,20个pixel。
图片加载中...
2.如果使用设置frame ,bounds,里面的尺寸最好使用相对坐标,因为在不同屏幕的手机,如果使用绝对的坐标,在某些手机看来,位置大小就不会那么协调,最简单的是定义一个宏,WIDTH为屏幕宽度,HEIGHT是屏幕宽度
2,IOS版本差异判断版本号,在高版本的手机上运行低版本的方法,容易过期,过期与否,看官方API使用高版本好的API,必须加上版本判断,当时低版本的手机时,应该有相应同等功能的API
一、ios7及之前版本**,universal程序准备3套资源:普清(320×480)、高清()、ipadhd()。其中,iPhone 4、iphone5、ipad普清()使用同一套资源。即背景图使用,资源图完全相同,针对ipad,使用如下代码:** if([[UIDevicecurrentDevice]userInterfaceIdiom] ==UIUserInterfaceIdiomPad) {//只针对ipad使用该资源[[CCFileUtils sharedFileUtils]setiPadSuffix:@"-hd"];//ipad使用-hd资源}
二、针对ios8的适配主要是Icon和launch image的操作。
在xcode工程中,command + N,——& iOS——》resource——》Asset Catalog。新建这样一个文件。然后,在这个新建的xcassets文件中,在其左侧栏右键,点击new app icon会产生一个APPIcon文件夹;new launch image,会新建1个LaunchImage文件夹。
这2个文件夹内就是你所需要提供的icon和launch image了。把你做好的icon和launch image放进这2个文件夹,鼠标拖曳到相应的栏位即可。
三、iphone6、iPhone6 plus的资源使用
1、iPhone6的图片资源使用同iPhone5、iPhone4,坐标调整最好使用autolayout.-hd高清资源的背景图统一调整为:,iPhone4、5、6以及非Retina的ipad都用这种尺寸的背景图。其余-hd的assets图片资源不变,继续沿用即可。
2、iPhone6 plus图片资源使用ipadhd的资源。
具体操作:(1)在CCCConfiguration.m中,找到如下方法:-(NSInteger) runningDevice。在此方法中找到这一行:ret = isiPhone5 ? CCDeviceiPhone5 : CCDeviceiP
在这一行之下,if条件之外另起一行,写入:
if ([UIScreen mainScreen].scale == 3.0f) { //iPhone6 plus的特征ret = CCDeviceiPhoneRetinaD
这几行代码可以让iPhone6 plus使用“-hd”高清资源。
(2)在appdelegate.m中,applicationdidfinishlaunching中,加入:
if (DEVICE_IS_IPHONE6Plus) {if((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) && ([CCDirector sharedDirector].contentScaleFactor == 3)){[CCDirector sharedDirector].contentScaleFactor = ([CCDirector sharedDirector].viewSizeInPixels.width/1024);
[[CCFileUtils sharedFileUtils]setiPhoneRetinaDisplaySuffix:@"-ipadhd"];//iphone6 plus使用-ipadhd资源}
(3)自行调节坐标,以适应iPhone6 plus就可以了。
四、图标icon上又出现了玻璃高光
在工程中选择包含icon和launch image的images.xcassets文件夹,选择Appicon,打开右侧边栏,勾选“iOS icon is pre-rendered”即可,如下:
图片加载中...
五、更新版本在iTunesconnect中上传截图,规格尺寸都对,就是上传失败,出现如下提示:
原因:上传的是ios模拟器自动生成的截图,截图命名中有汉字。把截图用简短的英文重命名即可。
六、上传更新版本的app出现如下问题:
图片加载中...
原因:工程中asset catalog里面,APPIcon中有个carplay图标是120×120的,这个图标不应该加上,将其删除,再次上传就ok了。
下面那个黄色警告可以无视。IOS8
此次苹果在2014 WWDC开发者大会上发布了全新一代操作系统iOS8。据了解,此次iOS8操作系统虽然和iOS7区别不打,但是苹果注重的是内在,iOS8添加了众多新功能。本文小编先为大家带来苹果iOS8全部新功能详细介绍 16大新功能。
图片加载中...
一、支持第三方输入法苹果的输入法一直被人诟病,而倒了iOS8苹果终于开放第三方输入法了。喜大普奔的更新!苹果自己的汉字输入法也加入了快速联想功能,输入更迅速。iMessage可发送语音和视频干掉微信的节奏?iMessage可以发送语音消息和视频了,而且体验与微信非常类似。二、通知中心的革新在锁屏状态下,用户可以直接回复短信。三、HealthKit健康平台第三方健康App应用可以通过过此平台来管理心率、运动、饮食等健康数据。四、Family Sharing家庭分享一个人买的应用或歌曲,可以分享最多6名亲属使用,同时它还能控制儿童购买应用。五、改进SiriSiri更加智能,并且增强了汽车内Siri语音的体验。六、针对中国的优化iOS 8针对中国市场进行了特殊优化,比如准确的中文导航和农历等。七、改进Spotlight搜索Spotlight不再只是本地搜索,可以搜索互联网内容和应用内容八、改进多任务界面多任务切换界面上方加入最近联系人九、强大的照片编辑功能Mac、iOS设备可以同步进行图片编辑,可以调整照片的曝光度、对比度、亮度等参数。更加强大十、TouchID向第三方开放第三方应用可以使用TouchID接口,意味着未来的很多应用都可以用指纹识别功能了。十一、HomeKit智能家居功能苹果向智能家居开放的API,比如未来通过这个API可以实现iPhone控制门锁,控制家庭灯光和电器开关等。十二、相机对焦时可以自由调节进光量iOS8不仅为照片的后期处理加入了强大编辑功能,内置相机同样增加了一项不可忽视的功能——自由调节进光量,在拍摄中,触摸屏幕对好焦点后,会在对焦框旁边出现进光量调节轴,能够自由增加或降低拍摄的曝光量,再也不必因为光的问题频繁找焦点测光了。十三、Safari新增DuckDuckGo搜索引擎DuckDuckGo是来自于美国的一家小型搜索引擎商,其最大的特点是严格保护用户的隐私,承诺不记录不监控用户的搜索内容,搜索内容也更加的精准。相信国内用户是不关心它的,不过有多一个好选择也不错。[4]十四、监测每款应用的耗电量iOS8还有一个隐藏较深的功能,在设置中打开电池用量菜单,用户会发现近期使用过的APP的耗电百分比都在里面,一目了然。经过这样的监测,的确是相机最耗电!十五、盲文键盘iOS8终于新增了盲文键盘。对于盲人来说,这真的是个福音,这也将会对他们的生活产生巨大影响。[4]十六、智能快捷按钮iOS8设备会根据位置,自动在锁屏界面左下角显示相关应用的快捷启动按钮。在iOS8Beta1测试版中,苹果利用iBeacon技术将基于地理位置的应用通知推送到用户iPhone或的锁屏界面上,这些通知图标位于锁屏界面左下方,用户可以按住这个小图标向上滑动解锁设备打开该应用。[5]比如当用户拿着更新至iOS8的手机到星巴克咖啡店时,星巴克的APP就会出现在锁屏的左下角(与相机快捷键相对应),用户按住它向上滑动就可以直接启动APP,与锁屏启动相机APP一致。此外,即使用户没有安装某个应用,在特定地点时,iOS 8也会向用户推荐应用,只是打开后会进入App Store应用安装界面。不过经过测试似乎该功能目前还不够完善。IOS7iOS7最大的变化莫过于UI设计,也许你会说UI设计“这是设计师大大们应该关注的事情,不关开发者的事,我们只需要替换图片就行了”。那你就错了。 UI的变化必然带来使用习惯和方式的转变,如何运用iOS7的UI,如何是自己的应用更切合新的系统,都是需要考虑的事情。另外值得注意的是,使用 iOS7 SDK(现在只有Xcode5预览版提供)打包的应用在iOS7上运行时将会自动使用iOS7的新界面,所以原有应用可能需要对新界面进行重大调整。具体 的iOS7中所使用的UI元素的人际交互界面文档,可以从这里找到(应该是需要开发者账号才能看)。ios-7-logo简单总结来说,以现在上手体验看来新的UI变化改进有如下几点:1.状态栏,导航栏和应用实际展示内容不再界限:系统自带的应用都不再区分状态栏和navigation bar,而是用统一的颜色力求简洁。这也算是一种趋势。2.BarItem的按钮全部文字化:这点做的相当坚决,所有的导航和工具条按钮都取消了拟物化,原来的文字(比如“Edit”,“Done”之类)改为了简单的文字,原来的图标(比如新建或者删除)也做了简化。3.程序打开加入了动画:从主界面到图标所在位置的一个放大,同时显示应用的载入界面。自己实验了几个现有的AppStore应用在iOS7上的运行情况:1.Pomodoro Do: 这是我自己开发的应用,运行正常,但是因为不是iOS7 SDK打包,所以在UI上使用了之前系统的,问题是导航栏Tint颜色丢失,导致很难看,需要尽快更新。2.Facebook:因为使用了图片自定义导航栏,而没有直接使用系统提供的材质,所以没什么问题。3.面包旅行:直接Crash,无法打开,原因未知。这次UI大改可以说是一次对敏捷开发的检验,原来的应用(特别是拟物化用得比较重的应用)虽然也能运行,但是很多UI自定义的地方需要更改不说,还 容易让用户产生一种“来到了另一个世界”的感觉,同时可以看到也有部分应用无法运行。而对于苹果的封闭系统和只升不降的特性,开发者以及其应用必须要尽快 适应这个新系统,这对于迭代快速,还在继续维护的应用来说会是一个机会。相信谁先能适应新的UI,谁就将在iOS7上占到先机。动态UIKit新增了UIDynamicItem委托,用来为UIView制定动态行为,当然其他任何对象都能通过实现这组接口来定义动态行为,只不过在UIKit中可 能应用最多。所谓动态行为,是指将现实世界的行为或者特性引入到UI中,比如重力等。通过实现UIDynamicItem,UIKit现在支持如下行为:
UIAttachmentBehavior 连接两个实现了UIDynamicItem的物体(以下简称动态物体),一个物体移动时,另一个跟随移动
UICollisionBehavior 指定边界,使两个动态物体可以进行碰撞
UIGravityBehavior 顾名思义,为动态物体增加重力模拟
UIPushBehavior 为动态物体施加持续的力
UISnapBehavior 为动态物体指定一个附着点,想象一下类似挂一幅画在图钉上的感觉。如果有开发游戏的童鞋可能会觉得这些很多都是做游戏时候的需求,一种box2d之类的2D物理引擎的既视感跃然而出。没错的亲,动态UI,加上之后 要介绍的Sprite Kit,极大的扩展了使用UIKit进行游戏开发的可能性。另外要注意UIDynamicItem不仅适用于UIKit,任何对象都可以实现接口来获得动 态物体的一些特性,所以说用来做一些3D的事情也不是没有可能。如果觉得Cocos2D+box2d这样的组合使用起来不方便的话,现在动态 UIKit+SpriteKit给出了新的选择。游戏方面iOS7 SDK极大加强了直接使用iOS SDK制作和分发游戏的体验,最主要的是引入了专门的游戏制作框架。Sprite Kit Framework这是个人认为iOS7 SDK最大的亮点,也是最重要的部分,iOS SDK终于有自己的精灵系统了。Sprite Kit Framework使用硬件加速的动画系统来表现2D和2.5D的游戏,它提供了制作游戏所需要的大部分的工具,包括图像渲染,动画系统,声音播放以及图 像模拟的物理引擎。可以说这个框架是iOS SDK自带了一个较完备的2D游戏引擎,力图让开发者专注于更高层的实现和内容。和大多数游戏引擎一样,Sprite Kit内的内容都按照场景(Scene)来分开组织,一个场景可以包括贴图对象,视频,形状,粒子效果甚至是CoreImage滤镜等等。相对于现有的 2D引擎来说,由于Sprite Kit是在系统层级进行的优化,渲染时间等都由框架决定,因此应该会有比较高的效率。另外,Xcode还提供了创建粒子系统和贴图Atlas的工具。使用Xcode来管理粒子效果和贴图atlas,可以迅速在Sprite Kit中反应出来。Game Controller Framework为Made-for-iPhone/iPod/iPad (MFi) game controller设计的硬件的对应的框架,可以让用户用来连接和控制专门的游戏硬件。参考WWDC 2013开场视频中开始的赛车演示。现在想到的是,也许这货不仅可以用于游戏…或者苹果之后会扩展其应用,因为使用普及率很高的iPhone作为物联网的 入口,似乎会是很有前途的事情。GameCenter改进GameCenter一直是苹果的败笔…虽然每年都在改进,但是一直没看到大的起色。今年也不例外,都是些小改动,不提也罢。多任务强化经常需要下载新内容的应用现在可以通过设置UIBackgroundModes为fetch来实现后台下载内容了,需要在AppDelegate里实现setMinimumBackgroundFetchInterval:以及application:performFetchWithCompletionHandler:来处理完成的下载,这个为后台运行代码提供了又一种选择。不过考虑到Apple如果继续严格审核的话,可能只有杂志报刊类应用能够取得这个权限吧。另外需要注意开发者仅只能指定一个最小间隔,最后下没下估计就得看系统娘的心情了。同样是后台下载,以前只能推送提醒用户进入应用下载,现在可以接到推送并在后台下载。UIBackgroundModes设为remote-notification,并实现application:didReceiveRemoteNotification:fetchCompletionHandler:为后台下载,开发者必须使用一个新的类NSURLSession,其实就是在NSURLConnection上加了个后台处理,使用类似,API十分简单,不再赘述。AirDrop这个是iOS7的重头新功能,用户可以用它来分享照片,文档,链接,或者其他数据给附近的设备。但是不需要特别的实现,被集成在了标准的 UIActivityViewController里,并没有单独的API提供。数据的话,可以通过实现UIActivityItemSource接口后 进行发送。大概苹果也不愿意看到超出他们控制的文件分享功能吧,毕竟这和iOS设计的初衷不一样。如果你不使用 UIActivityViewController的话,可能是无法在应用里实装AirDrop功能了。地图Apple在继续在地图应用上的探索,MapKit的改进也乏善可陈。我一直相信地图类应用的瓶颈一定在于数据,但是对于数据源的建立并不是一年两年能够完成的。Google在这一块凭借自己的搜索引擎有着得天独厚的优势,苹果还差的很远很远。看看有哪些新东西吧:1.MKMapCamera,可以将一个MKMapCamera对象添加到地图上,在指明位置,角度和方向后将呈现3D的样子…大概可以想象成一个数字版的Google街景..2.MKDirections 获取Apple提供的基于方向的路径,然后可以用来将路径绘制在自己的应用中。这可能对一些小的地图服务提供商产生冲击,但是还是那句话,地图是一个数据 的世界,在拥有完备数据之前,Apple不是Google的对手。这个状况至少会持续好几年(也有可能是永远)。3.MKGeodesicPolyline 创建一个随地球曲率的线,并附加到地图上,完成一些视觉效果。4.MKMapSnapshotter 使用其拍摄基于地图的照片,也许各类签到类应用会用到。5.改变了overlay物件的渲染方式。Inter-App Audio 应用间的音频AudioUnit框架中加入了在同一台设备不同应用之间发送MIDI指令和传送音频的能力。比如在一个应用中使用AudioUnit录音,然后在另一个 应用中打开以处理等。在音源应用中声明一个AURemoteIO实例来标为Inter-App可用,在目标应用中使用新的发现接口来发现并获取音频。 想法很好,也算是在应用内共享迈出了一步,不过我对现在使用AudioUnit这样的低层级框架的应用数量表示不乐观。也许今后会有一些为更高层级设计的 共享API提供给开发者使用。毕竟要从AudioUnit开始处理音频对于大多数开发者来说并不是一件很容易的事情。点对点连接 Peer-to-Peer Connectivity可以看成是AirDrop不能直接使用的补偿,代价是需要自己实现。MultipeerConnectivity框架可以用来发现和连接附近的设备,并传 输数据,而这一切并不需要有网络连接。可以看到Apple逐渐在文件共享方面一步步放开限制,但是当然所有这些都还是被限制在sandbox里的。Store Kit FrameworkStore Kit在内购方面采用了新的订单系统,这将可以实现对订单的本机验证。这是一次对应内购破解和有可能验证失败导致内购失败的更新,苹果希望藉此减少内购的 实现流程,减少出错,同时遏制内购破解泛滥。前者可能没有问题,但是后者的话,因为objc的动态特性,决定了只要有越狱存在,内购破解也是早晚的事情。 不过这一点确实方便了没有能力架设验证服务器的小开发者,这方面来说还是很好的。最后当然还有一些其他小改动,包括MessageUI里添加了附件按钮,Xcode开始支持模块了等等。完整的iOS7新特性列表可以在这里找到(暂时 应该也需要开发者账号)。最后一个好消息是,苹果放慢了废弃API的速度,这个版本并没有特别重要的API被标为Deprecated,Cheers。
*3.XCODE SDK的适配**
图片加载中...
Xcode 6 引入了设计和构建软件的崭新方式。Swift 是一种面向 Cocoa 和 Cocoa Touch 的创新编程语言,与 Xcode 工具相结合后,可以让编程变得轻松愉悦。这一生动体验渗透到了 Xcode 6 的方方面面。Interface Builder 的实时渲染功能,能将你手动编写的 UI 代码显示在设计画布中,并即时反映你在代码中输入的变化。全新的视图调试器将所有 UI 图层迸发为 3D 视觉化呈现,让你轻松了解界面的构成方式,识别重叠或截断的视图。观看“Xcode 6 的新特性”视频 SwiftXcode 6 对 Swift 有着全面深入的支持。你可以利用 100% Swift 代码创建全新的 app,或者将新的 Swift 代码或框架添加到现有的 app 中,还可查看用 Swift 和/或 Objective-C 语言编写的文档。“跳转至定义”或“快速打开”等所有常见的可供性同样适用于 Swift,甚至还可用 Swift 语法显示 Objective-C 标头定义。详细了解 Swift 编程语言 Playground尽管 Swift 编译为高度优化的原生代码,但 Playground 可以实现脚本语言的交互式体验。键入一行代码,结果便会立即显现。如果你的代码运行一个循环,可将该行代码添加到时间轴辅助编辑器中,观察其进度。以图形方式显示变量,绘制视图时检查每一个步骤,或者观看 SpriteKit 动画场景。在 Playground 中优化好代码后,即可将它移到你的项目中。Playground 文档包括你可以在 Playground 中打开的教程,其中包含可供试验的交互式工作表。 命令行Xcode 调试器包含 Swift 语言的交互式版本,它称为 REPL (Read-Eval-Print-Loop)。使用 Swift 语法来评估你的现有 app 并与之交互,或者在脚本式环境中编写新的代码。REPL 既可在 Xcode 控制台的 LLDB 中使用,也可通过“终端”调用。 实时渲染Interface Builder 现可在设计时显示你的自定义对象,就如它们在你的 app 运行时的那样。当你更新自定义视图的代码时,Interface Builder 设计画布可以自动更新为新的外观,无需执行生成和运行。你可以利用 API 添加属性到 IB 检查器中,为你的视图快速更改设计时间,甚至还可以使用示例数据预填充视图,以便对界面有更加精确的了解。 适用于 iOS 的 Storyboard 支持 UIKit 尺寸类,因此你可以开发一个可在任何 iOS 设备上正确运作的通用 Storyboard。为特定设备尺寸或方向挑选特有的行为,同时使界面的大部分元素保持一致、易于维护。Interface Builder 可以在你设计界面时预览任何设备与方向的组合。 视图调试调试 app 的 UI 现在非常简单,只需点按一下就能将暂停的 app UI 迸发为各个图层构成的 3D 渲染,并在视图堆栈中进行查看。轻松发现视图可能被截断或隐藏的原因,并在检查器中检查和调试各种限制和其他属性。若要修复问题,选择一个视图即可快速跳转到相关的代码。 Xcode 6 还包含其他新的调试工具,如用于监控 I/O 使用量的调试仪表和功能增强的 iCloud 仪表等。调试导航器甚至还能显示更多有用的信息,如记录的堆栈帧和队列中的块等。
图片加载中...
性能测试XCTest 框架现已扩展为支持性能测试,而且已完全集成到 Xcode 和 Xcode Server 中。Xcode 将运行性能测试,并让你定义基准性能标准。随后的每一项测试将比较性能,显示随时间的变化,并提醒你代码执行可能带来的性能骤降。性能测试已紧密集成到 Xcode 的全新日志 UI 中,该 UI 可以在测试结果变化时清楚地显示出来,在你监控 app 的质量时提醒你性能或功能下降。 各种工具的外观和工作方式更像是 Xcode。所记录数据的轨迹被赋予更多空间,并在统一的检查器区域中管理有关数据收集与查看方式的配置。工具甚至可以描述 XCTest。 更多功能 适用于 OS X 的 StoryboardStoryboard 现已加入到 OS X 中,其充分利用了 AppKit 中的 View Controller API。快速衔接多个视图,定义包含关系和动画,而不必编写代码。适用于 OS X 的 Storyboard 提倡使用遵循 Mac 标准的界面,以使 app 的操作方式符合用户的期望。 扩展和框架iOS 开发者现在可以创建动态框架,就如在 OS X 上一样。框架是一种代码和资源的集合,对功能进行封装,这项特性在多个项目中很有价值。框架与扩展相辅相成,两者共享的逻辑可由主 app 和捆绑扩展使用。 游戏构建Xcode 包含一个 SpriteKit 关卡设计器 SceneKit Support,支持粒子编辑器中的新特性。这让创建 iOS 版和 OS X 版游戏变得前所未有的简单。 本地化Xcode 6 中的本地化现已进行了彻底升级。基础 .strings 文件现在会从你的代码自动生成。通过 Preview Assistant 查看你的 app 在不同语言中的外观,或者使用 iOS Simulator 模拟在其他语言环境中启动你的 app。当内容准备就绪时,Xcode 可以轻松导出和导入业界通用的 .XLIFF 格式。 Xcode Server在 OS X Server 上运行的 Bot 支持的触发器可根据规则运行自定义脚本,还有更多选项可用于设置运行集成的间隔。此外,Bot 可以通过分组来共享配置。iOS Simulator 配置使得创建独特测试情景变得轻而易举,尤其是通过 Xcode Server 运行时4.UI布局方式绝对布局和相对布局纯代码和xib和storyboard
autosizing
对于IOS的app开发者来说,不会像Android开发者一样为很多的屏幕尺寸来做界面适配,因此硬编码的坐标也能工作良好,但是从设计模式上来说这不是好的做法。而且也还有一些问题,如iPhone5的适配,横竖屏的切换等。或许你可以做两套UI方案来做适配,但是这样增加重复工作量,而且不够高端,万一有出新的屏幕大小了呢。哲理就将介绍IOS中的两大自动布局利器:Autoresizing和Autolayout。 autoresizing是UIView的属性,一直都有,使用简单,但是没有autolayout强大。autolayout是IOS6以后的新技术,更加强大。本文主要介绍Autoresizing的特性和用法。
Autoresizing特性当UIView的autoresizesSubviews是YES时,(默认是YES), 那么在其中的子view会根据它自身的autoresizingMask属性来自动适应其与superView之间的位置和大小。autoresizingMask是一个枚举类型, 默认是UIViewAutoresizingNone, 也就是不会autoresize:123456789
"line-number"
"margin: 0 padding: 0"
"line-number"
"margin: 0 padding: 0"
"line-number"
"margin: 0 padding: 0"
"line-number"
"margin: 0 padding: 0"
"line-number"
"margin: 0 padding: 0"
"line-number"
"margin: 0 padding: 0"
"line-number"
"margin: 0 padding: 0"
"line-number"
"margin: 0 padding: 0"
"line-number"
"margin: 0 padding: 0"
&codeclass="objc"
typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
UIViewAutoresizingNone =0,
UIViewAutoresizingFlexibleLeftMargin =1&&0,
UIViewAutoresizingFlexibleWidth =1&&1,
UIViewAutoresizingFlexibleRightMargin =1&&2,
UIViewAutoresizingFlexibleTopMargin =1&&3,
UIViewAutoresizingFlexibleHeight =1&&4,
UIViewAutoresizingFlexibleBottomMargin =1&&5};
这个枚举类型,使用了1 && n这样的写法来定义,代表了它可以复选。如果你不明白为什么,可以复习下“位运算”。 那么这些值分别代表什么意思呢?其实如何理解这几个值很简单,那就是从xib里面看。 我们在一个xib文件中,取消勾选autolayout,(默认使用autolayout时,autoresizing看不到)。那么我们可以在布局那一栏看到如何设置autoresizing.
上图说明了在xib中设置的这些线条和实际属性对应的关系,这其中需要注意的是,其中4个margin虚线才代表设置了该值,而width和height是实线代表设置了该值,不能想当然的理解。这些项分别代表:
autoresizingMask是子视图的左、右、上、下边距以及宽度和高度相对于父视图按比例变化,例如:
UIViewAutoresizingNone 不自动调整。UIViewAutoresizingFlexibleLeftMargin 自动按比例调整与superView左边的距离,且与superView右边的距离不变。UIViewAutoresizingFlexibleRightMargin 自动按比例调整与superView的右边距离,且与superView左边的距离不变。UIViewAutoresizingFlexibleTopMargin 自动按比例调整与superView的顶部距离,且与superView底部的距离不变。UIViewAutoresizingFlexibleBottomMargin自动按比例调整与superView的底部距离,且与superView顶部的距离不变。UIViewAutoresizingFlexibleWidth自动按比例调整宽度。UIViewAutoresizingFlexibleHeight自动按比例调整高度。UILabellabel = [[UILabelalloc]initWithFrame:CGRectMake(50,100,200,40)];[labelsetAutoresizingMask:UIViewAutoresizingNone]; 控件相对于父视图坐标值不变CGRectMake(50,100,200,40)UIViewAutoresizingFlexibleWidth:控件的宽度随着父视图的宽度按比例改变 例如label宽度为 100 屏幕的宽度为320 当屏幕宽度为480时 label宽度 变为 100480/320 以上这些都较易理解, 但是autoresizing还有一些组合场景。那就是组合使用的场景。autoresizingMask说明xib预览效果
Noneview的frame不会随superview的改变而改变(右图的xib中预览效果与实际效果有差,实际效果是view的上边距不变)
TopMargin | BottomMarginview与其superView的上边距和下边距的比例维持不变
LeftMargin | RightMarginview与其superView的左边距和右边距的比例维持不变(右图的xib中预览效果与实际效果有差,实际效果是view的上边距不变)
LeftMargin | RightMargin | TopMargin | BottomMarginview与其superView的上下左右边距的比例维持不变
LeftMargin | Widthview与其superView的右边距的比例维持不变, 左边距和width按比例调整(右图的xib中预览效果与实际效果有差,实际效果是view的上边距不变)
LeftMargin | Width | RightMargin左边距、右边距、宽按比例调整,(右图的xib中预览效果与实际效果有差,实际效果是view的上边距不变)垂直方向是同样效果,故不列举
Width | Height自动调整view的宽和高,保证上下左右边距不变。如把tableView设置为此属性,那么无论viewController的view是多大,都能自动铺满
上面并未列举所有组合场景,但是已经足够我们理解autoresizing了。
小结Autoreszing的最常见的实用场景就是iPhone5的兼容了。比如我们想要设置tableView的frame,那我们只需要在初始化设置frame之后将tableView的autoresizingMask设置为UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight就行了。另一种比如我们想要一个view一直停留在其superview的最下方,那么我们在初始化设置frame之后只需要将autoresizingMask设置为UIViewAutoresizingFlexibleTopMargin就可以了。autorezingMask简单的一个属性,理解它之后可以让很多事情变得简单。AutoLayout
AutoLayout是什么?使用一句Apple的官方定义的话AutoLayout是一种基于约束的,描述性的布局系统。Auto Layout Is a Constraint-Based, Descriptive Layout System.
关键词:基于约束 - 和以往定义frame的位置和尺寸不同,AutoLayout的位置确定是以所谓相对位置的约束来定义的,比如x坐标为superView的中心,y坐标为屏幕底部上方10像素等描述性 - 约束的定义和各个view的关系使用接近自然语言或者可视化语言(稍后会提到)的方法来进行描述布局系统 - 即字面意思,用来负责界面的各个元素的位置。 总而言之,AutoLayout为开发者提供了一种不同于传统对于UI元素位置指定的布局方法。以前,不论是在IB里拖放,还是在代码中写,每个UIView都会有自己的frame属性,来定义其在当前视图中的位置和尺寸。使用AutoLayout的话,就变为了使用约束条件来定义view的位置和尺寸。这样的 最大好处是一举解决了不同分辨率和屏幕尺寸下view的适配问题,另外也简化了旋转时view的位置的定义,原来在底部之上10像素居中的view,不论在旋转屏幕或是更换设备(iPad或者iPhone5或者以后可能出现的mini iPad)的时候,始终还在底部之上10像素居中的位置,不会发生变化。总结使用约束条件来描述布局,view的frame会依据这些约束来进行计算Describe the layout with constraints, and frames are calculated automatically.
AutoLayout和Autoresizing Mask的区别Autoresizing Mask是我们的老朋友了…如果你以前一直是代码写UI的话,你肯定写过UIViewAutoresizingFlexibleWidth之类的枚举;如果你以前用IB比较多的话,一定注意到过每个view的size inspector中都有一个红色线条的Autoresizing的指示器和相应的动画缩放的示意图,这就是Autoresizing Mask。在iOS6之前,关于屏幕旋转的适配和iPhone,iPad屏幕的自动适配,基本都是由Autoresizing Mask来完成的。但是随着大家对iOS app的要求越来越高,以及已经以及今后可能出现的多种屏幕和分辨率的设备来说,Autoresizing Mask显得有些落伍和迟钝了。AutoLayout可以完成所有原来Autoresizing Mask能完成的工作,同时还能够胜任一些原来无法完成的任务,其中包括:AutoLayout可以指定任意两个view的相对位置,而不需要像Autoresizing Mask那样需要两个view在直系的view hierarchy中。AutoLayout不必须指定相等关系的约束,它可以指定非相等约束(大于或者小于等);而Autoresizing Mask所能做的布局只能是相等条件的。AutoLayout可以指定约束的优先级,计算frame时将优先按照满足优先级高的条件进行计算。 总结Autoresizing Mask是AutoLayout的子集,任何可以用Autoresizing Mask完成的工作都可以用AutoLayout完成。AutoLayout还具备一些Autoresizing Mask不具备的优良特性,以帮助我们更方便地构建界面。AutoLayout基本使用方法Interface Builder
最简单的使用方法是在IB中直接拖。在IB中任意一个view的File inspector下面,都有Use Autolayout的选择框(没有的同学可以考虑升级一下Xcode了=。=),钩上,然后按照平常那样拖控件就可以了。拖动控件后在左边的view hierarchy栏中会出现Constraints一向,其中就是所有的约束条件。
图片加载中...
选中某个约束条件后,在右边的Attributes inspector中可以更改约束的条件,距离值和优先度等:
图片加载中...
对于没有自动添加的约束,可以在IB中手动添加。选择需要添加约束的view,点击菜单的Edit-&Pin里的需要的选项,或者是点击IB主视图右下角的
图片加载中...
按钮,即可添加格外的约束条件。可视化的添加不仅很方便直观,而且基本不会出错,是优先推荐的添加约束的方式。但是有时候只靠IB是无法完成某些约束的添加的(比如跨view hierarchy的约束),有时候IB添加的约束不能满足要求,这时就需要使用约束的API进行补充。手动使用API添加约束创建iOS6中新加入了一个类:NSLayoutConstraint,一个形如这样的约束item1.attribute = multiplier ? item2.attribute + constant 对应的代码为[csharp] 1[NSLayoutConstraintconstraintWithItem:button2attribute:NSLayoutAttributeBottom3relatedBy:NSLayoutRelationEqual4toItem:superview5attribute:NSLayoutAttributeBottom6multiplier:1.07constant:-padding]
这对应的约束是“button的底部(y) = superview的底部 -10”。在创建约束之后,需要将其添加到作用的view上。UIView(当然NSView也一样)加入了一个新的实例方法: -(void)addConstraint:(NSLayoutConstraint ) 用来将约束添加到view。在添加时唯一要注意的是添加的目标view要遵循以下规则:对于两个同层级view之间的约束关系,添加到他们的父view上
图片加载中...
对于两个不同层级view之间的约束关系,添加到他们最近的共同父view上
图片加载中...
对于有层次关系的两个view之间的约束关系,添加到层次较高的父view上
图片加载中...
刷新可以通过-setNeedsUpdateConstraints和-layoutIfNeeded两个方法来刷新约束的改变,使UIView重新布局。这和CoreGraphic的-setNeedsDisplay一套东西是一样的~Visual Format Language 可视格式语言UIKit团队这次相当有爱,估计他们自己也觉得新加约束的API名字太长了,因此他们发明了一种新的方式来描述约束条件,十分有趣。这种语言是对视觉描述的一种抽象,大概过程看起来是这样的:accept按钮在cancel按钮右侧默认间距处
图片加载中...
图片加载中...
图片加载中...
最后使用VFL(Visual Format Language)描述变成这样:*[csharp]** 1[NSLayoutConstraintconstraintsWithVisualFormat:@\"[cancelButton]-[acceptButton]\"2options:03metrics:nil4views:viewsDictionary];
其中viewsDictionary是绑定了view的名字和对象的字典,对于这个例子可以用以下方法得到对应的字典:[csharp] 1UIButtoncancelButton=...2UIButtonacceptButton=...3viewsDictionary=NSDictionaryOfVariableBindings(cancelButton,acceptButton);
生成的字典为当然,不嫌累的话自己手写也未尝不可。现在字典啊数组啊写法相对简化了很多了,因此也不复杂。关于Objective-C的新语法,可以参考我之前的一篇WWDC 2012笔记:。在view名字后面添加括号以及连接处的数字可以赋予表达式更多意义,以下进行一些举例: [cancelButton(72)]-12-[acceptButton(50)] 取消按钮宽72point,accept按钮宽50point,它们之间间距12point [wideView(&=60@700)] wideView宽度大于等于60point,该约束条件优先级为700(优先级最大值为1000,优先级越高的约束越先被满足) V:[redBox][yellowBox(==redBox)] 竖直布局,先是一个redBox,其下方紧接一个宽度等于redBox宽度的yellowBox H:|-[Find]-[FindNext]-[FindField(&=20)]-| 水平布局,Find距离父view左边缘默认间隔宽度,之后是FindNext距离Find间隔默认宽度;再之后是宽度不小于20的FindField,它和FindNext以及父view右边缘的间距都是默认宽度。(竖线'|‘ 表示superview的边缘)容易出现的错误因为涉及约束问题,因此约束模型下的所有可能出现的问题这里都会出现,具体来说包括两种:Ambiguous Layout 布局不能确定Unsatisfiable Constraints 无法满足约束 布局不能确定指的是给出的约束条件无法唯一确定一种布局,也即约束条件不足,无法得到唯一的布局结果。这种情况一般添加一些必要的约束或者调整优先级可以解决。无法满足约束的问题来源是有约束条件互相冲突,因此无法同时满足,需要删掉一些约束。两种错误在出现时均会导致布局的不稳定和错误,Ambiguous可以被容忍并且选择一种可行布局呈现在UI上,Unsatisfiable的话会无法得到UI布局并报错。对于不能确定的布局,可以通过调试时暂停程序,在debugger中输入
po [[UIWindow keyWindow] _autolayoutTrace] 来检查是否存在Ambiguous Layout以及存在的位置,来帮助添加条件。另外还有一些检查方法,来查看view的约束和约束状态:[view constraintsAffectingLayoutForOrientation/Axis: NSLayoutConstraintOrientationHorizontal/Vertical][view hasAmbiguousLayout] [view exerciseAmbiguityInLayout]布局动画动画是UI体验的重要部分,更改布局以后的动画也非常关键。说到动画,Core Animation又立功了..自从CA出现以后,所有的动画效果都非常cheap,在auto layout中情况也和collection view里一样,很简单(可以参考 ),只需要把layoutIfNeeded放到animation block中即可~[csharp] 1[UIViewanimateWithDuration:0.5animations:^{2[viewlayoutIfNeeded];3}];
SizeClassSize Classes是什么iOS 8在应用界面的可视化设计上添加了一个新的特性-Size Classes,对于任何设备来说,界面的宽度和高度都只分为两种描述:正常和紧凑。这样开发者便可以无视设备具体的尺寸,而是对这两类和它们的组合进行适配。这样不论在设计时还是代码上,我们都可以不再受限于具体的尺寸,而是变成遵循尺寸的视觉感官来进行适配。在Xcode中的具体体现如下图:
但是我们看到图中的宽度和高度都是Any,Any是什么意思呢?如果weight设为Any,height设置为Regular,那么在该状态下的界面元素在只要height为Regular,无论weight是Regular还是Compact的状态中都会存在。这种关系应该叫做继承关系,具体的四种界面描述与可继承的界面描述如下:w:Compact h:Compact 继承 (w:Any h:Compact,w:Compact h:Any,w:Any h:Any)w:Regular h:Compact 继承 (w:Any h:Compact,w:Regular h:Any,w:Any h:Any)w:Compact h:Regular 继承 (w:Any h:Regular,w:Compact h:Any,w:Any h:Any)w:Regular h:Regular 继承 (w:Any h:Regular,w:Regular h:Any,w:Any h:Any)我们知道了iOS 8下面设备界面可以描述为4种,但是这么多设备(iPhone4S,iPhone5/5s,iPhone6,iPhone6 Plus,iPad,Apple Watch)具体对应什么描述呢?经过查看官方文档和具体实践得知具体对应关系如下:iPhone4S,iPhone5/5s,iPhone6竖屏:(w:Compact h:Regular)横屏:(w:Compact h:Compact)iPhone6 Plus竖屏:(w:Compact h:Regular)横屏:(w:Regular h:Compact)iPad竖屏:(w:Regular h:Regular)横屏:(w:Regular h:Regular)Apple Watch(猜测)竖屏:(w:Compact h:Compact)横屏:(w:Compact h:Compact)Size Classes手写代码为了表征Size Classes,Apple在iOS8中引入了一个新的类,UITraitCollection。这个类封装了像水平和竖直方向的Size Class等信息。iOS8的UIKit中大多数UI的基础类(包括UIScreen,UIWindow,UIViewController和UIView)都实现了UITraitEnvironment这个接口,通过其中的traitCollection这个属性,我们可以拿到对应的UITraitCollection对象,从而得知当前的Size Class,并进一步确定界面的布局。和UIKit中的响应者链正好相反,traitCollection将会在view hierarchy中自上而下地进行传递。对于没有指定traitCollection的UI部件,将使用其父节点的traitCollection。这在布局包含childViewController的界面的时候会相当有用。在UITraitEnvironment这个接口中另一个非常有用的是-traitCollectionDidChange:。在traitCollection发生变化时,这个方法将被调用。在实际操作时,我们往往会在ViewController中重写-traitCollectionDidChange:或者-willTransitionToTraitCollection:withTransitionCoordinator:方法(对于ViewController来说的话,后者也许是更好的选择,因为提供了转场上下文方便进行动画;但是对于普通的View来说就只有前面一个方法了),然后在其中对当前的traitCollection进行判断,并进行重新布局以及动画。代码看起来大概会是这个样子:123456789101112131415
123456789101112131415
- (void)willTransitionToTraitCollection:(UITraitCollection *)newCollection
withTransitionCoordinator:(id &uiviewcontrollertransitioncoordinator&)coordinator
[superwillTransitionToTraitCollection:newCollection
withTransitionCoordinator:coordinator];
[coordinator animateAlongsideTransition:^(id &uiviewcontrollertransitioncoordinatorcontext& context)
if(newCollection.verticalSizeClass == UIUserInterfaceSizeClassCompact) {
//To Do: modify something for compact vertical size
//To Do: modify something for other vertical size
[self.view setNeedsLayout];
} completion:nil];
}&/uiviewcontrollertransitioncoordinatorcontext&&/uiviewcontrollertransitioncoordinator&
在两个To Do处,我们要手写代码针对不同的状态做调整。Size Classes与Interface BuilderXcode6中Interface Builder对Size Class有了很强大的支持,xib中可以开启Size Classes如下图:
在不同的Size Classes描述下,界面元素可以选择安装还是不安装,具体操作如图:
Size Classes与Image AssetXcode6中Image Asset也支持了Size Class,也就是说,我们可以对不同的Size Class指定不同的图片了。在Image Asset的编辑面板中选择某张图片,Inspector里现在多了一个Width和Height的组合,添加我们需要对应的Size Class,然后把合适的图拖上去,这样在运行时SDK就将从中挑选对应的Size的图进行替换了。支持Size Class的Image Asset编辑效果如下:
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
被以下专题收入,发现更多相似内容:
我的苹果开发之路
· 71人关注
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
选择支付方式:

我要回帖

更多关于 遇见你之后都是好时光 的文章

 

随机推荐