开箱即用的UITableViewCells相当有限。 少数几种标准样式提供的标签和图像视图不多。 如果您希望单元格包含自定义按钮和控件怎么办? 充其量,您可以挂钩到详细信息显示按钮,并且可能会覆盖它的外观,但这有点不合常规。 通常最好建立自己的子类并使用自己的子视图和按钮设计表视图。 这是一个好的开始。 现在,我们希望控制器挂接到这两个按钮上。 您可能很想在表视图数据源的单元格配置步骤中向每个按钮添加自定义目标操作对。 这很危险,原因有两个: 如果不小心,可能会在重用单元格时意外地多次添加目标操作对。 捕获单击了其按钮的单元格的索引路径并不容易(遍历视图层次结构以达到单元格本身有点草率,并且UIView的tag属性对于复杂的表视图不是理想的选择) 快速方法:协议 Apple将Swift描述为一种面向协议的语言,因此让我们尝试一种面向协议的解决方案! 为您的单元格类创建一个自定义的委托样式协议。 我叫我SwiftyTableViewCellDelegate。 对于委托样式协议,您希望委托的用户对委托对象具有弱引用。 由于弱引用只能在类上使用,因此我们的协议将必须声明“类”一致性。 为您要跟踪的每个操作添加一个委托方法。 在我的示例中,我有一个心形按钮和一个垃圾按钮。 我想知道何时点击这些按钮中的任何一个,所以我为它们中的每个创建了一个委托函数。 将委托属性添加到您的自定义单元格类。 使它变弱和可选。 然后,将按钮操作连接到单元格中的方法,以调用这些委托方法。 这可以在情节提要中完成。 整合我们的自定义代表 使您的UITableViewController符合您刚刚设置的协议。 另外,还要确保将单元的委托设置为控制器本身。 最终结果看上去与我们最初的基于目标动作的方法并没有太大不同,但是它解决了我们两个主要问题! 由于单元格只有一个委托,因此每次使用该单元格时,表视图控制器都可以将自己分配为该单元格的委托,并且没有过度监听的风险。 由于委托函数在sender参数中发送单元格本身,因此我们可以要求表视图非常有效地查找索引路径。 精彩!
自从苹果宣布并发布了Linux兼容的Swift源代码以来,服务器端Swift一直是最活跃的开发追求之一。 已经出现了许多框架,包括Perfect,Vapor和Kitura(由IBM提供)。 在此博客文章中,我们将讨论使用Vapor进行基本设置有多么容易。 Vapor是Qutheory的合作者为Swift开发的Web框架。 它以其简单性,类型安全性和速度而自豪。 该框架会经常更新以使用最新的Swift 3快照。 当前,正在OSX和Ubuntu(14.04和15.10)上进行开发测试。 我们将设置一个服务器,该服务器将在撰写本文时使用最新的Vapor版本在本地运行。 安装Swift 3 为了简化安装,我们将使用swiftenv,它是一个类似于pyenv和rbenv的Swift版本管理器。 访问他们的github页面以获取更多详细的安装和使用说明。 目前,我们正在终端中执行以下操作,以安装最新的Vapor快照支持。 swiftenv安装DEVELOPMENT-SNAPSHOT-2016-05-03-a 此命令下载并安装2016年5月3日的Swift 3快照。 安装Vapor CLI 在处理Vapor项目时,Vapor的命令行工具提供了很多便利。 wget cli.qutheory.io -O蒸气 chmod + x蒸气 须藤MV蒸气/ usr / local / bin 更新CLI的过程非常简单 蒸气自我更新 创建服务器 使用CLI,我们将能够使用简单的命令来创建基本服务器。 vapor new test-server //创建一个名为“ test-server”的项目 cd测试服务器 蒸气生成 蒸气运行 运行给定命令将设置并运行基本服务器模板。 如果您在浏览器上访问http:// localhost:8080,将会看到类似的内容。 这是一个简单的项目示例,您可以对其进行修改以适合您的服务器需求。 蒸气甚至通过单击登录页面上的链接来提供示例。 自定义路线 检查项目目录,我们可以看到创建了许多文件和子目录,包括VaporApp.xcodeproj 。 双击以Xcode打开它。 确保您使用的是正确的Xcode开发快照工具链。 该项目应具有以下文件结构。 […]
Apple引入了用于在iOS 10中预取UITableView和UICollectionView的 API。这是有关如何实现UITableViewDataSourcePrefetching协议的简短故事。 总览 为了实现预取,我们向视图控制器确认了UITableViewDataSourcePrefetching协议,就像UITableViewDataSource和UITableViewDelegate一样 。 这使表视图的数据源可以在调用tableView(_:cellForRowAt 🙂数据源方法之前开始为单元格加载数据。 入门 将视图控制器设置为表视图预取数据源 tableView.prefetchDataSource =自我 在tableView(_:prefetchRowsAt :)的实现中,初始化指定索引路径中单元格所需的数据的异步加载。 func tableView(_ tableView:UITableView,prefetchRowsAt indexPaths:[IndexPath]){ 用于indexPaths中的indexPath { 警卫让_ = loadingOperations [indexPath]否则{返回} 如果让dataLoader = dataStore.loadPhoto(at:indexPath.row){ loadingQueue.addOperation(dataLoader) loadingOperations [indexPath] = dataLoader } } } 当表视图通知您tableView(_:cancelPrefetchingForRowsAt 🙂方法不再需要数据时,取消挂起的数据加载操作 func tableView(_ tableView:UITableView,cancelPrefetchingForRowsAt indexPaths:[IndexPath]){ 用于indexPaths中的indexPath { 如果让dataLoader = loadingOperations [indexPath] { dataLoader.cancel() loadingOperations.removeValue(forKey:indexPath) } } } 异步加载数据 与tableView(_:cellForRowAt […]
如果我们查找有关函数式编程的文章,则其中大多数都在谈论高级函数式编程,例如副作用,无状态,不变性或monad之类的内容 ,而其他基本示例(例如map的工作方式)则太简单了,但是在这里试图通过使用Swift中的示例来展示函数式编程的实用方面。 这篇文章的第一部分将为您简要概述函数式编程和基本定义。 示例部分显示了如何以功能样式编写命令性非功能代码。 高阶函数 函数式编程语言的第一个显着区别是,可以将函数分配给值并传递给其他函数。 这就是为什么他们被称为头等公民。 当您说一种语言具有一流的功能时,这意味着它将一种功能视为值,您可以将一个功能分配给一个变量,或者将其传递。 一流的功能被视为一个对象。 有一个更高层次的功能。 它们接受一个或多个函数作为参数或返回其他函数。 高阶函数是可以在其他函数上使用的函数,即它们将函数作为参数,也可以返回一个函数。 映射,过滤,缩小 Map是著名的高阶函数之一。 Map在数组(更确切地说是集合)上工作,它接受一个函数(称为transform)作为参数,并将此transform函数应用于每个元素,并返回结果数组,作为“ transformed”元素的新数组。 使用map有一些优点:它更短并且需要更少的代码 , 更少的错误空间 ,更重要的是它更干净 。 假设我们有一个字符串数组,要计算每个字符,我们必须1.遍历该数组,2.获取每个元素的计数,3.将其追加到新数组中: let houses = [“Stark”, ” Baratheon “, ” Targaryen “, “L annister “] var letterCounts:[Int] = [] 用于房屋{ letterCounts.append(item.count) } print(letterCounts) // [5, 9, 9, 9] 5,9,9,9 // [5, 9, 9, 9] 显然,功能性方法更为简洁: […]
警告!!! :使用基本SDK> = iOS 12进行构建时不起作用 在开发iOS应用时。 您通常会遇到一个使用垂直卡片设计的应用程序,如下面的屏幕截图所示。 如果您熟悉iOS Apps开发。 您将知道有2种选择。 使用UITableView或UICollectionView。 在本教程中,我将使用UICollectionView,因为它比UITableView具有更高的可伸缩性,并且您可以在iPad中采用多列。 在WWDC 2016视频会议219:iOS 10中UICollectionView的新增功能。苹果表示,从下面的屏幕快照中收集视图单元格大小有3种方法 在本教程中,我们将使用方法1 自动布局 。 开始吧 首先设置您的视图控制器和UICollectionView。 将您的UICollectionView出口命名为viewController的4面的“ collectionView”引脚约束 由于我们将不会在情节提要中使用集合视图单元格(我们将使用nib代替),因此我们将集合视图中的项目数设置为0,并确保“布局”为“流”,因为我们将使用集合视图流布局来制作单元格自动调整大小。 接下来,创建一个用于收集视图单元格的类及其xib。 在本教程中,我们将其命名为Cell.swift和Cell.xib 别忘了将nib注册为viewDidLoad中的单元。 我们还将UICollectionViewFlowLayout的EstimateItemSize设置为(1,1),因为当设置了估算项的大小时,flowLayout将通过自动布局使用自动调整大小(这是常见的陷阱)。 现在是时候在Cell.xib中设计单元格了,如果您将单元格大小设置为想要的最大宽度(对于5.5英寸的屏幕,> 414则是安全的),如果将宽度设置得太小,应用程序将在运行时崩溃(例如。您将宽度设置为350,它将在5.5英寸的屏幕上崩溃),并为其增加一些高度(请注意,此尺寸仅用于设计时) 将UIView用作容器,以便所有视图将单元格的第4针固定到单元格。 接下来,我们如下设计单元。 确保最底部的视图和最右侧的销钉固定到容器视图。 这是单元自动调整大小所必需的。 然后我们制作单元类的出口 为容器视图宽度创建约束,并为单元格类创建出口 然后设置内容视图宽度约束,以使其与您在情节提要中设置的从笔尖减去集合视图插图中唤醒时的屏幕尺寸匹配。 我们还设置了self.contentView.translatesAutoresizingMaskIntoConstraints = false,以防止Xcode为不需要的单元格的宽度和高度生成自动布局约束。 现在,我们应该像往常一样通过将数据源添加到集合视图中进行测试并运行 示例项目在这里:https://github.com/tttsunny/CollectionViewAutoSizingTest
戴夫(Dave)的第18张kata请求我们建立一个简单的传递依赖分析器。 代码下载以及我对本系列其他片的解决方案。 关于依赖项的一个隐患是,它们是可传递的-如果A依赖于B并且B依赖于C,那么A也依赖于C。因此,让我们编写一些代码来计算一组项目的完整依赖项。 该代码将一组行作为输入,其中第一个标记是项的名称。 其余的标记是此第一项所依赖的事物的名称。 对于kata的第一部分,最好将数据结构可视化为树 在图中,A依赖于B,C,D和E。 为了使代码域特定,我为Node和DirectDependencies创建了一个类型别名。 这使得在使用代码时可视化我们所指的内容变得更加容易。 typealias节点=字符串 typealias DirectDependencies = [节点:[节点]] add方法用于加载节点及其依赖项,并将其存储在allDirectDependencies字典中。 当调用findAllDependencies(node :, directDependencies :)时,我们递归地“沿着树走”,从传入的节点开始,并跟踪所有直接依赖项。 在我们遇到循环依赖的情况之前,这种方法可以正常工作。 哪里 A依赖于B B依赖于C C依赖于A 有两种方法可以处理这种情况,第一种是检测它,但是只对每个节点进行一次评估以避免无限循环。 第二个(以及我所讨论的)是说循环依赖项是无效状态,并引发异常。 我创建一个allDependencies属性,在调用findAllDependencies方法时将其添加到初始节点。 每次通过递归循环时,我都会检查是否找到的所有indirectDependencies已存在于allDependencies中。 如果没有,我将它们添加到集合中。 如果是这样,我会跳出循环并返回DependencyError.Circular类型的错误。 有关此Kata的完善功能实现,请查看Josh Smith的解决方案。
在本文中,我将描述一种在Swift中将速度作为一个单元工作的简单方法。 音乐节奏通常以bpm(每分钟的节拍)表示,对于许多任务(如同步动画,安排声音或验证音频循环的长度),将其转换为秒通常会很有帮助。 代码 struct Tempo { var bpm: Double func seconds(duration: Double = 0.25) -> Double { return 1.0 / self.bpm * 60.0 * 4.0 * duration } } 正在使用 let myTempo = Tempo(bpm: 110.0) let quarterNoteLength = myTempo.seconds() let barLength = myTempo.seconds(duration: 1) let phraseLength = myTempo.seconds(duration: 4) 背景 过去,当我需要进行这些转换时,我记了一些笔记,翻转和取消单位,并创建了一个可以解决我的特定问题的语句。 代码看起来像这样: var bpm = […]
移动开发人员通常会遇到设备的连接问题,情况很多。 设备可能会失去其互联网连接,连接状态可能会意外更改并可能重新连接。 因此,作为IOS开发人员。 我需要可以期待这种状态的改变。 我们的应用必须处理这种状态更改,以干净的方式正确响应这些事件。 因此,我在我的Swift应用程序中使用了Ashley mills / Reachability.swift的库,我正在努力处理这种情况。 ashleymills / Reachability.swift Reachability.swift –用闭包 github.com 在Swift中重写了Apple的Reachability。 但是还有更多,我也需要处理许多实现细节。 所以我建立了一个Manager类,混合了所有可能的状态。 这是ReachabilityManager类; 因此,让我们深入研究细节。 我们想知道我们的应用程序连接在三种可能的情况下何时发生变化。 当应用未连接时, 通过Wifi连接该应用时, 通过WWAN连接应用程序时。 Manager包括Reachability提供的一种通知机制,用于观察上述的可达性更改。 因此它通知我的其他班级来管理错误状态,UI更改或更新(本文中不包括)。 您可以在那里进行自己的实现以捕获更改。 最后,如果您需要在应用启动时检查连接或您的应用需要特定情况,则可以在AppDelegate#didFinishLaunchingWithOptions中调用ReachabilityManager 。 守卫ReachabilityManager.isUnreachable()== true否则{return} 您可以使用静态方法(.ie isReachable)。 简单。 感谢您的阅读。
Swift镜像是Swift语言中功能最强大但尚未使用的功能之一。 使用动态提取类实例的元数据的能力 令人惊讶的是,Swift镜像非常简单。 下面的实现动态读取与Flower结构关联的属性,并将其打印在输出窗口上。 但是,我们要做的不只是在输出窗口上简单地打印它。 我们可以使用Swift镜像技术为简单的CRUD(创建读取更新删除)操作创建通用数据访问层。 这是使用Vapor SQLite提供程序的简单通用保存功能。 魔术发生在prepareInsertSQL函数中,该函数利用Swift镜像创建所需的sql。 在prepareInsertSQL中,我们动态创建插入实体所需的所需SQL。 用法如下所示: 现在,我们创建了一个非常基本的通用“保存”函数,该函数可以使用Swift镜像的功能来动态生成SQL并将数据插入SQLite数据库。
我的应用程序的下一步是显示字母数组中的随机字母,并在其旁边显示倒数计时器。 和按钮功能: @IBAction func nextLetter(_ sender:UIButton){ letterLabel.text = randomLetter(字母:字母) stopTimer() runTimer() } @IBAction func backToStart(_ sender:UIButton){ self.performSegue(withIdentifier:“ firstSegue”,发送者:self) } 下一步将避免重复随机字符。 我需要弄清楚我的持久性数据策略是什么。