Tag: swift

Swift GoogleMap自定义信息窗口

GoogleMap GMSMarker本身有提供资讯视窗设定简单的内容 当你想要在资讯视窗中加入更多资讯的时候就必须做一个字定义的资讯视窗 所以这时候Google SDK也有提供一个delegate 只要把你做好的InffWindow做好再回传给Delegate就好了 但如果你想要在视窗里面加一些功能可以点击的话就没有办法这样子做成 根据我查到的结果,在iOS SDK他实际上显示在画面上的东西其实是一张图片 所以你原本加好的按钮就无法点击,在Android中有提供可以关掉这种资讯视窗的方法 但iOS就是没有…所以我们现在必须把我们做出来的视窗直接添加SubView在大头针上 所以我把实现infoWindow放在GoogleMap点击大头针的Delegate中 参考资料:自定义和交互式googlemaps(IOS SDK)信息窗口

让我们在Swift 3中制作一个折线图

好的,所以您希望您的应用具有简单的折线图。 您正在四处搜寻,并为其找到了一个很棒的库(iOS图表),但是它并没有完全按照您的要求进行。 或者,您不想只为一个小图表就链接整个库。 好消息是,它们实际上很容易使自己成为现实。 您只需要了解有关使用CoreGraphics进行绘图的知识。 在这里,我将逐步引导您完成整个折线图,并确切显示每个部分的功能,以便您可以根据需要自定义它。 总共,我们正在寻找250 LOC。 我将假设您具有Swift和Xcode的基本知识。 这是最终产品。 首先,我喜欢对基本的Swift类型使用一些简单的扩展,以使事情更具可读性并简化常见任务。 在图表中,我将利用您可能要放在另一个文件中的两个扩展名。 第一个用于获取字符串的渲染大小,并始终避免以NSString进行类型转换,第二个用于递增CGPoint的x或y。 在var chartTransform: CGAffineTransform?上var chartTransform: CGAffineTransform? 。 仿射变换是采用一个点并将其通过矩阵乘法转换为另一点的矩阵。 在这种情况下,我们的图表转换将在数据的XY坐标中获取点,并允许我们在折线图视图的XY坐标中进行绘制。 我们将其设为可选,以便在绘制数据之前可以验证是否有图表变换。 要从头开始,您需要六个参数。 a和d分别缩放x和y,b和c有助于旋转(因此我们将它们设置为零),tx和ty转换x和y。 您也可以一次为它们设置2个参数,但在此不再赘述。 为此的代码即将到来。

Swift中具有半圆形状的按钮扩展

请在下面的链接下载代码 https://www.dropbox.com/s/noh7ilddkacg67n/test.zip?dl=0 扩展UIButton { func mybg(_bg:UIColor){ 让circlePath = UIBezierPath.init(arcCenter:CGPoint(x:self.bounds.size.width / 2,y:self.bounds.size.height / 2), 半径:50.0,startAngle:(CGFloat(M_PI / 4)),endAngle:(CGFloat(M_PI)),顺时针:true) 让circleShape = CAShapeLayer() circleShape.path = circlePath.cgPath self.layer.mask = circleShape self.backgroundColor = .red } } 用它 导入UIKit 类ViewController:UIViewController { @IBOutlet弱var CircularButton:UIButton吗? 覆盖func viewDidLoad(){ super.viewDidLoad() CircularButton?.mybg(_bg:.red) //加载视图后进行其他任何设置,通常是从笔尖进行。 } 覆盖func didReceiveMemoryWarning(){ super.didReceiveMemoryWarning() //处理所有可以重新创建的资源。 } }

将您的iOS应用程序网络层重构为模块

