Tag: 迅捷

谢谢,自动版式!

对齐:在要在超级视图中水平或垂直对齐多个视图或单个视图时很有用。 首先,我突出显示了要对齐的两个标签,然后选择了“编辑器”窗口底部的对齐图标。 前四个约束选项将视图与边缘对齐。 中间的水平和垂直选项将视图与其各自的中心对齐。 仅当两个或多个视图具有基线时,才会出现基线约束。 最后,底部的两个选项设置相对于超级视图的水平和垂直约束。 固定:使您可以“固定”视图相对于其他视图的大小和位置。 固定工具有几个选项- 与对齐工具类似,前四个约束使您可以将选定视图的顶部,前导,尾随或底部边缘固定到最接近它的视图。 “约束到边距”选项确定视图是否将约束到超级视图的边距或边。 宽度,高度和纵横比(视图的宽度和高度之间的比例关系)约束分别自动默认为视图的当前值。 您到目前为止在“ Cute Cat !!”标签和图片之间以及图片周围看到的蓝线是我设置的约束。 解决:此工具提供有关如何解决已设置约束的指南。 顶部选项更新选定的视图,而下半部分影响所有视图。 3.让Interface Builder为您设置约束。 您可以通过单击“编辑器”窗口右上角的“ 解决 ”按钮(如上所述)并选择“重置为建议的约束”来选择此选项。 当界面设计器使用此布局设置约束时,一开始设计的界面必须准确。 因此,如果视图稍微偏向一侧,则界面生成器将不知道将视图移至上方,而是将视图限制在稍微偏心的位置。 如何选择设置约束的最佳方法? 最终,它取决于首选项以及您希望应用程序的用户界面多么复杂。 如果要使用简单的用户界面构建应用程序,则允许Interface Builder在视图之间设置约束或控制拖动可能是最佳选择,因为它们既快捷又容易。 更复杂的用户界面可能需要使用“编辑器”窗口底部的一个或多个工具。

RxSwift的基础

Xcode入门 创建一个新的Single-View Application项目,然后打开ViewController.swift 。 我们将在viewDidLoad中添加一个属性和一些代码。 使用CocoaPods或其他软件包管理器将框架添加到项目中后,请确保导入RxSwift 。 数据存在的地方 变数 在这里,我们创建了一个属性,该属性将为我们的开关保留一个布尔值 。 我们使用一个变量 ,其通用值Bool分配为true作为默认值。 要访问或更改布尔值,我们必须使用viewDidLoad中所示的变量的value属性。 可观察的 从名为switchState的变量中 ,我们可以创建一个可观察的对象。 一个Observable侦听状态以更改为新值或相同值(或事件)。 让我们看看接下来可以使用Observable做什么: 过滤 当我们使用。 对我们的可观察对象进行过滤 ,我们给它传递一个闭包,如果闭包返回false,则可观察对象将忽略此事件。 地图 使用 。 map将允许我们将Bool转换为所需的任何类型。 在这种情况下,我们将Bool映射到一个更好地表示我们状态的字符串 。 也许现在我们可以在标签上向用户显示此字符串 。 到目前为止我们所拥有的 在viewDidLoad中 ,我们创建一个observable,并应用一个filter , distingtUntilChanged和map操作来获取titledObservable的最终observable。 由于我们只需要一个可观察的对象,因此我们可以将代码重构为如下所示: 链接每个操作可以使我们更加简洁。 聆听数据更改 订阅可观察的 在我们的viewDidLoad中 ,添加以下内容。 这是我们侦听可观察事件以发送事件的方式。 在我们的案例中,我们正在监听switchObservable的更改,因此我们可以将labelToday.text更新为newValue 。 订阅可观察对象时,您可以收听不同的事件。 但是,这里我们正在监听onNext事件。 处理袋 处理袋用于将类似ARC的行为返回给RX。 当DisposeBag被释放时,它将在每个添加的一次性物品上调用dispose。 每当您订阅可观察对象时,此订阅方法都会返回Disposable对象。 这对内存管理很重要。 那么,您如何处理一次性用品? 查看以下代码: 在我们的ViewController中 […]

带流量控制器的MVVM —第一步

