Tag: 迅捷

Swift编程入门第2部分—值类型,引用类型,指针和集合类型

之前,我们讨论过变量,常量和类型。 开始Swift编程第1部分-变量,常量和类型 我知道那里有很多教程,Apple有很好的学习Swift的资源,包括他们的WWDC视频…… medium.com 在这一部分中,我们将讨论几个特殊类型,但是为了深入实现这一点,我们必须首先讨论值类型,引用类型和指针。 提醒一句,指针可能是最难掌握的概念之一,我会尽力而为。 初步的东西 是的,我们上次这样做,现在我们将再次进行。 上一次我们讨论了内存以及它如何以块,字节和位的形式排列。 我想在这里对此进行扩展,并为您提供一些有关内存工作原理的直观表示。 让我们创建一个包含值Hello的字符串。 我们之前没有做过什么特别的事情。 我在上一篇文章中告诉您,内存具有价值。 如果我们可以看一下该内存,它将像这样存储: 我敢打赌,您要问的是\0在字符串的末尾。 这称为空终止符。 斜线表示程序已准备好执行命令,零表示没有任何意义。 这是字符串值的存储方式,并在字符串允许使用空格的同时让程序知道字符串何时完成。 数字略有不同。 数字存储为二进制数字。 二进制很容易理解,从内存块最右边的1开始,向左移动,每次将当前值乘以2。 如果您对图形卡或记忆棒有所了解,这就是为什么我们会看到8位(Atari,NES),16位(Sega Genesis,SNES),32位(PlayStation),64位(Nintendo 64)和以此类推。 在二进制中,如果位置为0,则表示关闭,这是错误的。 如果位置为1,则为开或为true。 基于此逻辑,我们只需要计算位置为1的位置即可。 您能找出上图中的数字吗? 现在,这是一组8位内存,是的,它是一个完整的内存字节。 之前我说过字符串中的每个字符都是2个字节,这意味着我们使用16位来存储字符。 16位二进制文​​件的最大值为256。但是,当我们谈论位置时,我们总是从0开始。因此16位二进制数的范围是0-255 。 我敢打赌,您在问我们如何才能使字符超出此范围。 好吧,在这种情况下,我将带您到ASCII表,您可以在其中查看自己的值。 您甚至还会看到隐藏的字符,例如空终止符/0如上所示。 内存将值存储在静态内存中,该位置称为stack ,而该位置称为堆。 可以快速访问静态内存和堆栈内存,但是从堆访问内容的速度很慢(以计算机时间计)。 尽管对您来说似乎并不慢,但从堆栈加载可能要花费一毫秒或更短的时间,而从堆加载可能要花费10毫秒。 在介绍事物时,我将解释它们的实现位置,以便您以后知道将其放置在何处。 值类型 值类型很容易学习,这就是我们自然地思考事物的方式。 当您描述某些事物时,例如说一个高尔夫球,您可能会说一个高尔夫球很小,或者一个篮球是橙色。 值类型是包含您要查找的值的内存。 如果您将值8存储在内存中,然后再要求输入该值,则会收到数字8,非常简单,对吧? 字符串,整数,双精度型,浮点型和布尔型都是值类型,还有更多,但是我们还没有涉及它们,到目前为止,我所有的例子都是值类型。 值类型存储在堆栈中。 如果在它们前面添加静态元素,那么它们会添加到静态内存中,而不仅仅是在各处都这样做,这会带来另一个问题,我将在后面讨论。 参考类型和指针 引用类型在某种程度上类似于值类型,因为它们可以为您提供与值类型相同的值,但它们可以为您提供更多的价值。 引用类型使用指针为您提供所需的值。 之所以要准备这么长的篇幅,主要是因为本节有保证。 如果您看一下C和Objective-C程序,您会发现到处都使用了指针,看起来像这样 集合类型 继续本部分的最后一部分。 […]

使用IOS动画中的约束…