在每个项目上,总是需要改变核心服务。 这可能是由于不同的原因,对我们使用的库所做的更改,第三方/ Apple库上不推荐使用的方法,或者我们只是想迁移以开始使用新的库或API。 这种“小”变化可能会影响我们的开发速度,可能需要大量时间才能完成和/或可能会引入错误。 我们会做什么 在本文上,我们会将所有与网络相关的文件重构为一个模块。 然后,将网络服务和所有相关类迁移到动态库中,最后将使用URLSession更改为Alamofire 。 你需要知道的 要继续阅读本文,您需要熟悉以下内容: Cocoapods(您可以在此处阅读有关Cocoapods的更多信息) URLSession (很高兴知道) Alamofire ( Alamofire知) 即使您不熟悉最后两个库,您仍然可以利用本文。 初始点 您可以从这里获得本课程的起点材料。 第一 打开.xworkspace (或.xproject ,此时不起作用)并运行( command + R )。 该应用程序非常简单; 它可以让您搜索艺术家并显示其所有专辑,仅此而已。 简单直接。 现在,我们已将应用程序设为初始状态,让我们开始向项目添加动态库。 单击项目导航器顶部的项目。 现在,在“目标”窗口中,单击左下方的加号(+)。 现在一直向下滚动,直到到达“框架和库”,选择“ Cocoa Touch Framework”,然后单击“下一步”。 现在输入名称(我叫我的NetworkService),然后单击“完成”。 创建框架后,您应该在“目标”窗口和“常规”选项卡的“链接的框架和库”上看到它。 第二 现在我们有了框架,让我们将与网络服务相关的所有类移到新创建的名为“网络服务”的文件夹中(或者您将其称为框架) 太好了,现在,如果您运行该应用程序,则会在视图控制器上注意到一些错误。 修复此错误非常简单,只需在视图控制器上import NetworkService 。 再次运行该应用程序,它应该可以正常运行。 太好了,我们只是模块化了我们的网络服务。 第三 现在,该项目正在使用URLSession处理所有网络调用。 随着项目的增加或时间的推移,由于Cocoa Touch API或第三方库的更改,很有可能需要重构,更改或改编代码。 现在,让我们重构网络管理员以使用Alamofire代替URLSession 。 我们需要做的第一件事是更新Podfile […]

Swift for Ruby Devs:基础知识pt。 2

在上一篇文章中,Swift for Ruby Devs:The Basics pt。 参见图1,我们研究了最基本的数据类型在Swift和Ruby之间的语法差异。 我们介绍了变量和常量,字符串,整数和浮点数,运算符以及集合类型,例如数组和哈希(在Swift中称为字典)。 在了解了这些基本数据类型之后,我们将研究如何在Swift中编写控制流结构,以及它们在Ruby中的不同之处。 我们还将学习Swift中的方法,结构和类。 控制流程结构 循环和迭代器 在Swift中,有很多不同的机制可以遍历数组,字典,字符串,范围和其他序列。 尽管语法可能有些不同,但它们在大多数编程语言中都很常见。 如果您是Ruby / Rails开发人员,则应该已经熟悉这些内容,尤其是如果您之前编写过一些Javascript。 在大多数编程语言中,“ for-in”循环很常见。 即使Ruby也会实现它,尽管我们更喜欢其他迭代方法来编写更多惯用的Ruby。 #红宝石 #数组 生物= [“尼斯湖怪兽”,“萨斯喀彻奇”,“唐纳德·特朗普”] 对于生物中的生物 输入“您好,我叫#{creature}。” 结束 #哈希 生物= {狗:“汪汪”,猫:“喵”,donald_trump:“拥抱!”} 对于钥匙,生物的价值 放置“#{key}和#{value}” 结束 如果您以前编写过Javascript,那么您已经熟悉使用花括号打开和关闭函数,类,控制流语句等。 在Swift中也是如此,这是将Swift的语法与Ruby的语法进行比较时会注意到的主要区别之一。 //迅捷 //数组 让生物= [“尼斯湖怪兽”,“萨斯喀彻奇”,“唐纳德·特朗普”] 对于生物中的生物{ 打印(“你好,我叫\(生物)。”) } //字典 让动物= [“狗”:“ woof”,“猫”:“喵”,“唐纳德·特朗普”:“呵呵!”] 为生物中的(键,值){ 打印(“ \(键)和\(值)”) } 值得一提的是,Swift中的字典是按照相反的顺序进行迭代的,而Ruby中的哈希是从哈希中定义的第一个键值对进行迭代的。 如果您使用的是哈希/字典,那么您可能不在乎事物的顺序。 但是,在编写惯用的Ruby时,在遍历数组或哈希执行某些任务时,我们更喜欢使用“ each”,“ map”,“ […]

[车间]切换视图(快速)

