Tag: swift

Swift 3.0:专用与文件专用

私人的 根据Apple的文档,“私有访问将实体的使用限制为包含在声明中。”私有访问是最严格的访问级别。 基本上,这仅意味着您无法在定义私有实体的范围之外访问私有类型/功能/属性。 在下面的示例中,由于var visibleButton和func getAge()都在PrivatePerson类中定义,因此我们可以在PrivatePerson类的整个范围内访问这些函数。 但是,我们无法访问PrivatePerson扩展内的那些实体,因为该扩展不在定义私有实体的类的范围之内。 根据上面的知识,您能解释为什么我将handleTapGesture函数设为私有吗? 由于handleTapGesture函数是一个辅助方法,将仅由扩展中的configButtons()函数调用,因此,我决定仅对扩展访问函数。 如果我尝试在类的定义内调用handleTapGesture函数,则会收到“由于’私有’保护级别而无法访问”错误。 文件私有 根据Apple的文档,“ Fileprivate访问将实体的使用限制为自己定义的源文件。”如果您熟悉Swift 2.0,则fileprivate等同于Swift 2.0的私有文件。 文件私有和私有之间的主要区别如下所示。 可以在整个文件中访问Fileprivate实体。 在下面的示例中,即使在FileprivatePerson类中定义了var invisibleButton和getName(),我们仍然可以在FileprivatePerson扩展中访问它们。 您可能想知道为什么从未将实体定义为私有/文件私有,并且从未收到任何警告。 这是因为Swift的默认值为“内部”,这意味着实体(类型/功能/属性等)可被包括实体定义的整个应用/框架访问。 就您对所编写代码的体贴程度而言,将实体定义为私有/文件私有只是迈出了一步。 编码愉快! 🤓

在Swift中隔离任务,或如何创建可测试的网络层。

在过去的几年中,有许多闪亮的iOS体系结构越来越受到人们的炒作。 因为它们都是有效的,并且有好有坏,所以它们都解决了同一件事: 将业务逻辑与表示分离。 今天,我将写一个简单的概念,该概念适用于您下一个项目的架构,无论您打算使用哪种架构。 相当普通的网络层 为了解释我的观点,我将首先谈谈通常如何实现网络层。 我见过很多不同的网络层。 在大多数情况下,都有NetworkManager,ConnectionManager或类似的东西。 有一个类包含应用程序中的每个API调用。 尽管这是有效的并且可以正常工作,但它并没有遵循软件设计的核心概念: 单一职责。 ConnectionManager包含太多职责,因此不被认为是好的做法。 而且,它通常实现为单例。 我并不是说单例不一定很坏,但是不能将它们作为依赖项注入,并且在测试时不能轻易模拟。 这是非常常见的做法。 我也在MVVM或MVP架构中看到了这一点。 不同的方法 数据访问层可以以不同的方式实现。 让我们描述网络获取的过程: 这样,网络调用至少包含三个步骤: 创建一个请求 :这意味着设置URL,方法,参数(在URL路径或http正文中)和HTTP标头。 发货请求 :这是非常非常重要的一步。 必须使用URLSession或其上的一层(例如Alamofire)调度在上一步中创建和配置的请求。 获取和解析响应 :重要的是,此步骤应与前两个步骤分开实施。 在这里,您应该验证JSON或XML响应,然后将其解析为有效的Entity(如果愿意,也可以解析为Model)。 如果您确实希望您的体系结构干净且可测试,则应在不同的对象中实现这三个步骤。 这些对象如下: Request : Request对象具有配置网络请求所需的一切。 它是负责配置单个网络请求的结构或类。 这非常重要: 一个网络请求,一个 Request 对象。 NetworkDispatcher : NetworkDispatcher是一个对象,负责获取Request并返回Response 。 它应该作为协议来实现。 您应该针对该协议而不是针对具体的类(或结构)进行编码,并且永远不应将其实现为单例。 如果执行此操作,则可以将该NetworkDispatcher替换为实际上不发出任何网络请求的MockNetworkDispatcher ,而是从JSON文件获取响应,从而形成自然可测试的体系结构。 NetworkTask : NetworkTask是通用类Task的子类。 正如我将在稍后更好地解释的,任务是一个通用类,它负责以同步或异步方式获取Input类型并返回Output类型。 您可以使用RxSwift,ReactiveCocoa,Hydra,Microfutures,FOTask或仅使用闭包来实现Task 。 由你决定。 这里的重要部分是概念,而不是实现细节。 实施请求 […]

如何:创建一个UIPageViewController