我正在观看有关MVVM概念的KrzysztofZabłocki的视频,并认为只有一种方法可以理解某些内容:创建我的项目! 在深入了解应用程序体系结构之后,最近6个月我一直在研究带有MVVM协议的模型。 要了解其起源,必须引用Natasha The Robot的文章以及有关面向编程协议的所有知识。 如果您不知道我在说什么,那么好的主意是阅读Natasha The Robot 。 一个月前,我最终观看了Steve“ Scotty” Scott的MVVM-C讲座。 在我今年看过的最好的视频之一中,重要的防御不是缩写技术,而是架构可以帮助我们改进软件的。 对于捍卫技术“银弹”的人们,我没有什么反对的态度,但是我更喜欢这样一种策略:从每个创意中汲取最大的价值,以找到最佳的解决方案。 Flow的初始化程序将构建ViewModel和Model(如果需要,还可以创建更多模型)和start方法,并创建必要的接口并注入其依赖项。 这将使这些实体之间的耦合更多地利用代码。 我们可以看到在OwlsFlowController的情况下,通过配置选择是将数据显示为Grid还是List,在这种情况下,它是固定的,但它可能是测试简单的A / B。 此模型的优点是,大多数列表中的应用程序共享相同的行为和相同的接口基础结构。 在这种情况下,只有数据和单元格会更改,并且可以作为参数传递并为所有列表创建重用代码库。 这里一个有趣的想法是实现了两种响应协议:一种用于Grid,一种用于List。 但是两者的实现是相同的。 这很有趣,因为我对每种类型的接口都有单独的操作,但是可以共享常用操作。 并且不使用继承。 界面的实现清晰明了,它是一种客观的基础结构,具有简单的参数即可显示。 所有创建都被删除,使他没有任何业务实现。 另一件事是通过Closure填充了单元格,这将使我们能够在不久的将来传递使用哪个手机作为参数。 这种体系结构的思想是将接口分为两部分,第一部分是一系列现成的基础架构,可在整个项目中重用。 第二部分是针对每种情况和每种数据集定制的UIView和单元格。 因此,我们的大部分界面都已包含在通用测试中,从而提高了安全性。 PS:由于某些原因,在某些情况下,Swift不会接受Generic类型作为init方法的协议参数。 仍在调查Swift Bug或故意限制。 结果是非常干净的代码,并最大程度地重用了接口。 并探讨了泛型和协议作为抽象问题的一种方法。 其他结果是构建时间明显快得多。 这些是几周后的初步结果,我希望获得其他结果,并将在其他文章中进行探讨。 如果他们想继续关注Github,请尝试在“ Middle”(此处)或“ Medium”(此处)的此处进行很好的记录,我将把这些文章。 接下来的步骤,谢谢。 下一步 测试:带有模拟对象的单元测试和UITest(MVVM和测试) 展开模型:其他对象(我需要找到其他动物) 接口的基础结构:创建其他单元格类型并使用相同的UIViewController 我的下一篇文章将介绍如何构建有效且易于维护的测试。 为我交叉手指。 特别感谢 引用时,我试图标记所有阅读的内容,以写出这段代码,对不起,如果我忘记了别人。 我不能忘记感谢Mikail Freitas帮助我识别了通用协议的初始化错误。 我们永远不会理解为什么在一种情况下有效而另一种无效。 PS:Claire Knight(Twiter),她将项目迁移到Swift […]

iOS开发:The Woost Way™