目的 创建2个视图。 单击按钮并切换到新视图 方法 新建项目>简单视图应用程序 将另一个View Controller拖到情节提要 将按钮拖到第一个View Controller 单击此按钮,然后按Control键。 然后将其拖动到新的View Controller 要连接2个View Controller,可以将Action Segue设置为Show 6.要进行验证,可以将名为New View的新标签拖到新的View Controller中。 7.最终的UI设计如下所示: 测试 单击按钮,下一个视图 然后,我们切换到新视图

如何在iOS中自动检测内存泄漏

iOS开发人员面临的两个最大问题是泄漏或保留周期。 两者都可能给应用带来一些弊端,例如高内存消耗,随机崩溃,性能下降等。 因此,在Wolox,我们决定研发技术来避免这些问题,开发出功能强大的软件,并最终使开发人员的工作变得更加轻松。 什么是泄漏? 当给定的存储空间无法被系统恢复时,由于无法告知该存储空间是否在实际使用中,会发生内存泄漏。 在iOS中产生内存泄漏的最常见问题之一是保留周期。 当我们在两个或多个对象之间进行循环引用时,就会发生这种情况。 保留周期可防止释放这些对象使用的内存,即使这些对象的创建者释放了它们。 例如,如果我们有一个班级人员和一个班级公寓(如下所示) Swift和Objective-C都有一个引用计数器(ARC),负责释放未引用的内存(换句话说,就是不使用的内存)。 此过程通过计算每个对象具有的强引用来工作。 强引用将引用计数器增加一,而弱引用则根本不增加计数器(当对象的引用计数达到零时,它们会将值设置为nil)。 当实例具有零引用时,它将被释放。 但是,ARC无法检测到保留周期。 在我们的情况下,我们只有强大且交叉的引用,因此,这两个实例将永远不会被释放。 如何修复泄漏? 我们所能做的就是声明一个引用为弱引用,另一个声明为强引用,因此,循环引用被破坏了。 发现此类问题的两种常见情况包括: 案例1:关闭 情况2:委托模式 当一个对象的强引用(我们称其为ObjectA)强烈引用另一个对象(我们称其为ObjectB),而ObjectB强烈引用该闭包时,则可能发生由闭包创建的保留周期。 在下图中,我们可以看到所描述场景的表示。 情况1:可以使用`unown`或`weak`关键字来解决由闭包引起的保留周期,从而破坏循环引用。 另一方面,当未将委托声明为对委托具有强引用的弱对象时,可能会发生使用委托模式(情况2)引起的保留周期。 例如,如果我们有一个视图控制器实现了另一个对象的委托,而这个委托没有被声明为弱对象,我们将得到如下图形: 有关内存管理的更多信息,请查看以下链接:http://krakendev.io/blog/weak-and-unowned-references-in-swift 结合分析仪 在Wolox,我们使用MVVM模式使苗条的视图控制器更加有序,更小并且分开职责。 结合分析仪是我们用来检测泄漏的最早工具之一。 此过程包括评估在视图控制器中实现的绑定数量和未绑定数量之间的差异。 通过绑定,我们的意思是将视图模型的属性连接到控制器的视图出口和动作。 使用这个数字,我们可以区分发布的视图控制器和视图模型与未发布的视图控制器和视图模型。 我们必须小心,不要检测到由寿命长的对象(在应用程序的整个生命周期中保持活动的对象)引起的虚假内存泄漏,例如管理选项卡栏的视图模型。 为了做到这一点,我们有一个“注册表”来跟踪这个长期存在的对象。 该注册表是使用包含该长期对象的标识符的单例数组实现的。 另外,每次执行视图模型的绑定或取消绑定时,我们都需要注册和删除。 为此,我们还有一个带有结构数组的单例,其中包含我们注册的视图模型的数据。 此外,该类将分析是否删除了注册为“长期存在”的视图模型,该模型不应发布。 有关更多信息,请查看:带情节提要的ViewControllers中的ViewModel注入 完成registerUnbinding和registerBinding函数之后,我们可以注册绑定或取消绑定视图模型。 该方法如下: 最后,我们需要添加一个按钮来触发该工具。 实施新功能后,我们可以使用它来运行BindingAnalyzer来检查应用程序内是否存在任何泄漏。 绑定分析器工具是我们在Wolox使用的一种工具,可以产生出色的结果。 即使使用此工具,仍然有可能发生泄漏,因为每次代码库发生更改时,我们都必须手动运行该工具。 使用单元测试自动检测内存泄漏 绑定分析器工具引起的问题使我们思考如何使用单元测试自动检测泄漏。 通常,当我们添加新功能时,我们会测试其行为,但是是否会在添加新漏洞时进行测试? 在Wolox,我们将泄漏测试用于诸如视图控制器和视图模型之类的功能。 使用该技术可以省去手动检查泄漏的过程。 一种实现方法是使用Nimble和Quick。 如您所见,测试由两部分组成,第一部分负责检查视图控制器和视图模型中是否都存在泄漏。 给定一个视图控制器工厂,将创建一个引用以前模型的新控制器。 因此,它必须对视图控制器以及视图模型具有弱引用。 现在,删除与视图控制器关联的强引用并隐藏其视图。 […]

