设计模式是针对软件设计中常见问题的可重用解决方案。 它们是旨在帮助您编写易于理解和重用的代码的模板。 最常见的可可设计模式: 创作性 :单身人士。 结构 :装饰器,适配器,外墙。 行为的 :观察者,和,纪念品 让我们开始吧…… 🏄🏻 正面 Facade设计模式提供了到复杂子系统的单个接口。 无需向用户提供一组类及其API,而是仅公开一个简单的统一API。 当使用大量类时,尤其是当它们使用复杂或难以理解时,此模式是理想的选择。当外观下的类可能会更改时,这也很有用,因为外观类可以保留相同的API事情在幕后发生变化。例如,如果您想替换后端服务的日子到了,您将不必更改使用API的代码,而只需更改Facade中的代码即可。 装饰器 装饰器模式可以动态地 向对象添加行为和职责,而无需修改其代码。 它是子类化的替代方法,在子类化中,您可以通过将类与另一个对象包装在一起来修改类的行为。 在Objective-C中,此模式有两种非常常见的实现: 类别和授权 。 在Swift中,此模式还有两种非常常见的实现: 扩展和委托 。 委托:用于将实现特定的行为排除在通用类之外。 iOS中的许多UI元素都使用委托来控制其行为,例如UIScrollView。 UIScrollView类不知道应该滚动什么,因为那是应用程序特定的任务。 因此,要通知应用程序滚动事件,它将使用UIScrollViewDelegate。 应用程序可以实现委托,然后拦截由UIScrollView发送给它的滚动事件。 纪念品 在Memento模式中, 可以将您的内容保存在某处 。 稍后,可以在不违反封装的情况下恢复此外部状态。 也就是说,私有数据保持私有。 Memento模式的实现示例是存档,序列化和 状态恢复 。 适配器 适配器设计模式将类的接口转换为客户期望的另一个接口 。 Adapter使类可以协同工作,否则由于接口不兼容而无法实现。 它将客户端与目标对象的类分离。 苹果使用协议来完成这项工作。 您可能熟悉UITableViewDelegate , UIScrollViewDelegate , NSCoding和NSCopying等NSCopying 。 例如,使用NSCopying协议,任何类都可以提供标准的copy方法。 观察者 观察者设计模式定义了对象之间的一对多依赖关系,因此当一个对象改变状态时,其所有依赖关系都会被通知并自动更新。 观察者模式本质上是一个发布和订阅模型,其中主题及其观察者是松散耦合的。 […]
并发在我们的日常工作中越来越重要。 在我的上一篇文章(使用Swift进行并行编程:基础知识,操作)中,我们研究了Apple提供的工具。 这次,让我们看一下没有得到官方支持的东西。 总结一下: 并发是指同时进行工作的能力。 想象一下,任务长期存在。 需要一段时间,最后,我们得到了结果。 例如,这可能是下载文件。 结果将是图像。 同时,我们知道将图像设置为UIImageView。 那么我们如何实现呢? 最简单的版本是通过NSURLSession下载文件,然后将其关闭。 我们都知道,该怎么做。 所以这里没问题。 但是让我们稍微复杂一点。 我们没有该文件的链接,而是必须从后端请求该文件。 这样做将包含请求链接,将响应解析为我们期望的格式,请求图像然后进行设置。 对于像这样的简单用例,这可能会变得越来越复杂。 最后,我们处于回调地狱。 相反,我们可以创建一个委托并对此做出反应。 如果您有两个以上的请求,将很难维护。 调查操作,我们将这些任务拆分并以这种方式编写。 但是正如您所看到的,很难遵循用例的逻辑。 那么还有哪些其他选择呢? 承诺 有一个想法,考虑在将来创建包含值的变量。 它现在不需要立即包含其值,但是在某个时候,它将具有该值,然后我们就可以在其上执行代码。 这无非就是承诺-在某个时间点交付价值的保证。 对于Promise,您可以编写有关此想法的代码,即该变量有时会包含值或错误。 只要兑现了承诺,它就会被执行。 创作与创作 一个Promise包含一个带有2个回调的闭包。 您可以通过调用具有相应值的complement()来实现Promise,也可以通过错误拒绝它。 要创建Promise,只需包装要创建值的代码即可。 用法 承诺分为多个部分:承诺本身,成功代码(如果包含值)和错误代码。 只要没有代码,promise将不会执行任何代码,这将对其值做出响应。 要添加此代码,我们使用`.then()`。 这仍然不能决定执行时间。 它只是说,诺言如果愿意就可以开始。 由于经常需要创建代码链,因此我们不仅可以返回值,而且还可以返回承诺。 如果响应者链中有任何错误,执行流程将跳转到catch子句,而不继续执行其他then()闭包。 PromiseKit 有多个承诺库。 Google刚刚发布了自己的版本。 还有一个鲜为人知的竞争者,称为HoneyBee。 我将使用PromiseKit,因为它已经相当成熟并且已经开发了多年。 根据我的经验,他们的问题响应时间非常快,仅几个小时之内。 此外,PromiseKit提供了许多扩展,您可以在iOS中使用这些扩展来简化其使用过程。 由于Swift及其对Promises的解释,它确实包含一些特殊情况,但无论如何,让我们深入研究一下如何使用它。 安装 PromiseKit支持几乎所有的安装方式。 您可以通过Cocoapods做到这一点: 迦太基: SwiftPM: […]
圣诞节快乐! 圣诞节我只要你。 代表与关闭回调 还记得Objective-C中的委托模式有多棒吗? 通过委派出类来使类具有超级可重用性…… itnext.io 如何在Tableview内部的Collectionview中使用pageControl? 在我的项目中,我在collectionView中使用了tableView,还使用了pageControl。 当我滑动集合时… stackoverflow.com [Swift 4]如何在情节提要中使用自动布局制作水平分页UIScrollView 2017年12月更新:针对Xcode 9和Swift 4进行了全面更新。由于自动版式诞生了,因此制作… sweettutos.com Advanced UICollectionView作为迷你PokédexiOS应用程序的页面控件的示例。 想象一下,您最好的设计师对一个很棒的页面控制组件有一个想法,而作为iOS开发人员,您想… medium.com 问题:一直在努力应对iPhone X的布局。 场景:将一个UICollectionView(假设为“ ColA”)放在UICollectionView单元格内,我们将该集合视图称为“ ColB”。 ColA布局需要坚持UIViewController的导航栏。 解决方案:在情节提要或Xib中拖动布局时。 请记住选中“限制到边距”复选框,如下图所示。 提示:请确保您的约束真正指向的是什么! iOS 10和11上神秘的布局指南,边距,插图和安全区域 iOS 11带来了更多有关视图如何布局用户界面的信息和许多改进。 您可以… blog.smartnsoft.com 计算UIViewController的顶部距离(状态栏高度和导航栏高度),而无需… 通常,当我开发iOS应用程序时,我需要计算UIViewController的最大距离,这个距离是总和… medium.com 适应性和布局–视觉设计– iOS –人机界面指南– Apple Developer 了解有关为iOS设计应用的信息。 developer.apple.com 迅速 我现在要来写一系列关于iOS程式开发的文章。不是为了教学,而是为了把我懂的知识整理起来,系统化。里面的概念可能跟别人讲的不一样,不保证我写的是对的。 medium.com 如何让iOS程式码更美观:物件的设定 我们都看过这样的代码: medium.com iOS开发 简单地说,Swift只是语言,写iOS app不一定要用Swift(用Objective-C也可以),而Swift也不能只能编写iOS… medium.com […]
苹果做了一件大胆的事情,并将其平台编程语言从Objective-C切换到了全新而又不同的东西-Swift。 Swift是经过深思熟虑且易于学习的下一代编程语言。 它具有很大的灵活性,并结合了许多其他语言试图追溯地添加到其系统中的现代编程概念。 Java很老 Java已经存在了20年。 一直以来,它并没有完全跟上发展。 这是一种易于学习的语言,但在许多现代环境(包括Android)中比较繁琐。 现在该继续前进了。 对苹果的恐惧 Swift是由Apple创建和控制的。 我们仍然记得,iOS和Android之间的平台大战引发了网络上无数的狂热分子大战。 我认为我们可以摆脱对苹果的恐惧。 平台之战结束,两个平台均获胜。 iOS或Android不会很快到任何地方。 数字清晰 忽略在iOS和Android之间创建共享语言的所有潜在技术问题将是一笔巨大的财务胜利。 如今,近100%的移动项目是使用Android和iOS编写的。 大约50%的代码是业务逻辑,API调用等非UI,非框架特定的代码。 所有这些代码都可以在Android和iOS项目之间共享。 可以说,某些部分需要一些创造性思维,但是大多数部分的代码共享将非常简单。 实际上,MS围绕这个想法创建了一个业务Xamarin。 尽管Xamarin还有其他问题,但在iOS和Android之间共享业务逻辑代码当然是明智的。 能够共享业务逻辑将在测试和编码方面为所有移动项目节省大量资金。 节省时间将直接反映在移动项目的交付成本中,从而使分配的预算更有可能被更好地花费在创建质量更高的软件以及更多应用上。 这两个生态系统的数量和质量都将大大提高。 “负载平衡”移动开发 共享的业务逻辑还将允许移动团队工作时间的“负载平衡”。 通常情况下,其中一个平台领先于另一个平台。 在共享业务逻辑模块的情况下,总是可以将更快的团队分配给业务逻辑职责。 选择以更灵活的方式分配开发人员的选择将在许多项目中节省大量资金。 共享库 现在,我不主张共享UI层或特定于平台的库并执行某种跨平台策略。 那些失败了。 但是,共享编程语言将使庞大的共享库项目生态系统成为可能。 非UI代码库的许多部分可以做成跨平台的。 显而易见的好处是,团队将非常简单地了解彼此的体系结构和功能。 了解其他平台 共享语言将不允许Android平台的开发人员跳入iOS项目。 在平台上工作不仅需要了解编程语言,还需要做更多的工作。 但是,共享一种语言将使团队可以在一个全新的水平上讨论细节。 分享知识总是对企业有利! 没有跨平台框架的滞后或废话 Xamarin作为平台确实不能很好运行的原因之一是第三方系统的持续滞后。 一切新内容都必须始终通过第3方框架进行,并且所有功能都必须由跨平台工具维护者添加。 这不是一个可持续的模型,Xamarin并不真正适合大多数项目。 在共享编程语言的情况下,平台功能仍将是第一方开发和“ Xamarin问题”。 从技术上讲,这并不容易 好。 真的不是那么容易。 要使Swift成为Android的第一层语言,这将是一个巨大的项目。 我认为从长远来看,这样做是值得的。 该行业将节省大量资金。 如果有人能做到……那就是Google。 他们拥有使魔术发生的资源和技能。 […]
我正在做一个项目,我必须为此开发一个可滚动浏览的圆形聊天对象,并使其圆头,可以水平滚动,并且当用户在视图内部/外部轻按时可以展开/折叠。 首先,我们需要创建一个我最终以某种方式将其命名为ProfileHeadsView的视图。 这将是我们集合视图的容器视图,并将由用户添加为视图的子视图。 因此,此容器视图以及随后的收集视图将自动采用目标视图的宽度。 ProfileHeadsView是UIView的子类,并且具有相同名称的Xib文件。 Xib的视图是ProfileHeadsView的类型。 该视图需要一种方法来从包中加载Xib文件,并将实例返回给调用函数。 这是通过以下方法实现的。 class func loadViewFromXibWithFrame(_ frame:CGRect)-> ProfileHeadsView { 让viewFromXib = Bundle.main.loadNibNamed(“ ProfileHeadsView”,所有者:无,选项:无)? ProfileHeadsView viewFromXib.clipsToBounds = true viewFromXib.frame =框架 返回viewFromXib } 接下来,我们为设备旋转设置了一个观察器。 这使我们能够以纵向和横向模式处理流程。 我设置了旋转观察器,并在awakeFromNib中设置了我们的collectionView(这是所有插座都将连接的点。 在查看上面介绍的代码片段之前,我们必须了解UICollectionViewFlowLayout的疯狂功能 。 当我们需要自定义与集合视图的行为有关的任何事情时,这是首选。 为了获得所需的行为,我们利用了单元格的z索引。 Z索引允许垂直堆叠收集视图单元格。 为此,我们重写了集合视图的流程布局的layoutAttributesForElements(in 🙂方法。 在此方法内部,我们打算 计算电池堆中心 获取元素的布局属性以进行修改 根据堆叠因子和堆叠中心计算这些单元的新位置 显式地将第一个单元格放在堆栈顶部(除非您想将其他单元格放在顶部) 返回修改后的属性 下面是自从看到最后一个代码以来我们已讨论的所有代码的片段。 var stackCenter:CGPoint = CGPoint(x:0,y:0) var stackFactor = CGFloat(0.1)// MIN:0 …. MAX:1 @IBOutlet弱var […]
边干边学。 趣闻:我想构建一个iPhone应用程序。 我确定我们之前都听过该声明。 iPhone应用程序已成为我们生活的一部分。 我们中的许多人无法想象没有能力随时掌握天气预报。 快速浏览Instagram和几轮Quiz-Up,可以轻松地改变无聊的午休时间。 如果有需求,可能有一个应用程序。 现在,许多软件开发人员已将重点从传统的桌面应用程序转移到了移动应用程序开发上。 甚至网页设计师都在寻找一种方法来将移动应用程序开发添加到他们的技能库中。 真正的问题是: “几乎没有编码技能的人会去哪里学习如何构建iPhone应用程序?” 答案是通过学习Swift 。 我是那些不知道该去哪里的设计师之一。 除了使用HTML / CSS和少量前端Javascript构建网站外,我不知道从哪里开始。 但是,简单的Google搜索很快改变了这一点。 突然,我的选择权从零增加到数百。 对我而言突出的一种选择是学习Swift 。 对于不认识的人,Swift是用于创建iOS应用的相当新的编程语言。 它是C和Objective C的完善版本,使设计人员和开发人员更轻松地进入iOS开发。 苹果公司表示,Swift非常易于使用, “任何有创意的人都可以创造出令人难以置信的东西。” 甚至大型公司也开始使用这种语言。 去年,LinkedIn开发人员分享了他们的经验,他们为iOS构建Slideshare,这是完全内置于Swift的首批应用之一。 快速浏览Quora后,似乎每个使用Swift的人都对它的易用性大加赞赏。 受Katie Smillie和Kenny Chen的启发,我决定尝试一下。 目标? 在16/1/16之前在App Store中拥有iPhone应用程序 在接下来的10周里 ,我将每天花几个小时研究iOS开发,重点是设计 。 此旅程不仅涉及构建应用程序,还涉及利用移动设备上有限的空间来精美地传达想法,游戏或任务。 我对这一挑战最感兴趣,同时又建立了使我的设计栩栩如生的技能。 您可以在此处或在我的博客上通过每周更新来关注我的旅程和进度。 我还将分享学习Swift时需要注意的工具,资源和障碍。 敬请关注!
CAGradient , CAGradient速度很慢,我们应该使用UIImage渐变代替它。 让我们来看看。 TL&DR:具有shouldRasterize = NO CAGradient与UIImage具有相同的性能,并且比具有shouldRasterize = YES更快。 在比较它们速度的第一个实验中,我创建了带有UITableView和每个UITableViewCell内部的渐变的示例项目。 每个单元格都在prepareForDisplay重绘其渐变,因此我们可以测量渲染时间。 共有三种类型的渐变: CAGradientLayer(红色) 带有shouldRasterize == YES (绿色) UIImage渐变(黑色)
因此,您决定全心投入iOS应用开发吗? 好吧,让我们用一组很棒的资源来帮助您,这些资源有望提高生产力。 来自苹果 iOS开发的起点应该是Apple: 苹果提供的一本免费书,名为“ Swift编程语言” 。 WWDC视频。 一个很好的地方,开始聆听来自Apple的最新和最精彩的文章。 博客,播客和课程 您应该查看各种出色的博客,播客和机构课程。 斯坦福大学关于Swift的iTunes课程| 斯坦福大学提供的绝对棒的完整课程,完全免费。 https://medium.com/ios-geek-community | Bob Lee撰写的很棒的新博客。 那里有一些很棒的入门教程。 https://www.raywenderlich.com/category/ios | Ray是最古老和最著名的教程网站之一,拥有大量的教程。 一定要检查一下。 https://talk.objc.io/ | 关于Swift编程的每周视频系列。 http://www.appcoda.com/ | Appcoda有大量出色的教程和大量的初学者和中级书籍。 http://nsscreencast.com/episodes | NSScreencast拥有所谓的“ iOS开发中每周一口大小的屏幕录像”。 也有大量的免费截屏视频。 https://thinkster.io/a-better-way-to-learn-swift | 如果您是Swift的新手,那就太好了。 付费课程 如果您正在寻找可以付款并获得更多商业等级的地方。 https://www.udemy.com/swift-3-learn-to-code-with-apples-new-language/ | 尼克在Swift上有很多课程,并且反馈很多。 您还可以在Udemy的其余部分中进行搜索,以查找其他众多教师的课程。 https://www.codeschool.com/courses/app-evolution-with-swift | Code School的月度计划费用为29美元,使您可以选择各种不同主题的课程。 https://designcode.io/ | 如果您是一位打算从事App开发的设计师,那么这是Meng To的完美入门课程 时事通讯 我强烈建议您订阅的新闻通讯清单。 它们都是大量的提示,新闻,建议和信息。 http://nshipster.com/ | […]
我真的很喜欢Apple API。 我认为它们是合乎逻辑的且经过精心设计。 但是他们的某些选择只会使我瘫痪。 一种选择是使用字符串作为键路径或标识符。 在编译期间不检查字符串,您可以很容易地错误键入它们。 否则名称可能会更改。 哦,我还记得那些漫长的夜晚,当我尝试在UITableView中查找内存泄漏时,发生了这种情况,因为我忘记在Interface Builder中为我的单元格设置了reuseIdentifier 。 那些痛苦和遗憾的时刻。 另一个问题是,我的代码很容易出错,因为我在整个项目中都重复使用了单元格,这导致我创建带有标识符的常量头,这很麻烦,因为我必须不断将其与笔尖名称和标识符同步。 总体而言,我喜欢的字符串太多了。 其他开发人员的代码看起来和使用起来更加痛苦,因为它看起来像是直接从Apple教程中复制粘贴的代码,这些代码在各处都具有Massive View Controllers,并且具有零可重用性和可扩展性。 可悲的是,这样的代码甚至在今天都可以看到,并且在过去,平均而言,也没有比这更好的了: 因此,大约7年前的一天,我开始反思自己的事迹和周围人的事迹。 我觉得我是一个罪人,那不是永远的。 我脑子里有一个特别的问题:“我们为什么要使用Apple约定,却害怕创建自己的约定?”然后,我环顾四周,发现基于CoreData的ActiveRecords确实有自己的约定,我的团队也有。 它们只是没有形式化,没有得到很好的利用。 我很开悟。 我决定,我想创建约定以简化从辉煌的一天到永恒的代码。 但是我感到,公约同时是危险的,因为每个人都必须遵守它们。 因此,我记录了他们的心声,并在团队中谨慎而勤奋地向整个团队宣传。 我在那个时候恢复了我的行动和想法,但是我用Swift重写了它们,向您展示了如何自己分析和创建约定。 形式分析使我发现了一个发现。 所有单元格都有标识符,这是其类名的直接派生词。 而且,所有视图的所有笔尖都具有与该特定视图的类相同的名称。 首先,我摆脱了细胞问题。 我创建了一个约定,那就是我们所有的单元类名称和重用标识符应相等: 注意,我立即创建了一个负责类型字符串化的函数。 在那个时候我们不需要它,但这是常见的切入点,可以在以后需要时允许扩展。 在ObjC时代,我们可以重载扩展中的任何属性,但是我没有这样做,而是创建了IDPTableViewCell子类。 为什么? 很简单,我们与其他开发团队的代码具有互操作性。 而且,如果我超载了UITableViewCell redirectIdentifier ,我会弄乱其他人的代码,他们可能会使用不同的甚至根本不使用任何约定。 然后,我想,我想摆脱表视图中的字符串,这意味着我需要从UINib中删除字符串(那时没有UINib ,只有旧的NSBundle.loadNibNamed ,但是正如我之前提到的,我希望了解我的故事): 我创建了许多其他方法,从用于表视图的API中完全删除了字符串(我保证很快就会开源)。 我的生产代码开始看起来像这样: 虽然这不是LOC部门的重大改进,但此代码还是有一个巨大的胜利:我不必再费神笔尖中的字符串和标识符了。 我想提及的另一种情况是完全不同的,但也与约定有关。 经过分析,我发现项目中的所有视图控制器笔尖都具有与视图控制器类相同的名称。 这与苹果公司本身所强加的惯例是一致的。 但是真正的问题是,我的产品负责人(希望您在读这篇文章时能在地狱中度过一个愉快的假期)想要不同的笔尖,这些笔尖的布局完全不同,适用于不同的设备,那时没有尺寸级别。 那就是我发现的时候,如果需要的话,这些约定应该可以扩展。 因此,我有了解决方案—重载了抽象视图控制器类的nibName属性。 我真的很高兴拥有该类,因为否则我将不得不创建它并相应地重构所有代码。 因此,我想到的另一个约定是:“为您计划从中继承的所有基础组件创建子类”。 在我的情况下,它们是UIView , […]
如果您曾经尝试过在Swift的类方法中使用mutating关键字 ,则编译器肯定会对您大喊大叫,因为您做错了什么。 迅速地,类是引用类型,而结构和枚举是值类型 。 默认情况下,不能在其实例方法中修改值类型的属性。 为了修改值类型的属性,必须在实例方法中使用mutating关键字 。 使用此关键字,您的方法便可以更改属性的值,并在方法实现结束时将其写回到原始结构。 以下是Swift中Stack的简单实现,说明了变异函数的用法。 我相信这很容易理解。 但是,如果您需要任何澄清或问题,请在下面给我留言,我将为您解答。 谢谢阅读。