在制作子视图动画时,通常使用该子视图的约束来更改其位置或值。 基本上,“动画”定义为值或位置的变化。 IOS中的每个视图都包含一个称为“ constraints ”的属性,该属性仅是get,它给出了该视图所持有的所有约束。约束由最近的视图持有,该视图包含约束中的两个项目。 子视图之间/之间连接的约束通常由其超级视图持有。 视图所包含的所有约束均在大小检查器中列出。 子视图与其父视图之间的约束由其父视图保持。 因此,在使用约束进行动画处理时,首先我们需要找到哪种视图持有我们要设置动画的约束。 对于动画,意味着更改约束或其乘数/常量值,首先我们需要获取所有现有约束。 通过依赖约束,选择包含所需约束的视图。 要获取约束,我们可以使用仅获取属性“ constraints”,它提供了一系列约束。 为了获得每个约束,我们可以遍历结果数组。 注意:像“约束”属性一样,乘数也是“仅获取”值。 就像我们为现有约束更改常量值一样,我们无法更改乘数值。 因此,要更改乘数值,我们需要访问该约束,使其为“ .active = false”。 通过将其激活设置为false,在下一个布局更新中,自动布局引擎将删除该约束。 因此,在定义新约束之后,将其设置为“ .active = true”。 2.我们可以在定义约束的同时为约束赋予标识符。 稍后,我们可以使用“ constraints”属性来获取约束,然后可以通过使用其标识符值来访问所需的约束。 3.我们还可以定义两个具有两个不同值,具有不同标识符和优先级的约束。 但是在任何给定时间都应该只有一个处于活动状态。 因此,从已定义的这两个约束中,将其卸载。 然后,您可以根据需要通过访问这些变量来随时激活一个。

如何在Swift 3中使用动画制作自定义AlertView / DialogBox

尽管我们有UIAlertViewController来显示警报,但是我们没有足够的灵活性来进行自定义。 因此,在这里,我正在编写另一个教程,介绍如何根据需要使自己拥有AlertView / DialogBox。 在本教程中,我们将制作一个简单的AlertView,其中将包含标题和图像,但是您可以使用此方法实现任何复杂的设计。 如果可以想象,就可以做到。 👍 让我们开始吧… 我创建了一个名为Modal的简单协议,该协议可帮助您显示/关闭自定义AlertView / DialogBox。 您可以使用动画值来满足您的要求。 首先将该文件添加到您的项目中。 在将Modal Protocol添加到项目中之后,创建一个新的Swift文件,并为其指定任何名称。 我将其命名为CustomAlertView 。 现在,创建一个名为CustomAlertView的类,并将其作为UIView的子类。 导入UIKit 类CustomAlertView:UIView { } 现在,确认Modal协议并实施所需的变量。 类CustomAlertView:UIView,模态{ var backgroundView = UIView() var dialogView = UIView() } 我们将需要创建自己的初始化程序,以使用标题和图像初始化CustomAlertView ,因此,让我们创建一个将使用Title和Image的初始化程序。 如果要创建自己的初始化程序,则还需要实现所需的 init?(编码器aDecoder:NSCoder)并覆盖 init(frame:CGRect) 。 您还需要从初始值设定项中调用其指定的初始值设定项。 因此,我们通过提供主屏幕边界来调用init(frame:CGRect) ,这将使我们的CustomAlertView覆盖整个屏幕。 如果您想了解有关初始化器的更多信息,请转到此链接 。 便利init(title:String,image:UIImage){ self.init(框架:UIScreen.main.bounds) } 覆盖init(frame:CGRect){ super.init(frame:框架) } 需要初始化吗?(编码器aDecoder:NSCoder){ fatalError(“ init(coder :)尚未实现”) } […]

Swift Auto布局示例