在Woost,我们的承诺是在一个月内生产出最低可行的产品。 我们相信(几乎)每个新概念的核心都可以在该时间范围内构建。 我们帮助我们的客户找到核心,定义目标和假设,并缩小范围,直到一个月之内即可完成开发。 我们为网络(响应式)和移动(本地Android,本地iOS)构建。 为了能够加快速度并快速交付,我们拥有用于大多数项目的标准工具集和标准项目设置。 在本文中,我将向您介绍我们用于iOS项目的内容。 当然,随着每天都会出现新的最佳实践和新框架,这可能会发生变化。 警告:技术性越来越强😉 可可豆 其他人已经做了很多工作。 如果您知道如何珍惜他人*的工作,则可以节省大量时间,并避免通过使用轮子来重新发明轮子。 *: 这个很重要! 您应用的性能和稳定性至关重要。 CocoaPods是Swift和Obj-C项目的程序包/依赖性管理器。 您可以将CocoaPods集成到项目中,以轻松添加,删除或更新外部软件包。 我们主要使用CocoaPods,有时使用Carthage,但发现前者更易于使用。 我们或多或少的标准Podfile看起来像这样,已经使您了解了我们使用的工具: 吊舱“ RxSwift” 豆荚“ RxCocoa” pod’SwiftyJSON’ 吊舱“翠鸟” pod’PureLayout’ 吊舱“ R.swift” 豆荚“面料” pod’Crashlytics’ pod’Firebase / Analytics’#或’GoogleAnalytics’ 在设置Pod时,请确保还检查gitignore.io来创建一个漂亮的.gitignore模板! 我们通常从这一点开始。 接收 RxSwift是ReactiveX for Swift的一个版本(RxCocoa通过Reactive magic扩展了Cocoa API)。 ReactiveX简化了异步调用(避免了回调地狱 ),使代码更具功能性,可读性且不易出错。 我们主要将其用于API调用和用户界面绑定。 有关为什么使用Rx的更多信息,请查看RxSwift不错的页面。 Ray Wenderlich有一个很好的Rx入门教程。 SwiftyJSON 尽管Swift对JSON有一些基本的了解,但是使用SwiftyJSON可以使代码更整洁,类型更强,代码更短,更好理解。 翠鸟 有很多用于缓存图像的库,但是我们发现Kingfisher是最简单,最方便的使用方法。 PureLayout AutoLayout在情节提要板上可以很好地工作,但是如果您想在代码中添加布局约束,则原始API相当冗长且难以阅读。 PureLayout是一个很好的API,可以解决此问题。 凭借其方便的类型推断,尤其是使用Swift的短点语法,PureLayout的工作非常简洁。 SnapKit是一个不错的选择,我们尚未尝试。 […]

HanekeSwift iOS

简介 : iOS中有很多图像缓存库,很多库都是用Objective-C编写的,但是HenekeSwift是用swift编写的,非常易于缓存,它为UIImage,NSData,JSON,字符串或可以作为数据读取或写入的任何其他类型。 特点: 通用缓存,具有对UIImage,NSData,JSON和String的开箱即用支持 使用NSCache的一级内存缓存 使用文件系统的二级LRU磁盘缓存 从网络或磁盘异步获取原始值 所有磁盘访问均在后台执行 线程安全 根据内存警告或磁盘容量自动将缓存逐出 全面的单元测试 通过定义自定义格式,支持其他类型或实现自定义提取程序可扩展 对于图像: 零配置UIImageView和UIButton扩展以使用缓存,针对UITableView和UICollectionView单元重用进行了优化 调整背景图片的大小和解压缩 图片: 特别是Haneke擅长处理图像。 它包括一个具有自动调整大小的零配置图像缓存。 一切都在后台完成,从而实现快速响应的滚动。 您可以加载,调整大小,在共享缓存中缓存并显示来自url的适当大小的图像是: imageView.hnk_setImageFromURL //设置远程图像 您可以使用键手动设置图像。需要提供键。 imageView.hnk_setImage(图像,键:键) 上面的行照顾: 1)如果图像url或图像缓存在内存中,它将基于图像内容模式或此任务在后台执行的图像视图范围检索图像 2)如果未缓存图像,则从Web或源获取原始图像并根据imageview大小生成图像。从共享NSURLCache检索的远程图像(如果有)。 3)缓存结果图像 4)如果磁盘已满或其他任何问题,它将清除缓存中最近最少使用的图像 您还可以使用imageCache instance设置图像 。 例如 , 让imageCache = Shared.imageCache imageCache.set(值:UIImage(名称:“您在此处输入图像字符串”),键:“ image”) 使用获取图像 imageCache.fetch(key:“ image”)。onSuccess {(image)in //在这里设置图片 } .onFailure {(错误) //如果图片不可用则报错 } NSData: 您可以使用dataCache实例设置和获取NSData。 例如, 创建NSData缓存 let […]

RxSwift:Swift的响应式扩展第2部分