创建UIPageViewController的步骤—代码行= 60 故事板 将UIPageViewController拖到情节提要上。 将所需的页面数的View Controller拖动到情节提要上 为情节提要ID和恢复ID设置名称 码 4.创建UIPageViewController类,并继承UIPageViewController,UIPageViewControllerDatasource和UIPageViewControllerDelegate 5.添加数据源所需的方法 故事板 6.在情节提要中将UIPageViewController设置为其自定义类名称,即您刚刚在代码中创建的名称 设置过程完成。 现在介绍实现UIPageViewController的功能的实现。 码 设置数据源和UIPageViewController的委托 创建一个函数以检索视图控制器(应用程序的页面) 创建一个延迟实例化的数组:通过调用我们刚创建的函数来填充每个索引 在viewDidLoad中:从数组的第一个索引设置UIPageViewController的第一个视图控制器。 数据源方法 5.在viewControllerBefore中: 检查条件 如果在上一个索引处有一个视图控制器,那么您可以向后滚动 如果页面数量大于“ 0”,那么如果不是,则可以从0索引滚动到最后一页 如果先前的计数以某种方式超出了pages.count的范围,则返回nil,这样应用程序不会崩溃。 从数组索引返回ViewController 6.在viewControllerAfter; 逻辑与inViewControllerBefore相同,但滚动方向相反 可选:将滑动类型从页面卷曲(如大多数电子书)更改为滚动(如大多数应用程序)。 可以在UIPageViewController的情节提要属性检查器中完成此操作 UIPageViewController实现

框架如何在macOS上工作

即使约束几乎是在macOS / iOS和tvOS上构建UI的默认设置,在某些情况下,框架仍是首选。 macOS上的帧操作与其对应的帧操作非常相似。 与CGRect一起使用时,您会看到对NSRect的引用,但实际上这只是CGRect的类型别名。 但是,存在一个根本区别,就是坐标系被翻转,或者更确切地说,它在iOS和tvOS上被翻转。 这意味着值为零的x坐标始于其超级视图的底部,而不是其顶部。 值得注意的是,这只会影响x坐标,y坐标的工作方式与您期望的一样。 如果您习惯于在iOS和tvOS上计算帧,那么反过来做所有事情都会是一个挑战。 幸运的是,Apple为我们引入了一个属性,以便在我们想要翻转坐标系时覆盖它,以便x坐标或零表示子视图的顶部。 让我们快速看一下一个非常简单的NSView示例中的外观。 从图像中可以看到,子视图位于左下角。 仅需一行代码,我们就可以反转容器视图以获得所需的行为。 如您所见,我们仅添加了isFlipped的覆盖并将其设置为返回true 。 让我们看看文档中关于isFlipped属性的说法。 此属性的默认值为false,这将导致坐标系不翻转。 在非翻转坐标系中,原点位于视图的左下角,并且正y值向上延伸。 在翻转的坐标系中,原点位于视图的左上角,y值向下延伸。 X值始终向右延伸。 如果希望视图使用翻转的坐标系,请覆盖此属性并返回true。 https://developer.apple.com/documentation/appkit/nsview/1483532-isflipped 因此,通过覆盖该属性,该视图坐标系内的所有内容都将被翻转。 请确保注意,将其他子视图添加到基础子视图将不会继承此子视图,并且如果您还希望翻转那些子视图,则必须重写相同的方法。 为了说明我的意思,让我们看一个最后的例子。 就是这样,在macOS上进行基于帧的计算时,不再麻烦。

我为什么要成为一名编码员?

那是1993年。我刚从高中毕业。 我当时正在上大学考试课程。 一位来我父亲的理发店的顾客使我在接下来的25年中从事职业。 直到那天,我只触摸了Commodore 64和Sinclair ZX Spectrum的键盘,这些键盘无法正常工作。 我一直想成为计算机科学工程师。 当我开始从事这项工作时,我仔细地看着德语老师,他有时用Turbo Pascal写作,有时用GWBasic写作。 我对DOS的了解来自那些日子。 我可以设法赢得大学入学考试。 但是我研究的部门距离计算机很远。 大学第二年,我看到了我对语言学的兴趣。 我认为,这是因为我对计算机和语言感兴趣。 在我职业的20年中,我尝试学习Objective-C。 过了一会儿,斯威夫特出现了! 我立即开始学习这种语言。 我找不到时间写Swift(仍然不能),因为我不愿担任图形设计师。 下班后,当我回家时,由于我的孩子,我也找不到时间。 几乎没有时间进行处理。 但这对我来说还不够。 我内心充满饥饿感,就像对情人的一种激情。 当我闭上眼睛,我看到一些飞行代码。 一年前,我的一个朋友建议我学习Ruby on Rails。 我非常喜欢这种语言,以至于我也有同样的感觉。 我一直在脑子里写作。 那太饿了 我申请了工作。 我愿意少花钱。 我只想写代码。 那是我的梦想。 但是他们通常没有任何答案。 我最终还是菜鸟,没有人愿意雇用菜鸟。 没有人知道在我内部进行编码的热情。 我买了二手MacBook Pro。 我正在编码。 我编辑了第一个WordPress主题并将其出售。 我有一个家庭及其生活,我必须赚钱。 当然还有账单。所以我需要我的工资,这是我从平面设计中获得的独特收入。 即使我不再喜欢它,我也必须去做。 退休时间更少了。 之后,我想拥有自己的工作或为想要与我一起工作的人担任编码员。 但是与此同时,如果我是失业者,该计划将更改为“现在!”! 感谢您的阅读。

