Tag: swift

Swift中的回调– TableView和CollectionView的实际示例

您非常喜欢某件东西,因此您始终希望围绕它。 所有程序员都沉迷于某种东西,如果您是iOS开发者,那么当您被介绍到UITableView和/或UICollectionView ,您将UICollectionView 。 当您使用UIScrollView危险时,您会更加爱他们(我是说😢)。 我已经看到程序员非常喜欢某些数据结构(即enum , struct ),以至于他们只能思考。 这种爱带来了一些在别的事情的帮助下做某事的非常酷的技巧。 因此,在开始快速讨论之前,让我更新前面提到的报价, 您非常喜欢UITableView和/或UICollectionView ,以至于即使是简单的输入FORM看起来也UICollectionView 。 请参阅此非常简单的表单以获取用户输入。 它具有一些文本字段和一些标题标签。 可以使用UIScrollView在本地UIViewController轻松设计和维护(适用于较小的屏幕)。 但是,如果您喜欢TableView,那么您会发现它也可以很容易地实现。 我认为它具有一些明显的优势 。 但是让我们看看这怎么可能是一个实施问题。 表单的设计和表示形式与自定义单元格类完全没有问题,但是问题是如何将数据从custom cell对象传输到TableViewController对象。 我将通过图表显示。 现在,可以通过多种方式将输入文本返回给Parent ViewController 。 我们可以使用protocol声明, Notification userInfo等来实现。但是今天,我将讨论一种通过回调函数完成此操作的巧妙方法。 现在,在各种平台和语言中以各种方式定义了回调。 简单地说,回调会将某些内容返回给调用方。 它可以返回值,引用,函数或返回自身。 好的好的。 我说话太多了。 让我们看一些代码。 假设这是一个自定义UITableViewCell类 由名为UserController的UITableViewController实例化。 我们可以在控制器中UITableViewDataSource cellForRowAtIndexPath方法中执行此操作。 让cell = tableView.dequeueReusableCell(withIdentifier:“ singleTfCell”,for:indexPath)为! SingleTfTableViewCell cell.staticLbl.text =“公司” cell.inputTf.text = company ///如果表单处于编辑用户信息模式 返回单元 我们知道。 来吧,已经显示了回调!! 是的,我要去。 […]

成为一名优秀的技术大使– Matt Massicotte –中

