Tag: swift

Swift:基于UIStackView的网格布局

我们的目标是获得具有可变单元格数量的可重用网格组件。 让我们为网格准备一个容器。 请注意,此实现不支持滚动,要启用垂直滚动,您将需要使用UIScrollView包装网格。 为了让我们的网格动态调整大小,我们需要跟踪其中的当前单元格数量。 我们还需要知道一行可以包含多少个单元(一行的大小)以及网格单元的高度。 每当当前行超过其大小时,我们都将开始一个新行。 让我们看一下prepareRow()函数。 网格中的每一行都由一个水平的堆栈视图表示,并且由于我们希望所有像元具有相同的宽度,因此分配模式设置为fillEqually 。 为了向网格中添加新的单元格,我们将使用一个实例函数(我们也可以将一个单元格数组传递给GridComponent ”函数,这将是一种更美观的方法,但是在此实现中将省略它)。 我们的GridComponent几乎准备就绪。 但是我们仍然需要解决一个小问题。 我们在这里使用的水平堆栈视图具有fillEqually分布模式,并且如果最后一行中的单元格数量小于行的大小,则最后一行中的单元格将以不同的方式分布。 一种解决方案是使用伪造的单元格填充最后一行。 我们可以使用一个简单的UIView ,但是如果需要的话,我将创建FakeCell类来区分假单元格和网格中的实际单元格。 addCell函数的最终实现将如下所示: 现在我们完成了。 但是对于具有大量单元格的网格,我仍然建议使用UICollectionView来提高性能。 感谢您的阅读,如果您发现这篇文章对您有帮助,请别忘了鼓掌!

简介:ARC和弱引用/无引用与强引用

在Swift编程中,您可能已经看到一些带有“强”或“弱”引用的变量,例如: 事实证明,“强”,“弱”和“无主”是与内存管理相关的参考。 让我们进一步研究。 Swift和Objective-C具有管理应用程序内存的便捷方法: ARC (自动引用计数) 。 自2011年Apple在2011年WWDC上推出ARC以来,iOS开发人员就可以使用ARC。 在过去的日子里,程序员必须使用一种称为MMR(手动零售发行版)的内存管理方法,开发人员必须为每个创建的对象声明一个对象要保留在内存中,然后在不需要该对象时将其释放不再。 ARC做什么? 使用ARC,编译器会为类的每个实例分配一块内存。 这块内存保存与该实例的类型有关的信息以及与该实例关联的属性中存储的所有值 。 在实例化对象时,ARC会增加对该对象的引用数。 塔可类{ var order:命令? } 类Order { var taco:塔可? } var taco1 = TacoClass()// TacoClass的实例 var taco2 = taco1 // TacoClass的第二个实例 //在这里,我们实例化一个TacoClass并创建另一个引用。 //内存现在可以识别2个TacoClass 实例 。 随着时间的流逝,删除引用后,计数将减少(请参见下文)。 为避免崩溃, 只要 一个活动引用仍然存在,ARC就不会取消分配实例。 一旦引用计数达到零 ,ARC就会从内存中取消分配实例。 ARC如何做到这一点呢? Apple文档说: 为做到这一点,每当您将 类实例 分配给 属性,常量或变量时,该属性,常量或变量都会 强烈引用 该实例。 引用被称为“强引用”,因为它在该实例上保持坚挺,并且 只要该强引用仍然存在 , […]

在操场上学习认知服务