UITableViewCells的带有复选按钮的多行选择(以编程方式)

UITableViewCells具有流行的附件类型“ .checkmark”和导航的“编辑”按钮项中众所周知的编辑功能。 但是,“邮件和消息”应用程序中鲜为人知的功能之一是显示用于多行选择的圆形复选框的选项。 通过互联网组合在一起解决此问题后,希望我可以省去您的精力! 这是有关如何完成的快速演示: 在继续之前,我想提醒您仔细查看如何以编程方式添加tableView和导航栏。 您可以检查AppDelegate.swift和ViewController.swift以获取详细信息。 在viewDidLoad()中,添加以下两行。 第一行向导航控制器添加了一个编辑按钮,第二行实现了显示动画复选框的内置功能,该复选框允许用户一次选择多个单元格。 tableView.allowsMultipleSelectionDuringEditing = true self.navigationItem.rightBarButtonItem = editButtonItem 3.因为我们有不同的部分,所以我们需要实现以下功能: 4.我们只想编辑第一部分的行 5.现在我们需要告诉应用程序删除我们选择的行 6.请记住,由于tableView是子视图,因此我们需要显式更新其编辑状态 7.在底部添加带有删除按钮的工具栏 8.通过遍历所有选定的行并将其删除来实现删除按钮 您可以在此处下载整个示例应用程序:https://github.com/mrachamallu/MultiSelectExample

故事板:已批准,但不推荐

自从在iOS 5中引入情节提要板以来,关于为iOS应用程序构建界面的最佳方法的争论一直很多。 尽管UI的可视化编辑器具有许多优点,但是许多开发人员拒绝使用它们,因为它们无法应对复杂的导航和UI层次结构。 Apple通过向OS X引入情节提要来大力鼓励使用情节提要。实际上,Apple Watch现在已要求使用情节提要,并且所有iOS项目模板默认都使用情节提要。 Xcode的最新更新甚至比以前选择在新项目中退出情节提要更耗时。 在Maxwell Forest,我们禁止使用情节提要板来支持程序化布局。 虽然我们可以看到将故事板用于小型项目和单独开发人员的好处,但我们发现在较大的团队环境中,故事板有很多缺点。 紧随其后,了解使用情节提要的利弊很重要。 长处 1.可视化 情节提要是出色的可视化工具,可封装视图表示和它们之间的过渡(segue)。 组织良好的情节提要可以轻松地从高层次了解应用程序流,功能以及应用程序中的视图如何协同工作。 这种可视化可以使刚接触项目的开发人员更容易掌握最新信息。 一个有效用于简单应用程序的情节提要 2.简单性 故事板也非常适合初学者,因为它们易于设置,并且只需最少的代码即可实现许多功能。 即使没有对自动版式的全面了解,简单的界面也可以快速实现,并且拖放界面对于人们学习如何开发比通过编程方式创建版式更加直观。 3.原型制作 Interface Builder具有强大的实用性:它可以使开发人员在没有设计背景的情况下设计出外观合理的UI。 它还允许熟练的设计人员对应用程序进行原型设计,并在工程师充实数据模型并微调UI细节之前将其显示给利益相关者。 弱点 情节提要的简单性和易用性很好,但是在开发更复杂的应用程序时,这也是它们最大的弱点。 在开发复杂的视图层次结构和交互时,尤其是在团队中工作时,Interface Builder的文件结构,工具和稳定性远非理想。 1. Interface Builder的稳定性和怪癖 Interface Builder已经走了很长一段路,但是仍然有其缺点。 例如,它不能在单个情节提要文件中处理大量屏幕,从而产生滞后并经常导致Xcode崩溃。 往返于关键视图控制器之间需要大量测试的应用程序流程可能很快就会陷入混乱,使在情节提要图板之间难以导航。 使用时,Interface Builder中的大多数操作都需要100%缩放,这进一步降低了可用性,尤其是在视图控制器之间拖动以创建序列时。 通过将情节提要分解为多个文件可以缓解这些问题,但是仍然难以管理,并且降低了情节提要作为可视化工具的有效性。 用于复杂UI的情节提要板可能很快变成一团糟 2.没有清晰界面的代码划分 当开发复杂的UI时,将实现分成两个文件,视图控制器和情节提要会使调试和维护变得烦人。 任何工作都需要在代码编辑器和Interface Builder之间进行上下文切换。 在繁忙的大型故事板上,这可能会令人厌烦并且令人生厌。 3.可重用性 可重用性在软件项目中对于减少重复,增加可维护性和错误至关重要。 故事板鼓励使用重复的视觉设计,并手动更改单个元素而非元素类别的属性。 为了使用情节提要板达到可接受的可重用性水平,必须将它们与NIB或程序化UI设计结合使用。 4.单个文件和合并冲突 对于任何严肃的开发,情节提要的最大缺点是它们是包含应用程序多个视图的单个文件。 在团队合作和使用源代码管理时(这应该一直如此),这会产生戏剧性。 只有一个文件意味着合并冲突要普遍得多,当必须使用XML处理冲突时,合并冲突会变得很混乱,这在使用Interface Builder进行更改后会变得非常棘手。 烦人的是,如果开发人员使用不同版本的Xcode,仅打开情节提要板文件将创建更改,这将导致合并冲突! 可以说,通过合理的任务管理可以使合并冲突最小化,但是大多数应用程序的大部分UI流程都集中在几个主屏幕上,并且大多数情况下,多个开发人员将在彼此非常接近的区域工作。 […]