在博客文章的第二部分中,我们将应用ReactiveX以便使用RxSwift创建示例iOS应用程序。 在第一部分中,我们探索其背后的理论以了解RxSwift,特别是ReactiveX。 您可以在此处签出第一部分。 我们将要构建的应用程序是电话目录。 该应用程序包含一个表,该表包含用户添加的所有联系人。 它还使用户可以添加新联系人。 我们使用RxSwift更新界面,同时在每个用户输入处验证联系人。 我们还应用了RxSwift来绑定我们的模型(联系人列表),并在表格中显示它们。 您可以在此处检查最终结果: 如您所见,当我们输入输入内容时,标签会更新存在的剩余错误并启用/禁用“保存”按钮。 为了获得此结果,我们为名称文本字段创建了一个可观察值,为数字文本字段创建了一个可观察值。 让名称= nameTextField.rx.text.orEmpty .observeOn(MainScheduler.instance) 让数字= numberTextField.rx.text.orEmpty .observeOn(MainScheduler.instance) 然后,我们将两者结合起来以创建一个Contact Observable。 let contact = Observable.combineLatest(name,number){(name,number)-> Contact in 返回联系人(姓名:姓名,电话号码:号码) } 每次更新此联系人时,我们都会更新用户界面。 contact.subscribe(onNext:{contact in self.updateUI(与:联系人) }) 接触的验证和当前的错误在Observable之外。 您可以在此处查看完整的项目。

Swift如何改善自动版式?

如果使用自动布局,请举手。 以编程方式举手。 如果您想要一种简单的书写方式,请举手。 有很多开源项目试图使处理自动版式变得更容易。 (即砌体,PureLayout,制图) 我在这里通过介绍DHConstraintBuilder向您展示更快捷的方法。 您可能会想,“我为什么要打扰您?”,这是一个很公平的问题。 DHConstraintBuilder可以使用最少的代码来表达约束,但又不会失去任何意义。 它可以直观地显示约束的外观,同时生成有用的约束。 假设您有两个视图,并且要在它们之间放置默认填充。 使用自动版式时,该距离通常为8像素。 下面是将DHConstraintBuilder与NSLayoutConstraint进行比较的示例。 代码看起来如何? (以下两个示例在功能上等效) 使用NSLayoutConstraint: 使用DHConstraintBuilder: 让我们分解一下: // 1 -greenView和redView在水平轴上之间有15.5像素 -greenView在其超级视图的前导约束上具有默认填充 -redView在其超级视图的尾随约束上具有默认填充 // 2 -blueView在其超级视图的前导约束上具有默认填充 -blueView在其超级视图的尾随约束上具有默认填充 // 3 -greenView在其超级视图的顶部约束上具有默认填充 -greenView在垂直轴上具有与blueView的默认距离 -blueView在其超级视图的底部具有默认填充 // 4 -redView在其超级视图的顶部约束上具有默认填充 -redview在垂直轴上具有与blueView的默认距离 // 5 -greenView和redView具有相等的宽度 // 6 -greenview和blueView的高度相等 我可能有偏见,但是DHConstraintBuilder确实看起来更小,更简洁并且更易于阅读。 它消除了两个常见错误:忘记将translatesAutoResizingMaskIntoConstraints设置为false,以及忘记将视图添加到父视图。 可能突出的一件事是使用 ()|-^ ^-| () 同样,这是Visual Format对 |- -| 不用说,但是此API面向swift3。它必须是swift,才能利用重载的运算符。 DHConstraintBuilder在GitHub上可用,并且为ios 8及更高版本。 这是我的第一个开源项目。 […]

将服务器端Swift部署到Linode