就像你们大多数人一样,自从我上学初期就喜欢编码。 那时我还不知道在计算机屏幕上移动海龟*并用它绘制东西实际上是在编码。 但这是! 随着时间的流逝,关于我们的编码方式,必须处理的复杂性级别以及最重要的事情,很多事情都发生了变化和改进:最重要的事情是:我们如何学习编码以及如何教别人这样做。 作为技术传播者,我必须紧跟技术潮流,学习新事物,以便能够与现有技术人员分享这些技术–是的,要教他们这些新技术。 因此,学与教是我日常工作中非常基本的原则。 我个人一直在寻找方法,工具和方法来更有效地完成这项工作。 由于我们能够为计算机创建内容,应用程序和功能,因此我们可以随身携带,我对应用程序编码着迷。 在2008年发布第一个SDK时,我的工作重点几乎一直局限于iOS平台。 用简单的工具创建令人敬畏的东西。 对于像我这样总是寻求摆脱复杂性的人们来说,这是一件令人愉快的事情! 🙂 因此,我们谈到了学习,教学和编码平台。 这与操场上的认知服务有什么关系? 今年夏天,iOS在iPad上增加了一个名为“ Swift Playgrounds”的应用程序。 使用此应用程序,用户可以直接在iPad上使用所有iOS板载工具在Swift中进行编码。 作为开发人员,我们可以为此Swift Playgrounds应用生成内容,以教他们如何编码和使用某些技术。 这就是我想到的想法,即为“ Swift Playgrounds”应用程序创建内容,以教人们如何使用认知服务。 直接在iPad上,您无需编写任何代码即可开始使用Vision API(计算机视觉,情感和面部),而作为开发人员,您可以深入了解并探索如何使用API在自己的应用中 作为初稿,我创建了一个运动场和一个运动场书(为您提供了更多的编辑自由,但又增加了复杂性),以使您初步了解CognitveServices的工作方式以及在自己的应用程序中使用它们的难易程度。 可以在我的GitHub存储库中找到所有与代码相关的内容-与我的slidedeck并排放置。 https://github.com/codePrincess/playgrounds 这样,对于使用新技术“玩弄”以学习如何使用的反馈非常好。 我最近在两个事件中谈到了这个问题,希望还会有更多事件🙂 SwiftConf在科隆 https://swiftconf.com/ https://www.youtube.com/watch?v=O5u3hVu3R7c 慕尼黑TechFest Hackathon http://www.techfestmunich.com/ 因此,随时可以进入游乐场! 我很高兴听到您对此有什么印象和经历🙂 继续编码! *对于那些至今未遇见“乌龟”的人,https://en.wikipedia.org/wiki/Turtle_graphic

(iOS)人机界面指南_系统功能

AR(增强现实) Apple(R)发行人ARKit(Apple)的产品套件。 AR앱에서세계를세계를3차원상로로로브형식을이브형식을보브형식을다。 下载있으며있으며있으며있으며있으며있으며。。。 2.多任务 iOS上的iPad上的iPad上的产品在iPad上的下载量也将增加。 ,제든지중단로있으므로,정한정한다。다。다 。다다표시한다。 双高状态栏(이중이상태)작동하는지작동하는다。 。다른시스오디오로있다있다있다。 。다。 앱이중지실행되실행되실행되실행되알림을사용하도록다。 3.通知 도착능으능으능으메세메세메세도착도착도착를를정정정를를정를든를든있다 사잠금화면이나기기를사아래아래로스아래이프하여있다。 4.印刷 AirPrint发布文档,PDF格式的文档,PDF格式的文档,以及PDF格式的文档。 5.快速浏览 Look快速查看란主题演讲,数字,页面및PDF문서아니라이아니라지나기타미리해주는기해주는다。 邮件앱에서는지메세이콘과이름을다。 。이콘을미리보기가표시됩니다。 보리보기보를다。 6,评分和评论 。리뷰는사뷰는지말지결정하는데에이됩니다。 。이많뷰는됩니됩니됩니됩니됩니됩니됩니됩니됩니됩니됩니됩니됩니됩니됩니됩니됩니됩니됩니됩니이 사용자가사물어본물어본다。 。스트레스가용자를수행할방해하지않는다。 。가평사용자의사부정적인다있。 최소1〜2주정도의기간을다。 시스템의가평로영향으좋좋좋좋좋좋좋좋좋좋좋좋좋 7.屏幕截图 사있스크린。있있다。 iOS 11上的所有功能。 용자긱긱긱긱긱긱긱긱긱긱긱다。있다 스크린저장된다。 8. Siri Siri的照片,Siri的照片,Siri的照片,Siri的照片,Siri的照片,Siri的照片,Siri的照片,Siri的照片,Siri的照片,Siri的照片,Siri的照片,Siri的照片。 。지만이없이음성만을기위해다。 Siri모방하거나조작하지않는다。 환경에서는Siri환경에서는,마케팅이내용다。 9.电视提供商 앱을앱앱인온사싱글(SSO)하고람들에게하고하고하고있하고있다있다 싱글사인온(SSO):통합인증싱글인온인온한한한한한한들을들을들을들을들을템템템템템템템템템템템템템。 링크링크: https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/adaptivity-and-layout/ [애플문서] https://zetawiki.com/wiki/%EC%8B%B1%EA%B8%80%EC%82%AC%EC%9D%B8%EC%98%A8_SSO [제타]

使用普通Vanilla Swift消费JSON

