苹果在iOS 11的UIFONT中引入了新的可访问性功能,称为“ UIFontMetrics ”。 基本思路: 它是获取支持应用程序中动态类型的自定义字体的对象。 概述: UIFontMetrix允许在您的应用程序中添加自定义可缩放字体支持。 您可以通过设置应用程序更改辅助功能字体大小,该设置应用程序直接反映在包含动态系统字体类型的应用程序字体中。 在iOS 11上,apple允许用户根据用户的可读性设置辅助功能字体大小。 应用支持动态类型 ,可根据您的首选阅读大小进行调整。 分步集成: 您需要在viewDidLoad()中调用“ showFontAndFamily”方法。 强制性的,我们需要打开上图中提到的更大的辅助功能大小 。 启用了字体滑块,可以根据您的选择使用和设置字体。 现在打开您的应用程序。
众所周知,设计应用程序中最重要的步骤是DataModel的定义。 这个阶段需要大量关注和长时间,因为这是我们项目的逻辑,核心,在此阶段做出的决定可能会影响我们代码的速度,可持续性和可重用性。 我记得对于与我的队友Giacomo和Jippe一起进行的最新Apple iOS开发人员学院项目,我们花了3个多星期才发布第一版。 当您开始设计它时,情况似乎并没有那么糟。 关键时刻到了,您必须创建第一个对象。 这就是两难的原因: 类还是结构? 可以在网上找到成千上万的文章。 每个人都通过重复通常的概念以及类和结构之间的通常差异来作出响应,而没有根据我们的需要解释何时使用一种而不是另一种有用。 答案总是相同的,并且倾向于强调两者之间的差异,它们并不能真正帮助我们选择对我们的案例最有用的一个 例如: 1.继承 类具有继承。 结构没有。 因此,如果需要对结构进行子类化,唯一的解决方案是将其转换为类。 2.价值和参考语义 类使用语义参考。 当等距分配给变量或函数时,它们指的是同一现有实例。 例如: 如您所见,创建新变量并不意味着创建新对象。 通过视图所做的更改也可以从view2中看到,因为它们引用了内存中的同一对象。 关于不可变性的观察: 如您所见, view和view2都被声明为let,因此它们都是constant 。 但是,为什么可以在类中更改值而不用编译器抱怨呢? 类是引用类型,因此可以暗示在程序执行期间,所指向的存储区域(即地址)不变。 您可以使用var和let控制类中的可变属性和不可变属性。 结构使用值语义。 当将值类型的对象分配给变量或传递给函数时,编译器将复制该对象。 实际上,只要不修改对象,它们就与同一对象相关。 发生更改时,编译器将进行复制。 这种技术称为写时复制。 例如: 在发生更改之前,string1和string2是相同的实体 编辑string2,强制编译器创建原始对象的副本。 关于不可变性的观察: 尝试将string2从var更改为let 。 您会注意到编译器会抱怨,因为您已将结构声明为常量 ,并且试图更改其内部状态。 它们的行为不像类。 结构具有语义值,如果声明为let,则不能更改结构中的任何属性。 对于声明为var的结构,您可以在初始化后更改,将所有内部属性定义为var。 但是……这些解释可以帮助我们解决难题吗? 没有! 我认为,所有这些答案都无法阐明选择为特定实体创建类或结构所引起的疑问。 很多时候,我开始考虑这种选择似乎天天琐事。 终于,我找到了解决这个难题的办法! 平等的概念 那些了解我的人都非常清楚,我喜欢通过使用现实生活中的示例来解释概念,然后将其与实际的示例进行比较。 每当我们遇到这种选择, 类或结构时 ,请问自己: […]
这是我撰写有关测试的提示的系列文章的第二篇,您可以在此处查看另一篇文章: iOS测试技巧#1-跟踪辅助功能测试失败 软件开发中最有害的事情之一是无法读取的代码。 当我们失去太多精力去理解某些代码时,我们会花费更少的精力来查看极端情况,这是产生错误的最有利条件之一。 测试是消除bug的武器,因此它很重要,但是如何知道它有效呢? 不要看代码覆盖率就知道是否正在测试某些东西,因为代码覆盖率只会检查这些行是否已执行。 即使没有灵丹妙药,您的测试代码也越不可读,要找出是否正在测试所有必要的上下文就越困难。 有一些技术可以帮助您组织测试代码,使其更具可读性。 在这篇文章中,我将以一个简单的测试服开始,然后将通过应用这些技术来前进。 在此示例中,只需尝试找出正在测试的内容以及如何使用它。 。 在上面的示例中,我们很难发现要测试的内容,而Arrange-Act-Assert可以帮助您解决这一问题。 该技术可帮助您从设置和断言中分离出正在测试的内容。 使用这种技术,可以更清楚地知道是否存在同时测试多个对象的测试方法。 这项技术可以帮助我们确定自己正在测试的班级,我个人并没有使用太多。 设置方法在测试套件的每个测试方法之前运行。 此步骤很重要,但要明智地使用,您的测试应该易读且易于维护,过度使用设置方法可能有害,因此您必须评估最适合自己的方法。 比较每个重构步骤,并了解哪种方法更适合您的环境。 所有人,谢谢您的阅读!
在我正在进行的项目中,我选择了建筑模式-VIPER。 这是音乐制作应用程序,它允许您播放,录制和混合第三方乐器。 主模块的框架(以简化形式): 最初,该应用程序是为iPad设计的,后来该应用程序是为iPhone开发的,并且更改了主要模块。 某些组件可用于两种设备(通用),有些则不能: 我们希望保持课程尽可能整洁。 每次创建/更改课程时,您都应该问自己: 该课程有多少职责? ( 单一责任原则 )。 我认为,创建模块和DI(返回对象图)的责任应该属于一个特殊的类。 它不应制作AppDelegate,Router或VC。 这可以使您的程序集 : 其余代码非常简单: 然后我提出要为Mac创建应用程序,为什么不…
斯威夫特yakınzamanda 5yaşınagirecek。 5个iOS版本您可以使用Swift Dilinde,yazılıyor和Obj-C dilinden esergörmüyoruz。 你是不是喜欢我的节目? İsimlerine? Buyazıdasizlere Swift’te yer alan UIKit’itanıtmayaçalışacağım。 UI kelimesininaçılımı“用户界面”目录。 Yanikişiningördüğüekran diyebiliriz。 Biruygulamayıaçtığınızda塔布拉尔语,butonlar ve metinlergöreceksiniz。 Bunlarınhepsi UIKitadıaltındabulunan objelerdir。 Gördüğünüzüzerebir Ekranüzerindebirkaç元素mevcut。 UILabel ,它的名称为objedir。 Genelliklekısametinlerin,说“ılarınekranayazdırılmasındakullanılanbir obje olmakla birlikteüzerindedeğişiklikleryapmak epeykolaydır”。 Bununla birliktebüyük植骨iText UITextViewkullanmaktayız ,从yarayan pekçoközellikbulunmaktadır。 重要信息“可滚动”的gibiyukarıkaydırarakkalanıokuyabildiğimiz。 像是从Bize birşeyyazmasınıbekliyor isek o zamanUITextField’ıkullanıyoruz。 Küçükgörünebilirancakburayıözelleştirerek她的seyeikullanıcıdanalmanızmümkün。 İsterbir kelime olsun,isterseniz bir paragraf,isterseniz bir toplamaişlemi。 她的türlümetni seve sevealıyor。 İşinizbittiğinde她的zaman […]
我在新加坡iOS Conf的Jesse Squires演讲中,他讨论了Swift的数字类型和协议。 这让我想起了SE-0104(面向协议的整数),现在该实现是在Swift 4中进行的,认为现在是仔细研究的好时机。 让我们从每个人喜欢的整数类型Int的协议层次结构开始: 与标准库中的大多数类型一样, Int符合很多协议! 从头到尾, Numeric是基本协议之一。 所有不同大小的整数类型( UInt , Int8等)以及浮点类型( Float , Double等)都符合Numeric 。 数值,从0x00开始 您可以在Integers.swift.gyb中遵循标准库源代码,尽管照常,所有相关代码都将在下面内联。 这是开始的协议声明: public protocol Numeric : Equatable, ExpressibleByIntegerLiteral { 这里有另外两个符合性: Equatable增加了对==运算符的支持。 ExpressibleByIntegerLiteral允许使用let a: Int = 42这样的代码let a: Int = 42其中42是上述的“整数文字”。 这意味着所有数字类型都可以使用整数文字进行初始化,但不能使用浮点文字进行初始化。 这段代码可以: let someFloat: Float = 42 // ✅ 但这不行: let someInt: Int = 4.2 // […]
使用MBCircularProgressBa r — https://github.com/MatiBot/MBCircularProgressBar来自Interface Builder Swift的圆形,可动画制作且高度可定制的进度条,使用吊舱配件MBCircularProgressBar安装Cocoapods terminal.pod“ MBCircularProgressBar” 那—安装pod文件的简单步骤— 打开终端 终端上的命令转到项目文件夹CD路径 在终端上设置项目路径。 命令:pod初始化 打开pod文件— open -e podfile 在pod文件中添加了in:pod“ MBCircularProgressBar” 命令:Pod安装 关闭Xcode项目 从终端打开您的项目 命令:打开PodDemos.xcworkspace 操作StoryBoard之后,现在将UIView拖到Storyboard中的viewController上 或设置UIView约束的宽度,高度或垂直或马尾空间,并在StoryBoard中设置类MBCircularProgressBarView。 打开Atribute检查器并根据需要自定义进度栏 现在打开ViewController.swift文件导入UIKit导入MBCircularProgressBar ViewController类:UIViewController { @IBOutlet周var progresssView:MBCircularProgressBarView! 覆盖func viewDidLoad(){supper.viewDidLoad()self.progresssView.value = 0}覆盖func viewWillAppear(){UIView.animate(withDuration:10.0){self.progresssView.value = 60}} } 最初发布在 iosdeveloperlive.blogspot.com上 。
在Swift 3中,您可以使用 在Swift 3中创建单视图应用程序的简单项目 拖动文本字段并连接到viewController 日期选择器看起来像图像 Swift 3和Swift 4示例中的UIDatePicker。 在Swift 3中,您可以使用 在Swift 3中创建单视图应用程序的简单项目 拖动文本字段并连接到viewController 日期选择器看起来像图像 ViewController代码如下。 类ViewController:UIViewController { //文本字段连接 @IBOutlet弱var txtDatePicker:UITextField! //选择器 让datePicker = UIDatePicker() 覆盖func viewDidLoad(){ super.viewDidLoad() //显示日期选择器 showDatePicker() } func showDatePicker(){ //格式化日期 datePicker.datePickerMode = .date //工具栏 让工具栏= UIToolbar(); 工具栏.sizeToFit() //完成按钮和取消按钮 让doneButton = UIBarButtonItem(标题:“完成”,样式:UIBarButtonItemStyle.bordered,目标:自我,动作:“ donedatePicker”) 让spaceButton = UIBarButtonItem(barButtonSystemItem:UIBarButtonSystemItem.flexibleSpace,目标:无,动作:无) 让cancelButton = UIBarButtonItem(标题:“取消”,样式:UIBarButtonItemStyle.bordered,目标:自我,操作:“ cancelDatePicker”) 工具栏.setItems([doneButton,spaceButton,cancelButton],动画:false) //将工具栏添加到textField […]
您好,第3部分已准备就绪! 如果还没有,请查看第1部分和第2部分 更新:2018年12月27日。 1-什么是Nil合并和三元运算符? 它很容易返回未包装的可选值或默认值。 如果没有值,则可以设置零或默认值。 2-什么样的JSONSerialization有ReadingOptions? mutableContainers指定将数组和字典创建为变量对象,而不是常量。 mutableLeaves指定将JSON对象图中的叶字符串创建为变量String的实例。 allowFragments指定解析器应允许不是Array或Dictionary实例的顶级对象。 3-如何防止用户在其设备上多次执行上述操作? 苹果在iOS 10中引入了DeviceCheck。该API使我们可以访问iOS设备中按设备,按开发人员的数据。 该解决方案比UserDefaults或Advertising Identifier更好。 DeviceCheck允许我们存储一个布尔值。 4-什么是DispatchGroup? DispatchGroup 允许工作的聚合同步。 我们可以使用它们来提交多个不同的工作项,并跟踪它们的完成时间,即使它们可能在不同的队列中运行。 如果在完成所有指定任务之前无法取得进展,此行为将很有帮助。 — Apple的文档 最基本的答案:如果在继续之前需要等待几个异步或同步操作,则可以使用DispatchGroup. 5-什么是RGR(红色-绿色-重构)? 红色,绿色和重构是TDD(测试驱动开发)的阶段。 红色:编写少量测试代码,通常不超过七行代码,然后观察失败。 绿色:编写少量生产代码。 同样,通常不超过七行代码,即可通过测试。 重构:测试通过了,您可以进行更改而不必担心。 清理您的代码。 这里有很多讲习班笔记。 6-我们在哪里使用依赖注入? 我们在iOS应用中使用情节提要或xib,然后创建了IBOutlets。 IBOutlet是与视图相关的属性。 这些在实例化时被注入到视图控制器中,这实质上是依赖注入的一种形式。 依赖注入有多种形式:构造函数注入,属性注入和方法注入。 7-请说明通知类型。 通知有两种类型:远程和本地。 远程通知需要连接到服务器。 本地通知不需要服务器连接。 本地通知会在设备上发生。 8-什么时候是我们项目中依赖注入的好时机? 您可以遵循一些准则。 规则1.可测试性对我们重要吗? 如果是这样,则必须在要测试的类中标识外部依赖项。 一旦注入依赖关系,我们就可以轻松地将真实服务替换为模拟服务,从而使其易于测试。 规则2.复杂的类具有复杂的依赖关系,包括应用程序级逻辑,或访问外部资源,例如磁盘或网络。 应用程序中的大多数类将很复杂,包括几乎所有控制器对象和大多数模型对象。 最简单的入门方法是在应用程序中选择一个复杂的类,然后在该类中查找用于初始化其他复杂对象的位置。 规则3.如果一个对象正在创建其他对象的实例,这些实例在其他对象内是共享的依赖关系,那么它就很适合进行依赖关系注入。 9-我们可以在集合类型上使用哪种订购功能? map(_:) :使用提供的闭包转换序列中的每个元素后,返回结果数组。 filter(_:) […]
大约一年前,Apple发布了AppleTV 4,并通过tvOS 9首次为开发人员开放了该平台。tvOS和iOS之间最大的区别可能是用户与系统的交互方式。 在iOS上,他们通常使用手指,但在tvOS上,使用游戏控制器或iPhone的“ Remote”应用可通过随附的遥控器取消互动。 为了管理这种新的输入法,苹果公司创建了一种叫做焦点引擎的东西。 在焦点引擎内,屏幕上的任何一个元素都具有当前焦点,并且焦点在用户导航时在一个元素和另一个元素之间移动。 如果用户按下按钮,则输入将定向到当前关注的元素。 在tvOS 9中,焦点引擎仅在UIKit中受支持,因此SpriteKit开发人员可以滚动自己的系统。 在tvOS 10中,焦点引擎已扩展为支持SpriteKit,目的是使SpriteKit游戏中的交互性更符合UIKit和基于TVML的应用程序。 我目前正在将我的iOS游戏Mazy移植到tvOS,并且其中一部分采用了新的Focus引擎来为游戏菜单提供动力。 我想在这里分享我的经验,希望您在从事类似工作时能从中受益。 有2个WWDC视频,介绍SpriteKit中新的焦点引擎集成。 在tvOS上进行焦点交互(SpriteKit位从15:20开始,但是如果您不熟悉焦点引擎,则值得观看整个视频)。 SpriteKit的新增功能中也介绍了该引擎(焦点位从39:15开始)。 我有一个github存储库,您可以克隆以遵循以下示例。 你可以在这里找到它。 由于需要tvOS 10,它需要Xcode 8 beta,它也是使用Swift 3编写的。下面的每个部分都有一个场景。 只需在GameViewController.swift中更新此行以选择相关场景即可: 让场景= SimpleMenuScene(大小:view.frame.size) SimpleMenuScene 首先让我们得到一个简单的菜单。 SimpleMenuButton是SKNode的子类,将显示一个字符串,并在聚焦时更改颜色。 我们将从垂直列表中的3个SimpleMenuButton开始。 为了使项目可聚焦,它必须实现UIFocusItem。 SKNode已经实现了此功能,因此我们可以在SimpeMenuButton子类中重写它,如下所示: 覆盖public var canBecomeFocused:Bool { 得到{ 返回真 } } (请注意,在Swift 2.3中,canBecomeFocused是函数而不是属性)。 现在我们需要处理焦点更改,我们通过实现UIFocusEnvironment中的didUpdateFocus来实现。 您可以在关注的项目或其父项之一上实施此操作。 在这里,我已经在SimpleMenuScene上实现了它 覆盖func didUpdateFocus(在上下文中:UIFocusUpdateContext,与协调者:UIFocusAnimationCoordinator){ 让prevItem = context.previouslyFocusedItem 让nextItem = context.nextFocusedItem 如果让prevButton […]