开发完应用程序后,下一步就是将其提供给您的受众群体使用……因此,自然的愿望是将其部署到服务器上。 在本文中,我将演示如何将服务器端Swift应用程序部署到Linode容器。 如果要遵循,必须满足三个先决条件:Perfect Assistant应用程序,Mac上可运行的Docker应用程序以及Linode帐户。 服务器设置 第一步将是设置一个新的Linode容器。 在您的Linode Manager控制台中,单击“添加Linode”链接。 选择所需的大小和数据中心位置。 您将返回到Linodes列表,其中列出了新的Linodes。 单击它,然后按“部署映像” 。 在这里,我们可以创建一个新的Ubuntu 16 Linode,但是我们将使用“ StackScript”为我们完成所有繁重的设置,因此请单击“使用StackScripts进行部署”链接。 在“社区StackScripts:关键字”搜索中,输入“ Swift” 。 这将带来一些,但是您想要的是“ jono / Server-Side-Swift”脚本。 在下一个屏幕上,确保选择了Ubuntu 16.04,然后输入磁盘大小,交换磁盘大小和root密码,然后按“ Deploy” 。 等待“主机作业队列”作业全部完成,然后按“启动” 。 您可以通过选择“ Remote Access”并启动“ Lish via Browser”选项来观看引导和StackScript的进度。 StackScript将所有软件包执行一次完整的更新,以更新到最新的可用软件包,并安装Swift需要Perfect编译的许多常见库所需要的依赖项。 然后,它将安装Swift 3.0.2,并为您建立一些链接。 当最终出现登录提示时,您的Linode就绪了。 记下您新的Linode的IP地址,我们很快将需要它。 编译代码 现在切换到Perfect Assistant,让我们从GitHub获取“ Perfect App Template”。 在“欢迎”屏幕上,单击“创建新项目”,“自定义存储库URL”。 单击位置旁边的“浏览”,然后为模板找到URL,然后粘贴模板的URL:“ https://github.com/PerfectlySoft/PerfectAppTemplate.git” 保留“将Linux构建与Xcode项目集成”的复选框,因为我们在此阶段的目标是Linux部署。 单击“保存”后,系统将启动它是macOS端项目的初始克隆。 进行Linux构建非常简单,只需单击“ BUILD:Linux”按钮。 幕后操作是准备好Docker容器,将项目的依赖项克隆到沙盒位置,并进行沙盒化的Linux构建。 完成后,您应该看到最后三行是这样的: […]

使用SnapKit可视化斐波纳契序列

处理约束是用户界面编程中最普通,最挑剔和不可避免的方面之一。 作为新开发人员,我绝对需要以编程方式设置和处理约束的经验。 用代码全部写出来提高了我的效率,提高了我对如何最合理地安排视图和子视图的理解。 话虽这么说,但是如果您仅依靠UIKit功能来进行约束,那么就会有局限性,并且不乏烦恼。 我的一位讲师向我介绍了一种非常用户友好的CocoaPod,名为SnapKit,它可以简化并简化过程。 SnapKit通过消除对约束规则和视图本身进行单独操作的需求,使您可以更动态地设置和更新约束。 它在语法上也更加简洁。 由于这些原因及其他原因,SnapKit有助于避免常见错误,例如在应用程序生命周期中的任何给定时刻将过多或过少的约束应用于视图。 我决定制作斐波那契序列的可视化动画作为起点,以测试SnapKit的实用性和便利性。 资深的数学书呆子会同意:斐波那契数列非常有趣,因为它在整个自然和人类文化中表现出许多模式。 一个示例是金色矩形,其侧面的比率为〜1.618。 在铌酸钴的磁共振中,从量子水平到帕台农神庙设计的巨大规模,这一比例是显而易见的。 这是我想生成的图像: 首先,我编写了一些函数来生成斐波那契数,并创建具有相应尺寸的方形UIView。 我为每个正方形应用了随机的背景色,并将初始alpha值设置为零,以便以后实现淡入动画。 我希望约束正方形将是棘手的部分。 我首先编写伪代码来定义它们的排列算法: 将第一个正方形固定在超级视图的中心。 将第二个正方形的顶部和左侧边缘分别与第一个正方形的顶部和右侧边缘对齐。 将第三个正方形的右边缘和上边缘分别与第二个正方形的右边缘和下边缘对齐。 将第四个正方形的底部和右侧边缘分别与第三个正方形的底部和左侧边缘对齐。 将第五个正方形的左边缘和下边缘分别与第四个正方形的左边缘和上边缘对齐。 对系列中的其余正方形重复前四个步骤。 使用SnapKit,将这些步骤转换为Swift实际上非常容易。 您可以使用switch语句实现重复,该语句为索引模4的每个可能值指定一组不同的约束: 现在,该让它看起来很酷了! 我使用了关键帧动画来使正方形逐渐淡入。 使用.CalculationMode Paced会使每个正方形的渐变以渐进的方式发生,而不是从透明变为不透明。 这是最终产品: 我想添加一个滚动视图,以便您可以查看任意数量的斐波那契正方形的迭代模式的完整范围。 这将增进我对SnapKit的理解,特别是因为滚动视图是在约束方面要实现的更具挑战性的UIView类型之一。