在设计Web API时,传输介质与API的结构同样重要。 您可以使用XML,JSON,或者如果您穿的是大童裤,则可以使用SOAP。 首选使用JSON,因为它占用空间小,并且可以轻松映射到模型类。 在本文中,我们将探讨不使用任何JSON解析库而使用 JSON响应的不同方法。 让我们从简单而可爱的东西开始! 什么是简单可爱? 宠物小精灵! 我非常喜欢Pokemon,以至于我在Vapor中创建了服务器端Swift API,该API返回了Pokemons的数组。 您可以使用此链接签出API。 计划香草词典: 在第一种方法中,我们将以字典数组的形式使用JSON。 我们使用JSONSerialization类将返回的数据转换为适当的数据结构。 由于我们的JSON API返回了一个字典数组,我们使用[[String:Any]]作为目标数据结构类型。 使用字典的主要问题是键为字符串格式,并且可能会拼写错误。 另一个问题是,如果您使用密钥100个位置,然后又更改了密钥,则必须在所有这100个位置中更新密钥。 解决方案是使用可以表示JSON模型的具体类。 JSON模型类: 代替依赖于字符串键的字典,模型类是一个更好的选择,因为它们是强类型的,并且还提供了一次轻松修改属性的简便方法。 类定义如下所示: 现在,我们可以用以下代码替换字典代码: 比字典更好一点,但是现在我们的回调函数中有太多代码。 我们可以将初始化部分移到自定义Pokemon初始化程序中,如下所示: 这使我们的回调函数更加精简,如下所示: 看起来很棒! 但是我们还没有完成! for循环可以由Swift集合上可用的map或flatMap函数代替。 更好,更简洁! 我们也可以通过调用NSObject对象上可用的setValueForKeys函数来替换我们在init方法中手动执行的键-值映射部分。 由于setValuesForKeys对由Objective-C表示的类型使用键值编码,因此我们不能使用Double! 还是Double? 这就是为什么我们删除了可为空的类型,并使用一些默认值对其进行了初始化的原因。 使用setValueForKeys函数时要小心,因为找不到该键会引发异常。 如果您不受API的控制并且API的所有者以自己的格式发送回JSON,则可能是这种情况。 对于未在接收对象中找到的每个键,将触发未定义键的setValue。 嵌套的JSON: 目前,我们只研究了使用简单的JSON。 但是生活不是那么简单! 让我们看看如何使用嵌套的JSON结构。 我们将使用JSON PlaceHolder网站,该网站返回虚拟JSON数据。 您可以使用此链接查看我们将使用的JSON结构。 我们的用户JSON结构由以下子结构组成。 用户数 地址 地缘 公司 第一步是为每个结构创建自定义类,就像Pokemon初始化程序一样,创建一个将字典作为参数并填充所需属性的初始化程序。 用法如下所示: 而已! 在本文中,我们没有使用任何JSON解析库,而是依靠iOS框架中已经可用的API。 对于不返回复杂嵌套数据的简单应用程序,这很好,但是当您遇到更复杂的应用程序时,最好使用第三方库来帮助您解析JSON响应。 […]

了解Swift中的Struct

让我们快速深入了解struct struct是一种值类型 ,当将其值分配给变量或常量或将其传递给函数时,其值将被复制 。 结构必须在创建结构实例时将所有存储的属性都设置为初始值。 您可以在初始化程序中或通过分配默认值来为存储的属性设置初始值。 让我们为ecommerse网站的产品创建一个结构。 当我们复制struct时,它复制所有值类型,但它共享引用类型的引用。 如果您在上面的对象图中看到,ProductA和productB之间共享ProductFactory 结构类型的成员初始化器 所有结构都有一个自动生成的成员初始化器,您可以使用该初始化器来初始化新结构实例的成员属性。 可以通过如下名称将新实例的属性的初始值传递给成员初始化程序: 产品(标识号:1234,名称:“ Remote car”,库存:true) 产品又有一个工厂。 由于我们已经在声明时初始化了此属性,因此无需传入initializer 。 可选属性类型 可选类型的属性会自动初始化为nil值。 关于写时复制的不错的文章 内存分配: 结构将始终在堆栈中为所有值类型分配内存。 堆栈是一个简单的数据结构,具有两个操作,即Push和Pop 。 您可以通过按住指向堆栈末尾的指针来推动堆栈末尾并弹出堆栈末尾。 所有引用类型都将存储在堆中。 堆使您可以分配具有动态生命周期的内存。 它必须搜索未使用的内存块进行分配,然后重新插入内存块以进行重新分配。 因此,如果结构具有引用类型,它将具有指向该类型的指针。 结论: 我试图在此处添加有关结构值类型的所有信息,这对于我们作为开发人员来说是必需的。

小错误处理简介