设置Swift和Objective-C互操作性

3.在此处添加要在swift类中使用的Objective-C类的导入头。 将头文件包含在Bridging头文件中后,就无需将其重新导入到任何Swift文件中。 可以在项目中的所有swift文件中访问它。 现在,您选择的Objective-C对象可用于您的快速班!! 做得好!! 使用Swift和Objective-C时要谨记的事情 Swift和Objective-C有一些根本的区别,在使用两种语言进行工作时,需要牢记一些非常重要的事情。 为了使从一种语言到另一种语言的过渡最顺畅,最好记住它们的独特功能。 Swift和Objective-C之间的区别 如果swift类中的方法或变量没有出现在Objective-C文件中,则可能是因为Objective-C不支持确定该方法或变量的特定功能。 以下是在Objective-C中不可用的Swift功能的简短列表:在swift中定义的元组,泛型,任何全局变量,结构,类型别名或枚举,以及顶级swift函数。 解决这个问题的一种方法是创建一个包装器类,该包装器类可以处理这些不可用的功能,并在与Objective-C类进行交谈时被调用。 子类限制 局限性之一是无法从子类快速分类。 Swift对象可以具有Objective-C类的子类,例如NSObject。 但是,快速类不能成为Objective-C类的基础类。 种类 幸运的是,objective-C类型和swift类型彼此之间具有很好的对应性,并且可以跨语言很好地进行翻译。 选装件 可选状态是Objective-C和Swift之间在功能上非常重要的区别。 当您从Objective-C将参数传递给Swift类时,Swift必须知道变量的可选状态。 在Swift中,任何事物都可以保持未定义状态,甚至可能为零。 由于Objective-C不满足此要求,因此传入的参数可能会自动后面跟一个!。 或爆炸符号,或其他更严重的问题和错误可能会发生。 理想情况下,您应该设置某种方式来检查要快速传递的每个变量的可选状态。 将属性传递给swift时,您可以采取的一种初步措施是在Objective-C类文件中从一开始就声明非null或可为null。 @属性(非原子,强,非空)NSString * name; 这使swift文件知道该变量在收到后不会为null。 作为捷径,您还可以指定整个文件为非空或可为空。 在文件的@interface之前添加以下行。 NS_ASSUME_NONNULL_BEGIN 然后在@end之后添加下一行。 NS_ASSUME_NONNULL_END 感谢您的阅读! 有用的链接和来源: 将Swift与Cocoa和Objective-C(Swift 3.1)结合使用:基本设置 描述Swift与Objective-C语言和Cocoa / Cocoa Touch框架的兼容性的各个方面。 developer.apple.com Swift和Objective-C:永远的好朋友? 我们很高兴在我们的SLUG聚会上欢迎Jonathan Blocksom。 经验丰富的行业资深人士,乔纳森(Jonathan)具有真正的… realm.io 将Swift与Cocoa和Objective-C(Swift 3.1)结合使用:与Objective-C API交互 描述Swift与Objective-C语言和Cocoa / Cocoa […]

使用Swift自定义iOS中的导航栏

更改导航栏颜色 为了更改所有视图控制器的导航栏颜色,必须在AppDelegate.swift文件中进行设置 将以下代码添加到didFinishLaunchingWithOptions函数中 var navigationBarAppearace = UINavigationBar.appearance() navigationBarAppearace.tintColor = uicolorFromHex(0xffffff) navigationBarAppearace.barTintColor = uicolorFromHex(0x034517) 在这里tintColor属性更改导航栏的背景颜色 barTintColor属性影响颜色 后指示器图像 按钮标题 按钮图片 此代码不会影响导航栏标题的颜色。 它仍然保持黑色 更改导航栏标题的颜色 将以下代码添加到didFinishLaunchingWithOptions函数中 var navigationBarAppearace = UINavigationBar.appearance() navigationBarAppearace.tintColor = uicolorFromHex(0xffffff) navigationBarAppearace.barTintColor = uicolorFromHex(0x034517) // change navigation item title color navigationBarAppearace.titleTextAttributes =[NSForegroundColorAttributeName:UIColor.whiteColor()] titleTextAttributes影响标题文本,在这里我将标题文本设置为白色 以编程方式更改导航栏标题 为了更改导航项的标题(在ViewController中),您必须在ViewController的viewDidLoad函数中设置标题 override func viewDidLoad() { super.viewDidLoad() self.navigationItem.title = “New title” } 以下是此更改后的示例输出 更改状态栏颜色 […]