椰子足与迦太基

很多时候,我们想知道如何管理对我们iOS项目的依赖。 从历史上看,这非常简单,因为选项非常有限。 从历史上看,我们使用Cocoapods是诚实的唯一有意义的选择,因为您既不想自己也不使用git子模块来管理它们。 过去的依赖管理 随着时间的流逝,我们意识到有新的选项可以管理依赖项。 当迦太基第一次出现时,我们也给了它一个机会,但它仍处于早期开发阶段,因此它具有很多令人讨厌的缺点。 不可能只为一个平台建立依赖关系,更新一个依赖关系而不更新其他依赖关系是不可能的,添加一个依赖关系而不编译其他依赖关系也是不可能的。 这样的事情只会让我们放慢脚步,因此我们决定坚持使用Cocoapods。 我们也不喜欢迦太基的哲学,因为我们喜欢运行pod install而不处理其他任何东西的想法。 迅速并发症 自从我们开始使用Swift作为主要的编程语言以来,我们面临着越来越多的麻烦-编译时间增加,语法高亮和SourceKit崩溃频繁。 我们开始想知道如何使我们的开发人员的生活更加愉快。 我们的第一个想法是看一下我们的依赖关系,因为它们是不变的代码,不需要被Xcode一次又一次地索引和编译。 这就是Carthage展示其优势的地方-依赖关系仅在框架中构建一次,仅此而已,不再需要建立索引,也无需进行编译。 迦太基反击 我们进行了一次尝试,Carthage似乎解决了所有早期开发阶段的问题,因此我们仅使用platform选项为iOS构建,而使用cache-builds选项跳过了已在本地编译的框架的编译。 结果真的很酷-语法突出显示变得更加可靠,并且构建时间减少了百分之几十。 这意味着,即使在功能不强的设备上,iOS开发也比15英寸Macbook Pro更舒适。 这也意味着我们决定以迦太基作为主要的依赖项管理器开始新项目。 我说主要的,尽管仍有一些不支持它的图书馆。 这些可能是较旧的存储库,它们不再维护或对我们无关紧要,因为我们尝试仅使用维护的库。 但是,某些专有软件使用静态库,这意味着它不能由迦太基管理。 在那些情况下,我们仍然使用Cocoapods。 持续的不便 但是,我们仍然遇到一些问题。 依赖项的初始编译时间可能会非常长,尤其是当依赖项包含多个子规范时(在Cocoapods术语中),因为Carthage会编译它们的全部(及其所有依赖项),即使项目不需要它们也是如此(为此存在拉动)迦太基github上的请求,这将减少这种不便,但目前仍未合并)。 我们也希望在项目之间进行一些本地缓存。 在我们的机器上,我们有更多的项目使用Carthage,并且经常使用相同版本的依赖项。 如果我们在每个项目中都运行迦太基引导程序 ,则即使它们的依赖关系可能是由以前的项目构建的,也可以建立依赖关系,这可以节省大量的构建时间。 也许与团队远程共享构建工件也很好。 由于我们的许多项目都使用Realm数据库,因此Carthage的空间利用率也可能更高一些-其工件占用大约1 GB的磁盘空间。 如果您有更多项目,则会很快损失很多空间。 仍然不是最好的 迦太基虽然极大地加快了我们的发展速度,但是仍然存在一些需要解决的问题。 也许现在可以通过使用正确的参数集来解决其中的一些问题,而另一些可以通过使用正确的工具(如Rome)来解决,但是那些提到的缺点可以很好地在迦太基内部集中解决。 分享是关怀 我们认为#sharing很重要,因此我们很乐意听到您如何管理依赖项。 您可以在下面给我们留下评论,或者在我们的Twitter,Github或Facebook上ping我们。