NSTimer代表NoSwiftyTimer

NSTimer是Apple提供的创建计时器的最简单机制之一。 您可能已经看到它适用于多种用途:在一定的延迟后显示或隐藏视图,定期更新的视图或周期性或延迟执行的任何其他任务。 毫无疑问,它们是非常通用且功能强大的工具。 NSTimer基本上只是在等待特定时间间隔之后,然后将特定消息触发到其目标。 如您所见,我在这里谈论消息和目标。 这是第一个问题出现的地方。 目标和消息听起来不是很迅速,对吗? 最近,我不得不使用NSTimers,我发现了一些令人讨厌的细节。 首先,正如我们所看到的,它具有基于Objective-C运行时的非常古老的时尚语法,使用目标和选择器而不是闭包,这使它们在我的Swift代码中看起来像一条鱼。 另一方面,更重要的是,如果您不关注ARC,则NSTimers是在应用程序中引入内存泄漏的最简单方法之一。 为什么? 好吧,请检查以下示例: 从NSTimer到SwiftyTimer 苹果在NSTimer的文档中留下了非常明确的信息: 子类化注释 :您不应尝试将NSTimer子类化。 由于这个原因,我决定使用组合来创建我的自定义Swifty版本的NSTimers。 基本上将它们包裹起来,将其讨厌的部分扫到地毯下。 但这将使我能够解决这两个问题,获得更快捷的语法并更容易避免内存泄漏。 使用这个简单的包装器,我们能够以非常简单且易读的方式避免来自计时器的强烈引用。 再一次,如果您将此代码复制到操场上,您将看到它现在生成另一个输出: 你好 再见 多亏了附加层,我们得以避免内存泄漏,因为NSTimer现在保留的不是使用计时器的代码,而是SwiftyTimer的实例。 当然,我们在SwiftyTimer和NSTimer之间仍然有一个保留周期,但是通过使用SwiftyTimer的invalidate方法,我们可以轻松打破这一局面。 在这一点上,快速化定时器的使用,使用参数的默认值并利用闭包是一项非常容易的任务。 最后获得一个更具可读性和更少错误的解决方案。 结论 Apple可能(并希望)很快会给仍然需要它的那些API带来所有的爱和温柔,但是与此同时,它们是创造力的好借口,因此获得了更具可读性和安全性的代码……害羞! 如有任何疑问,请随时在github,twitter或dcordero.me上添加我。