成为优秀的技术大使 最近,围绕Swift的Apple开发人员世界也进行了大量讨论。 最近关注的焦点是缺乏动态功能。 考虑到Objective-C的动态性以及围绕该功能构建的Apple API的数量,我认为这是一个特别有趣的讨论主题。 在这个主题上有一些相当体贴的文章,我很喜欢阅读它们。 但是,正是这种问题的性质使我发现了最有趣的问题。 也许不足为奇,编程语言具有口头语言的某些特质。 文化围绕着它们发展,通常具有非常独特的方面。 我认为部分原因是由于Objective-C的动态功能,它具有独特的文化。 特别是对于已经使用了一段时间的用户。 由于Swift在哲学上与Objective-C不同,因此在文化上也有所不同。 这将使某些人感到震惊。 但是,我们知道即将到来。 多年以来,Objective-C的纯粹活力已荡然无存。 将此错误作为证据: 当然,出于充分的理由这是非法的。 编译器需要有关使ARC工作的方法签名的更多信息。 但是,在引入ARC之前的一段时间,这个特殊的结构成为了警告。 我的意思是无论是形象上还是字面上。 正是编译器试图帮助您防止出现明显的错误。 但是,这也是不鼓励使用最动态功能的一种方式。 这表明文化正在发生转变。 这绝对让我震惊。 宣布Swift时,我大为震惊。 即使我看到了它的到来,也知道这是必然的(http://arstechnica.com/apple/2010/06/copland-2010-revisited)。 我开玩笑花了几个月的时间来完全处理新闻和含义。 Objective-C既怪异又充满活力,一旦掌握了它,我就会觉得自己在使用非常不同的东西。 我喜欢那个。 如果您像我一样,就已经对该工具产生了情感上的依恋。 也许是非理性的。 但是不可否认。 对我而言,Swift感觉更像是C ++的衰落者,而不是Objective-C。 而且,鉴于情况,我认为这是完全合理的。 所有的LLVM和Clang都是用C ++编写的。 我怀疑苹果的编译器团队在设计Swift时显​​然考虑了Objective-C,但他们内心却是C ++。 所以我们到了。 我们不在Objective-C 3.0的那个替代维度上。 这不仅仅是目标/动作范式。 不仅仅是Swift需要动态性,或者它是不必要的。 有很多技术上的原因说明这种过渡会很好。 但是,您还必须承认过渡​​不仅是技术上的。 这是情感的。 这是关于放开您可能依附的东西。 如果感觉不太好也可以。 我希望我们认真思考为什么要进行类型战争。 为什么对使用动态类型的个人发表尖刻的评论。 我们很想对Objective-C说好话。 谢天谢地,对不对? 有更好的方法。 苹果建立了融合不兼容技术的迷人历史。 […]

模仿Haskell的列表模式

阅读之前,请注意,无需具备Haskell或函数式编程的先验知识。 文章 最近,我一直在试验Haskell,尤其喜欢一种功能-列表模式匹配中的(x:xs),其中x是当前元素,即所谓的“ head”,而xs是其余元素列表,即所谓的“尾巴”。 下面是一个示例,其中包含提到的功能,即列表的长度方法: 话虽如此,我开始怀疑用另一种语言实现此功能是否有用。 下一个代码段是尝试在Swift中“模仿”它: 如您所见,这两种方法都是“ Array”类型的扩展。 我称之为第一个(因为无法给出更好的名称)递归,它返回一个由可选元素(称为x)组成的元组,而数组的其余部分称为xs。 X是可选的,因为在某个时候可能还没有实际的元素。 它的身体是不言自明的:self.first是当前的头,self.dropFirst将返回“尾巴”。 但是,dropFirst的返回类型是ArraySlice而不是Array,因此是map方法。 现在,在某种程度上模仿了Haskell的功能,可以实现它的长度。 一般情况是返回1加上当前“迭代”末尾使用长度的结果,请参见示例2,l。 9.上面两行是列表为空并返回0或head元素不存在的情况,这意味着它等于null并仅返回1。 尽管它的实现方式不如Haskell中的原始方法那么优雅,但它可以在某种程度上对我产生吸引力。 我自己,我真的没有看到像Swift这样的语言进行递归的优势,我的一些认识Swift的朋友也没有。 但是,这可能是一种吸引人的设计模式。

简单的每设备NSLayoutConstraint常量

设计人员将您交给一个Sketch文件,然后您便开始将其转换为Interface Builder。 除非您发现设计人员希望为iPhone SE,常规设备和Plus设备设置不同的间距,否则这很简单。 您喜欢自动布局,并且知道在这种情况下Interface Builder的紧凑和常规版本无法提供任何帮助。 是时候解决这个问题了! 首先,拖出约束的IBOutlet并添加代码以使用测试屏幕尺寸的switch语句更新其常量 。 uck IBOutlet很脆弱。 您抛出IBOutlet并命名约束。 然后添加一些代码以通过其标识符查找约束。 也许更好。 但是所有这些都可以在代码中完成! 我们正在使用Interface Builder。 如果我们可以在IB中为约束设置每个设备的值,那就太好了! 像这样: 这是一个很大的帮助。 我们需要的是对NSLayoutConstraint的扩展! 这将3个变量添加到NSLayoutConstraint。 当UIKit加载XIB / Storyboard时,如果您在IB中设置了一个或多个这些变量,则将调用setter。 每个设置器都会检查当前屏幕大小以查看是否适用,如果适用,则更新约束的constant 。 如果您尚未为这些变量中的任何一个设置值,则约束的常数就是IB中设置的普通值。 这很棒; 您只需为具有不同设计值的约束条件设置这些新变量即可。 IBInspectable神奇地使变量出现在Interface Builder…中(感谢http://uibyblue.com指出了这一添加)。 一个有用的,微不足道的扩展是添加仅适用于3.5英寸显示器的第四个变量。

跟踪Swift编译时间

通常,您需要向财务部门证明如何为您提供新的笔记本电脑会提高生产率。 使用此脚本,您可以确切地向他们显示等待Xcode花费时间的时间。 #!/bin/bash 让我们开始一个新的BASH脚本。 在脚本的整个生命周期中,它应大约运行swiftc (Swift编译器)运行的时间,并应与Xcode项目完全脱钩。 当我们在这里时,让我们获得其他一些有趣的统计信息,例如最长的构建时间和我们编译代码的次数。 首先,我们需要声明我们的变量。 让我们在脚本顶部编写该代码,以便在需要时可以轻松地对其进行编辑: INTERVAL = 5#采样率,以秒为单位 COMPILE_TIME = 0#总编译时间 ALL_TIMES =()#所有编译时间的数组 PREV_TIME = 0#临时存储 在这个阶段,我正在想象该脚本没有自然的退出点-它会一直运行,直到您从终端用^C (control + c)杀死它为止。 我们应该截获(也就是“捕获”)此中断信号,处理我们收集的数据,打印它,然后退出脚本: #当用户键入^ C时, #运行函数ctrl_c而不是退出 陷阱ctrl_c INT 函数ctrl_c(){ #找到最长的构建时间 最大= 0 对于$ {ALL_TIMES [@]}中的v; 做 如果(($ v> $ max)); 然后max = $ v; fi; 完成 #很好地格式化我们的数据 TIME_SPENT_S = $(日期-u -r $ max […]

Unity —如何搭建桥梁:iOS到Swift的Unity

通过添加ARKit和iOS 11中的Core ML,能够将iOS功能桥接到Unity中,使您作为开发人员能够获得更强大和独特的产品体验。 在ustwo建立实验时,我们必须创建一个自定义屏幕录制功能,该功能涉及尚未桥接到Unity中的iOS功能。 结果是使用iOS的ReplayKit API记录游戏玩法,保存记录并将文件传递回Unity的桥梁。 源代码在这里:ReplayKitUnityBridge 在DemoUnityAndReplayKit文件夹中运行DemoScene 将Xcode的“构建设置”中的Swift版本设置为4.0,以便正确构建* 步骤1:如何从Unity向iOS发送消息 首先打开Xcode> New Project> Cocoa Touch Framework 将该项目命名为“ ReplayKitUnityBridge” 在左上角显示“ ReplayKitUnityBridge”。 右键单击->单击“新建组” 右键单击您的源文件夹,然后单击“新建文件”> Swift文件 将您的新文件命名为“ ReplayKitNative ” 将以下内容添加到您的ReplayKitNative.swift文件中 进口基金会 导入UIKit 导入ReplayKit @objc公共类ReplayKitNative:NSObject { @objc静态让共享= ReplayKitNative() 私人let screenRecorder = RPScreenRecorder.shared() 让kCallbackTarget =“ ReplayKitUnity” @objc func startScreenCapture(){ self.screenRecorder.startRecording {(错误)在 // UnitySendMessage(kCallbackTarget,“ OnStartRecording”,“”) } } 让我们回顾一下上面的代码: 使用@objc标志来标记要公开给Objective-C和Unity的内容 @objc公共类ReplayKitNative:NSObject @objc静态让共享= […]

自动布局Swift 3

Un enquequevíacódigo ¿Quées el自动版式? 在自动布局和手动模式之间,在手动和手动模式下进行可视化。 Hay dos Implementaciones del Autolayout,无需使用Storyboard或Apple llama的InterfaceBuilder,也可以使用基于锚点的方法进行操作 。 安博斯(Ambos)征服了儿子的证明,并证明了他在西班牙的保护性和合法性。 界面生成器 Echemos un vistazo a la manera como funciona Interface Builder。 Cuando abrimos和Storyboard aparece un rearea se de no nos mover las vistas y empezar a jugar con ellas。 阿奎斯·唐德·科多恩扎 弱势群体,维莫斯·辛科·埃尔拉门蒂斯·德·伊基奎尔达·德·雷科查·阿尔·佩雷斯,《现实世界》,《限制条件》,《反对革命》,《反对派》,《 Herramienta podemos reubicarlas。 StackView上的segundo icono es para agrupar las vistas seleccionadas […]

具有命名关联值的快速枚举

快速枚举是解决许多问题的强大工具,因为它们可以提供自定义方法,并且每种情况都可以包含关联的值。 分配一个期望有多个参数的案例可能会变得相当混乱,而我的印象是,人们对此无能为力。 但是事实证明, 具有关联值的快速枚举可以具有命名参数 。 在快速的沙箱中尝试: IBM Swift沙箱 一个交互式网站,可让您在Linux之上的服务器环境中编写,执行和共享Swift代码! swiftlang.ng.bluemix.net 或使用以下要点作为参考: 开心飞驰!

动态架构和集合视图

在本文中,我将主要讨论UICollectionView,但它也将与UITableView一起使用。 主要问题 UICollectionView的最大问题之一是单元,控制器和模型之间的依赖关系。 如果架构不好,则所有内容都在控制器中,很难更改任何内容。 但是,UICollectionView的目标是显示具有不同设计和数据的UICollectionViewCell。 解 解决方案之一是使用MVVM软件架构模式,如果您不知道它是什么,可以在此处学习一些技巧。 让我们看一个具体的示例,该示例说明并显示如何解决上面看到的问题。 该项目显示一个简单的集合视图,该视图显示具有不同设计的电影列表和一些广告。 ($$$$) 您可以在此处找到该项目。 建筑 如您所见,这里不仅包含ViewController和单元,而且由于每个类的职责也将更加清楚! 我将逐一解释每个班级的责任。 视图模型 这个ViewModel的目的是通过遵守UICollectionViewDataSource协议来告诉控制器它必须显示什么以及何时必须通过ViewModelDelegate显示它。 在我们的项目中,ViewModel将提供要显示在UICollectionView中的项目列表。 视图模型的简单实现示例 首先,我们调用viewModelDidStartLoad委托方法以在屏幕上显示加载程序或任何内容。 然后,我们添加项目并调用viewModelDidLoad委托方法以刷新屏幕。 ViewController 通常,每个控制器都有一个ViewModel。 惰性变量viewModel:ViewModel = ViewModel(委托:self) ViewController实现UICollectionViewDelegate和自定义ViewModelDelegate 。 ViewModelDelegate实现的示例 当数据准备好显示时,此类必须遍历所有项并将它们注册到collectionView中,如您所见: 通过项目在集合视图上注册单元格 CellItem 每个项目都处理一个单元格,并且必须遵守协议CellItem。 单元项协议 如您在上面看到的,该项目必须: 知道重用标识符 了解XIB来加载单元 配置单元(显示数据) 知道细胞的大小 将单元格注册到集合视图 通常, register和cellNib方法总是相同的,因此我们可以创建协议的扩展以具有默认实现。 MovieCellItem 让我们看一个带有MovieCellItem的更具体的例子。 在此类中,我们有一种类型可以帮助我们加载特定的XIB,但是CellItem协议的实现非常简单。 如果您必须处理单元内部的特定交互,则最好在项目中进行。 例如,该项目可以是单元格拥有的UITextField的委托,并通过特定协议,数据块或您喜欢的任何数据将数据直接传递到ViewController或ViewModel 。 细胞 细胞几乎什么都不做! 它们仅具有IBOutlet,并可以根据需要在aakeakeNib()或prepareForReuse()方法中自定义设计。 MovieCell类:UICollectionViewCell { @IBOutlet弱var imageView:UIImageView! @IBOutlet弱var […]

[Swift 3]协议

部分内容笔记。 协议类型 协议作为类型,可以考虑集合宣告的一部分,也可以作为变数宣告的一部分,表示该变数本身是什么类别,但必定遵守此协议,另外也可以用down的语法来处理它。 可选协议要求 您可以为协议定义可选要求。遵循此协议的类型不用一定要实作这些可选要求。可选要求的定义方法是在协议的宣告前面加上可选的修饰修饰词。 使用上,当你的协议里面的成员为可选要求时,该成员前面要加上@objc,并且该协议的宣告前面也要加上@objc。 @objc协议SomeProtocol { @objc可选的func someMethod() } 需要注意的是,这代表这些属性和方法的类型都是可选的。因为你可以不实作,那表示这值可能就是零,方法也有类型,由参数和回传值组成,例如(Int)-> String,这时就会变成((Int)-> String)? @objc协议SomeProtocol { @objc可选varstoreProperty:整型{get} @objc可选func someFunction()->字符串 } 加上optional表示有没有实作都可以,所以使用上要配合可选链,如果是可选功能,要在呼叫时,于括号前加上问号。 如果让文字=采用ClassInstance.someFunction?(){ 打印(文字) } 加上@objc表示要和objective-C协作,协议前面也需要注记@objc 。这样的协议只能由继承自objective-C或其他@objc的类别遵守。无法由结构或枚举来遵守。 @objc类SomeClass:SomeProtocol { } 协议扩展 通过由扩展,让您可以定义协议的行为,而不必在每一个遵守该协议的类型或者在全局函数里面去实作这些行为。 这里稍微和你直觉想像的协议的扩展不同,协议的扩展是可以提供具体的实作的,你可以想像这个扩展是将所有采用某个扩展协议的类都外加一些属性或者方法。可以说是对全部符合此扩展协议的类的扩展。 扩展SomeProtocol { 有趣的description(){ 打印(someFunction()) } } 到这边你可以想像说,那扩展可不可以让protocol的要求的属性或者方法有时序的实作呢?当然可以,在符合类型提供自己的实作之后,这样的实作就会被替代掉,反之,conform type没有提供需要的实作的话,就会采用时间表的实作。 向协议扩展添加约束 你可能不希望扩展协议可以适用于所有的符合类型,你可以加上一些限制,踩到让那些符合类型获得扩展协议。在内部定义的实作之前,进行检查。你会使用where这个通用子句(参考这里)。