使用一流的对象创建具有多种单元格类型的UITableViews

问题 在AI公司工作时,您总是会做很多技术演示,以在野外使用某种技术。 现代算法往往具有很多您想尝试的参数,有时工作的结果只能由人类认可,尤其是当它与任何类型的图像处理/计算机视觉或AR / ML类型相关时应用程序,您必须用眼睛检查结果。 这通常导致必须创建一堆屏幕上的按钮/滑块,以便可以对核心逻辑进行参数设置,并查看新的超参数如何影响结果。 在进行了几次这样的演示之后,我决定创建一个自定义调试菜单,您可以在其中以声明方式添加几个选项,然后观察更改。 我一天通过分叉现有的调试工具Dotzu制作了原型。 项目仍处于起步阶段,但现在或多或少可以满足我的需求。 您可以在公共仓库中使用它。 以下是取得的成果的小演示: 现在,有趣的部分。 我们创建一个UITableViewController子类,在其故事板上没有单元原型: 所有的魔力都进入了它的实现。 让我们来看看: 在最底部,我们声明要呈现的模型数组 这是最有趣的部分。 由于一流的类型对象不可比,因此我们使用Swift标准库中的 ObjectIdentifier结构为每个Type对象创建Hashable / Equatable代理对象。 我们声明一个字典和两个方便的方法来注册并从中获取类型。 由于它是重复的代码部分,因此可能应将其移至称为TypeRegister或类似名称的单独类中。 3.在viewDidLoad()方法中,我们使用一个小的辅助方法将单元格类型注册到表视图中。 4.接下来,我们将关联的Model-View对注册到我们的类型字典中。 5.在cellForRowAt中:我们从数组中获得一个模型,为其确定一个单元格类型,并出列适当类型的单元格。 6.最后,我们告诉UITableView使用自动布局来计算单元格的高度,因为它可以从一个选项到另一个选项。 而已! 现在,您有了UITableView的60行代码的超灵活实现,可以处理其中无限数量的模型。 用法 框架的使用非常简单。 您所要做的就是通过调用一种方法来一次初始化调试菜单(通常在AppDelegate中): DebugMenu.sharedManager.enable() 然后以声明的方式声明您的选项(通常在控制器的viewDidLoad中 ): 通话开始的结果可以在故事开始的视频中看到 由于该仓库专用于调试,因此您可能希望使用#if DEBUG…#endif子句覆盖与DebugMenu的所有交互。 最后的话 由于UI工程不是我每天都会做的事情,因此,我很想听听您对这项技术的反馈,并希望听到关于如何做得更好的任何指导。 希望您喜欢阅读! 不要忘了在GitHub上使用仓库,并在Twitter上关注我。

Swift的基础

Swift是用于iOS,macOS,watchOS和tvOS应用程序开发的新编程语言。 很快,很多人就会熟悉C和ObjectiveC。 Swift提供了自己的所有基本C和Objective C类型的版本,包括Int,Double,Float,Boolean和String。 Swift还提供了数组,集合和字典的集合类型。 Swift引入了在Objective C中找不到的高级类型,例如Tuples。 元组使您可以创建和传递值分组。 常量和变量 常量和变量将名称与特定类型的值相关联。 您可以使用let关键字声明constan,使用var关键字声明变量。 设a = 10 var b = 20 var x = 10,y = 20,z = 30 在声明常量或变量以明确常量或变量可以存储的值的类型时,可以提供类型注释。 var名称:字符串 var a,b,c:双精度 注释 swift中的注释与C中的注释非常相似。 //这是一条评论。 / *这也是评论 但它写在多行上* / / *这是第一个多行注释的开始。 / *这是第二个嵌套的多行注释。 / * 这是第一个多行注释的结尾。 / * 分号 如果要在一行上编写多个单独的语句,则需要使用分号。 设a = 10; 打印(a) //打印10 整数 Swift提供8位,16位,32位和64位形式的有符号和无符号整数。 […]

[车间] PickView(快速)

目的 了解如何创建选取视图 方法 创建一个单视图应用程序。 将一个PickView UI对象拖到情节提要中。 告诉App我们的数据源位于何处。 现在我们的数据源来自ViewController.swift。 3.编码如下 为了避免出现如下所示的错误消息,必须实现与UIPickerViewDataSource相关的方法。 测试 参考 UIPickView API:https://developer.apple.com/reference/uikit/uipickerview