我们在编写代码时都已经看到错误和警告,它们肯定会很痛苦,但要感谢它们在那里。 如果不存在,我们的应用程序将在用户面前崩溃,并且该应用程序肯定会在应用程序商店中获得不良评价。 没有人想要! 成为一名优秀的开发人员意味着您不仅可以编写代码,而且可以编写正确的无错误代码。 即使不是不可能,编写完全没有错误的代码也是非常困难的,但是我们可以采取步骤确保我们的代码包含尽可能少的错误。 此过程称为错误处理。 那么什么是错误? 错误是任何会产生不正确或意外结果或导致程序无人照管的行为的代码。 有两种不同类型的错误。 编译器错误和运行时错误。 编译器错误是快速编译器在解析或读取代码时引发的错误。 编译器错误也可以分解为域错误,但并非总是如此。 有些错误是编译器无法捕获的,只有在您击中特定代码行时才会发生。 这些是运行时错误。 运行时错误可以分解为两个。 第一个是可恢复的错误,第二个是不可恢复的错误。 根据是哪个错误,我们可以对如何处理错误做出不同的反应。 不可恢复的错误可能是由程序员错误引起的逻辑错误,也可能是我们无法预料到发生的普遍错误。 因为这两种情况都无法防范,我们通常会在这些情况下崩溃并以不同的方式处理它们。 我们将重点放在可以恢复的运行时错误上。 错误处理到底是什么? 苹果必须说的是: 错误处理是响应程序错误状态并从错误状态中恢复的过程。 从Apple文档中可以找到四种处理错误的方法。 您可以断言该错误不会发生。 您可以将错误作为可选处理。 或者,您可以使用throw在函数中传播错误。 您可以使用do-catch语句。 我们已经看到了其中的一些,但我将深入探讨最后两个。 首先,我们可以通过采用错误协议来对错误建模。 错误协议是一个空协议,但是它指示可以将类型用于错误处理。 枚举通常用于对我们的错误可能进行建模,因为我们可以在枚举中使用关联的值,这使我们更具描述性 现在,我们对错误进行了建模,可以编写函数了。 为了表明该函数可能引发错误,我们在函数本身中使用了关键字throws。 如您所见,throws关键字添加在function /方法参数之后和返回类型之前。 如果没有返回类型,则可以使用关键字throws。 现在在函数内部,我们必须使用关键字throw。 throw关键字是控制转移语句,它退出当前作用域,并且必须始终接受一个参数。 既然我们已经完成了该函数的编写,我们可以调用它,但是由于它是一个抛出函数,因此需要尝试实现。 我们在这里使用do – catch语句。 如果do子句中的代码引发错误,则将其与catch子句进行匹配,以确定其中哪一个可以处理该错误。 Do子句实质上会创建所谓的幸福之路,以确保一切成功。 这是错误处理的非常简短的介绍。 那里有很多不错的文章,但会更深入,但是我建议使用Apple文档。 编码愉快!

Swift中更好的承诺

一个简单的承诺 异步代码很常见,但是如果我们仅在一个地方添加更多的异步调用,我们将得到大量的方法和十个级别的缩进。 换句话说,我们将成功实现回调地狱。 当然,我们可以做得更好! 我们可以尝试将其拆分为几个功能……但这可能会导致其他问题…… 这种方法的缺点是很难跟踪控制流。 从方法签名来看,不清楚哪个方法被调用。 如果方法调用是实现方法职责的一部分,那么这是一件好事,但是如果它调用了流程管道中的下一个项目,那么它很快就会变成可控流地狱。 这就是为什么我们首先要有回调! 我们希望在一个地方定义高级控制流,然后将实现细节放在其他地方,并适当地封装它们。 一种可能的解决方案是使用诺言。 那么, 什么是诺言? 承诺(也称为“未来”)是指用于同步程序执行的构造。 他们描述了一个对象,该对象充当最初未知的结果的代理 ,通常是因为其值的计算尚未完成[1]。 我为什么要使用诺言? 保持代码干净和结构良好。 这是避免回调地狱和控制流地狱之类的简单选择。 我们始终希望代码缩进尽可能合理 ,而诺言是实现这一目标的好方法。 答应过地狱? 根据使用方式的不同,promise可以简化代码,但也会使代码难以理解。 在进行代码审查时,我基本上遇到了一件奇妙的事情: 相当多的工作,不是吗? 乍一看,这是有问题的,因为代码在美学上看起来并不令人满意(在我看来,这是判断代码质量的很好指标)。 不幸的是,使用promise退化为类似代码的代码并不少见。 所以有什么问题? 很难说出.then块的作用,它们可能变得非常庞大。 它也违反了单一责任原则[2],因为每个块都有单独的责任,但是它们都包含在一个方法中。 我们遇到的另一个问题是缺乏抽象层的分离。 一个方法应该只包含占据一个抽象层的代码,在我们的例子中,我们可以说有两个:1.管理过程流程的代码,以及2.构成过程步骤的实现细节。 更好的承诺 一种简单的解决方案是在每个块的开头添加注释,以描述其功能。 更好的解决方案是编写自我记录代码 ,在这种情况下,这意味着将程序包提取到单独的方法中 。 只要确保正确命名方法即可 。 而且您还需要正确命名方法(我已经说了两次,因为它很重要,以防您想知道)。 最初的问题是,我们无法轻易分辨出发生了什么,而用模糊的内容代替它并不会带来太大帮助,对吗? 即使块的内容包含很多代码,如果将其包含在方法中,它也更易于管理,并且我们还解决了抽象层问题。 答应天堂? 由于Swift函数是一流的对象,因此我们可以采取进一步的措施。 这意味着我们可以将它们传递到其他需要关闭的函数中 。 promisseHell示例将变为以下内容: 我们可以选择几种承诺库。 最受欢迎的可能是PromiseKit [3]。 就我个人而言,我更喜欢then框架[4],因为它的方法不需要标签,这使它更加简洁(即在那时我们将编写.then (handler),而在PromiseKit中将是.then (execute:handler) )。 任一种都可以,但是您将需要根据所选框架的期望编写略有不同的代码。 […]