这是一个简单的示例,它无需任何代码即可通过Xcode swift3为iOS应用构建简单的个人资料场景,下面的图片是您可以达到的目标。 我们可以看到那些文本字段的前导在同一垂直线上,其他标签也都在同一行,所以我首先确定顶部项目的位置Y 然后,我为这些文本字段和标签设置了主要约束 现在,我设置上下两个拖曳物品之间的距离,但没有设置绝对位置,因为如果有一天我需要移动这些物品,我要做的就是移动最上面的物品,而那些较低的物品将自动跟随移动。 现在让我们转到按钮,我使左按钮以0常数尾随左边距到0常数的conter X处,而右按钮以0常数尾随X到达中心X,并以0常数尾随右边距。 希望这种简单的Xcode自动布局可以帮助刚开始学习快速语言并在简单插入场景中工作的人员,希望大家喜欢它。

项目6.7 –笔记薄弱的一周

沉默接管了项目6。6.3和6.4是周末在电脑上度过的时间,由于缺乏进度,6.5和6.6被迫放弃了说话。 将我们最终安静地带到6.7-6周计划的一个星期。 我一直在研究可可,NS前缀和苹果不太喜欢的开发套件的来龙去脉。 我的意思是没有冒犯,Mac应用程序可以很漂亮而且令人惊叹,只需询问Panic,但是您只能看到很多次 不会因CocoaTouch的普遍存在而感到孤独。 凭借多年的Apple开发人员经验,我觉得自己的工作效率只有一半。 每个Autolayout错误,以及解决了您从2002年以来的问题的方法的文章都不再起作用,并且坐标系的完全怪异意味着调试和测试比运送要花费更多的时间。 一个例子就是希望在NSTextView中找到光标的位置。 经过大量的UITextView答案,我找到了可能的解决方案。 textView.firstRect(forCharacterRange:,actualRange:) 这是为了给我当前选定范围内光标位置的NsRect。 只要您喜欢绝对的屏幕坐标,一切都会很好,但是对我来说完全没用。 该兔子洞进展为尝试使用以下命令将窗口坐标映射到文本视图的原点 [textView convertRect:rect fromView:textView.textInputView] 但是由于某种原因,textView的原点返回0,0,并且每个Stack Overflow都带来了比以前更多的问题。 最后,我浏览了足够多的NSContainers和NSLayoutManager文档,以偶然发现圣杯 让cursorPoint = textView.layoutManager?.boundingRect(forGlyphRange:textView.selectedRange(),在:textView.textContainer!) 最后,我兴高采烈地出现了,只花了一个小时就在光标位置插入了一个子视图。 (#ForFutureGoogle在NSTextView中找到光标/插入符号的局部坐标)。 然后,此模式进行多次自我复制,分为多个Objective-C至Swift复制粘贴重构以及Swift 2至Swift 3弃用路径。 我喜欢Swift作为一种语言,在搜索iOS解决方案时并没有这么大的问题,所以我的猜测是iOS内容更新速度更快并且紧贴前沿,或者iOS内容庞大而过时搜索。 就是说,总共大约20个小时之后,我已经成功地使用本地数据库,一个很酷的Medium风格的插入菜单和Operational Transformations构建了一个本地Notes应用程序。 回想起来,也许启动了一个未知数众多的项目,尤其是在第一周就显得有些雄心勃勃。 此外,我希望在该应用程序上花费总计超过20个小时,因此我认为最终产品将更加精美。 此外,我花了几个小时将一些逻辑提取到一个单独的库中,以用于业务逻辑/操作转换逻辑(以防我想创建一个iOS应用程序)和另一个库,用于包装类来处理中型TextView。 尽管如此,到最后,我还是学到了很多新的Cocoa开发人员,对任何Mac App开发人员都产生了新的尊重,并非常喜欢这个项目。 下一步? 我想花更多时间将应用程序完善成可用的工具,也许还要研究一下iOS应用程序和CloudKit的集成。 长期-如果我无法或不会支持我,我可能会愿意公开采购整个应用程序或库组件。 如果有人对应用程序感兴趣,或者代码可以随时与我们联系,那肯定会帮助我评估这些选项。 今天花费的时间:4小时 总开发时间:〜20小时 结果:工作记录应用 任务完成1/6 还是足够接近

在Perfect 2.0样板应用程序(PerfectTemplate)中重构路线

我在网上看到的所有示例在路由和处理请求时都具有相同的样板结构,看起来有点像这样 导入PerfectLib 导入PerfectHTTP 导入PerfectHTTPServer //创建HTTP服务器。 让服务器= HTTPServer() //注册自己的路由和处理程序 var route = Routes() route.add(方法:.get,uri:“ /”,处理程序:{ 请求,回应 response.setHeader(.contentType,值:“ text / html”) response.appendBody(string:“ 你好,世界! 你好,世界! ”) response.completed() } ) //将路由添加到服务器。 server.addRoutes(路线) … 并继续进行服务器设置,配置和启动顺序的设置。 我目前是一名PHP开发人员,试图切换到Swift进行后端开发,并且在同一文件中包含路由,闭包和可能的业务逻辑有点不安。 修复非常容易,我决定共享它,以防万一其他人遇到相同的问题,所以让我们开始编码吧…… 提取路线 首先创建一个新文件,将其命名为AppRoutes.swift ,并将其放置在与main.swift和arguments.swift相同的位置。 打开新文件后,将目标会员身份更改为仅检查您的应用-应该看起来像这样…… 接下来,我们将删除导入Foundation行,并添加自己的导入PerfectHTTP并将路由位从main.swift提取到一个函数中,我们将其称为setupAppRoutes 。 代码现在应该看起来像这样…… 导入PerfectHTTP func setupAppRoutes()->路由{ var route = Routes() route.add(方法:.get,uri:“ /”,处理程序:{ 请求,回应 response.setHeader(.contentType,值:“ text / html”) response.appendBody(string:“ 你好,世界! […]

让我们每周一次洗牌

在Flatiron学校的第一周,他们给了我们二十一点实验室一个工作。 我慢慢地开始逐步研究它。 我创建了卡片,播放器,卡片组,引擎,并设置了所有实例,方法,初始化程序等。一切都以正常且良好的速度向前发展,直到实验室指示要求我对卡片组进行洗牌。 说明: 我的第一个想法是“这很容易。 因此,我开始在arc4random_uniform()周围键入各种不同的变体,但似乎无济于事。 在花了很多时间尝试解决这个问题之后,我决定发挥创造力,并提出了自己的解决方案,我将其称为“弗兰克·辛纳屈”。 第一周:弗兰克·辛纳屈 开始了。 让我们将其分为几步: 我们的任务是创建shuffle()方法,以获取包含52张随机洗牌的卡组。 这时的牌组“ undealtCards”是一副纸牌,看起来像这样: 我的第一个想法是创建一个名为“ cardsToShuffle ”的纸牌阵列,并确保我名为“ undealtCards ”(我的副牌)和“ DealtCards ”(另一副装有发牌的牌)的两个阵列是空的。 然后,我用一个for循环填充我的arraycardToShuffle阵列,使我的Card类中的所有西服和等级符合我的52张牌。 此时,问题是我有一副纸牌,但它们又重新排列好了,没有被洗掉。 最后一部分是创建一个新的for循环,在该循环中,我们以随机顺序将所有Cards从cardsToShuffle移至undealCards 。 并做了! 我们设法洗牌了。 如果一切顺利,我们应该有两个空数组( cardsToShuffle和DealtCards )来启动, undealtCards应该有52个Card元素被改组。 我不得不说,我为自己感到非常自豪。 尽管现在看来这很容易,但是在第一周想出这个解决方案对我来说感觉非常好,我做到了。 第二周:印第安纳·琼斯 一周后,当我们回顾二十一点实验室的工作时,一位同学(@ramamilaneha)向我展示了一种改组甲板的更好方法。 我们将其称为“印第安纳琼斯”。 解决方法如下: 我们将创建一个for循环,该循环将从0到几乎undealtCards计数运行。 然后,我们将使用arc4random方法获得randomIndex。 然后我们验证i值是否与randomIndex不同,并以良好的“ Indiana Jones”风格交换了每个元素的顺序 第三周:魔术技巧 然后,在熨斗学校的第三周开始了,随之而来的是更多的实验室。 我认为经过一两个实验室之后,我们又不得不改组阵列。 老实说,我回到了最初的“ Frank Sinatra”解决方案,因为那时我还不太了解“ Indiana Jones”的方式。 我输入了整个解决方案,几分钟后,我决定必须有一个更好的方法。 我用谷歌搜索,直到找到第三个最好的解决方案“魔术”。 这是逐步的: 带来GameKit框架。 现在,我们可以使用GameKit框架中的GKRandomSource类来创建新的纸牌阵列。 然后我们可以调用实例方法“ […]

迅捷阿尔卑斯山背后的概念

如网站上所述,斯威夫特阿尔卑斯山是一个实验性会议。 问题是:为什么? 在会议空间进行实验的原因是什么? 我写这篇文章的目的是澄清所有内容。 动机 在会议空间尝试新事物的原因很多,其中一些原因是演讲者和与会者所面临的问题 在每项事件中: 回到常规 会议结束后,回到办公室,解雇代码编辑器,尝试一些新的东西,然后……一个星期后就忘了这是很常见的。 上一次活动中刚刚学到的所有新技巧已经完全消失了。 有时也可能发生,与同事一起我们可以尝试更长的时间,但是通常只有一个想法被采纳,而忘记了会议中其他N件事。 试验和失败是我们日常工作的一部分,有时我们有零时间,有时我们还有更多时间,但是试验是采用的第一步 ,在定期会议中很难做到。 合作 我们通常只与我们的同事合作,很少与我们在一个开源项目中不认识的人合作,但是,大多数情况下,我们和代码才是我们的合作伙伴。 在经典的会议中,屏幕上的代码最初看起来很有趣,但是在谈话结束后,就不太可能记住它以备后用。 再次,会议的凉爽性几乎被人们忘记了。 社会化 社交是会议的重要组成部分,对于某些人来说,社交是参加会议的主要原因,但是社交的机会仅限于休息和聚会后。 我从来没见过有人在舞台上演讲时发起随机聊天, 这通常是很不礼貌的 。 我还从未看到过,有几个参与者在屏幕前社交,谈论一段代码,考虑到我们每天在屏幕前花费6-8个小时的工作时间,这听起来很奇怪。 学习 学习是一个复杂的过程,我们在学习某些东西时会走很多步。 当前的会议模型使学习变得困难,在舞台上倾听他人的声音 这是一个很小的步骤,因为结果通常会像“我刚刚意识到一些很棒的事情”那样继续进行,而前面还有很多步骤,但是……我们如何学习一些东西? 在尝试时通常会失败。 失败是我们日常工作的一部分,我们:编写代码,失败,学习,修复并重做。 在大多数情况下,我们可以与其他参与者一起学习很多东西,与他人一起分享失败经验并共同学习。 我们与一个绝对的陌生人合作了多少次,他可以教我们一些新奇的东西,或者相反,我们可以教一些新的东西? 很少 。 阿尔卑斯山 这个事件是关于社区的 。 期。 主要目标是与所有其他参与者一起尝试使用Swift编程语言,尝试在失败的前提下尽可能多地学习。 Ash Furrow写了两篇有关“规范化斗争”和后来有关“共情文明”的惊人文章,对于有兴趣加入我们参加此活动的人来说,这是两篇很棒的读物。 这两篇文章都总结了Swift Alps想要解决的问题以及即将发生的事情。 格式 该格式已经由许多人开发,并在一个文档中进行协作,试图获得hackathon和un-conferences等其他格式的最佳效果。 结果如何? 正如您可能在官方网站上看到的那样,已经列出了一些导师(不是演讲者!)。 这些导师将成为活动的重要组成部分,但最重要的是成为参与者-您! 介绍 导师将在5-7分钟内进行介绍,内容涉及进行实验的主题(示例:跨平台Swift,服务器端Swift,测试,安全性,扩展,异步编程等),然后每个参与者都可以了解小组的内容,然后加入小组进行实验。 实验中 每个导师都会有一群人,他们准备的主题进行实验,也许会带着最终的目标(例如:示例Web应用程序,Swift中的Android应用程序,在广泛使用的OS库中修复乏味的错误,Swift Evolution提案等),但它们也可能是完全开放的(带来您自己的错误)。 所有与会者都将与可能从未与之共事的其他人一起工作,在规范斗争的同时交换知识。 我们会定期进行调整,彼此进行3-4次会话。 您将带回家的东西远远超出了定期会议带回家的东西 […]

使用SnapKit编写自动布局约束

当最终使用Auto Layout开发UI时,您可以选择在Interface Builder中布置视图和/或以编程方式编写约束。 两种方法都不总是比另一种更好。 使用IB确实很方便-无需输入所有布局代码,它就可以大大减少开发时间。 但是有些人(包括我本人)经常喜欢用代码编写大多数约束,因为他们发现调整,调试和重用布局更容易。 而且,除非您有明确的流程,否则尝试与故事板文件上的开发人员团队并行工作可能会成为Git Nightmare™。 但是,如果您以编程方式进行了大量布局,也许您已经注意到NSLayoutConstraint的API可能很冗长。 是否曾经在代码中完全实现过复杂的UI? 最终它有多少LOC? 大概很多! 一般来说,代码越少越好吧? 如果有一个更简单,更快的方法来编写布局约束,那将是很好的。 SnapKit简介 从GitHub页面 SnapKit是一种DSL,可在iOS和OS X上简化自动布局。 SnapKit本质上是用于编写约束的语法糖。 它通过UIView / NSView类上公开的’snp’属性提供了很高的抽象水平,允许您使用简洁的闭包语法在视图上定义约束,然后让SnapKit负责其余的工作。 它可以使您的布局代码清晰,简洁。 真的很简洁。 只要看看将UITableView约束到其超级视图的所有四个方面是多么容易。 这是使用原始NSLayoutConstraint API的相同代码。 这是另一个示例,将视图集中在屏幕上。 我们可以利用SnapKit的一些便捷方法和链接约束的能力来略微缩短此时间。 很酷。 如您所见,SnapKit非常直观且易于使用。 查看文档以获取更多示例。 不确定SnapKit是否适合生产中的应用程序,我不确定—好像存在一些内存泄漏问题,也许不是吗? 尽管如此,SnapKit是一个很棒的库,只是因为它变得更好,所以我建议您检查一下。

5个随机Swift片段

使FileManager使用URL和路径 扩展FileManager { func fileExists(URL:URL)->布尔 { 返回self.fileExists(atPath:url.path) } func removeFileIfExistsAtURL(_ url:Foundation.URL)抛出 { 保护fileExists(at:url)else {return} 尝试removeItem(atPath:url.path) } } 我知道它愚蠢的简单,并且有一个很好的论据将它们仅保留为路径(更好的是将其作为适当的“文件路径”类型),但是为了方便起见,这非常方便,特别是因为许多其他框架仅返回URL。 2.平等 扩展FloatingPoint { func equal(to value:Self,精度为Self)-> Bool { 令lhs =(自我/准确性).rounded()*准确性 令rhs =(toValue /准确度).rounded()*准确度 返回lhs == rhs } } 在很多情况下,例如在处理纬度/经度时,您仅在意一个值是否等于N个小数点。 3.对 扩展数组 { func pair()-> [((Element,Element)] { 返回Array (zip(self,self.dropFirst())) } } //示例: 令tmp = [1,2,2,3,1] 让结果= tmp.pairs() //结果== […]