您的(和我的)第一个带有核心动画的贝塞尔曲线

我很高兴学习Xcode中的动画。 这是我的背景,也是我的热情。 但是当我们学习UIView动画时,我非常失望。 这个过程感觉很笨拙,就像我无法在Maya或After Effects中所能控制的地方一样。 我决定学习Core Animation,这就是我要带您了解的内容。 这是一个用于bezier动画的非常简单的教程,只是让您不知所措。 什么是贝塞尔曲线? 让我们从这里开始。 在设计工作时要理解这是一个非常重要的概念。 Adobe Creative Suite会大量使用它们。 贝塞尔曲线简单且可扩展,非常适合矢量图像。 如果您使用过Illustrator或Photoshop,则可能已经看到过贝塞尔手柄: 贝塞尔曲线也是计算机动画的基础。 可以沿贝塞尔曲线移动对象。 速度图使用贝塞尔曲线手柄。 它们允许轻松控制动画流,同时仍保持事物的紧密和流畅。 但是,贝塞尔实际上是什么? 长的答案在于函数,但这不是您必须记住的东西。 我能找到的最好的视觉解释来自博客文章(如果您想深入研究贝塞尔曲线及其背后的微积分,则值得一读): 简短的答案以及您需要了解的所有内容是, 贝塞尔曲线是具有起点和终点的直线,在点之间平滑插值以创建曲线。 如何为Core Animation制作动画? 在探讨如何沿贝塞尔曲线进行动画处理之前,让我们研究一下Core Animation。 核心动画(用于与之关联的类,协议等的缩写CA)是一种基础结构,可用于为应用程序的视图和其他可视元素制作动画。 导入QuartzCore ,但是如果您已经包含在UIKit中 ,则不需要这样做,它是其中的一部分 设置要更改的视图。 我通过将变量声明为UIView并将其添加到主视图并设置其框架来以编程方式进行操作。 别忘了也给它加上背景色! 和我一起玩,变黑。 输入以下代码: 让changeColor = CABasicAnimation(keyPath:“ backgroundColor”) changeColor.fromValue = backgroundView.backgroundColor changeColor.toValue = UIColor.white.cgColor changeColor.duration = 2 backgroundView.layer.add(changeColor,forKey:“ backgroundColor”) 这里发生了什么事? 首先,将一个变量声明为CABasicAnimation(keypath […]

代理NSNotification — Desenvolvimento iOS

Qualquer desenvolvedor或iOS设备。 观察者的观点在质量上和精神上都有所不同。 代表们 委派参会人员或委派代表参加辩论。 您可以使用本机或本机,也可以使用本机。 Os代表funcionam da mesma forma,el​​es criam um link entre dois objetos enãoépreciso saber qual odepédedé,se simplesmente实现者或协议。 NS通知 作为通知(NSNotification)的比较,请在es发行后将其分发给其他人。 Ques escuta pode ignorar a mensagem ou podem fazer algo com ela。 作为通知(NSNotification)的许可,质量反馈已得到普遍存在。 Depois de uma longa busca na Internet sobre esse assunto posso dizer que na maioria dos caso o Delegate […]