Tag: xcode

快速浏览类型擦除

如果您正在编写Swift,那么您可能已经听说过类型擦除。 也许您甚至在使用它。 但是,即使您属于这两个阵营中的一个,也有可能实际上不知道为什么类型擦除有效。 ♂️ 与其给您提供有关如何擦除类型的方法,不如让我们实际研究问题所在并逐步解决。 问题 假设我们正在制作一个通用网络会话类,该类必须支持各种JSON反序列化器,这些反序列化器返回的对象与网络会话的关联类型匹配。 像这样: 这很烦人,但确实有道理。 我们的协议JsonDeserializer是抽象类型,因此Swift编译器无法推断其引用的具体类型,也不能假设其在编译时由其associatedtype提供的类型。 Hector Matos在他的博客KrakenDev : 简短的答案是:Swift希望是类型安全的。 再加上它是一种提前编译的语言,并且您有一种需要NEEDS能够在编译期间随时推断具体类型的语言。 我不能太强调。 在编译时,不是函数/类约束的每个类型都需要具体。 协议中的关联类型是抽象的。 这意味着它们不是具体的。 他们是假的。 没有人喜欢假货。 因此,尽管此错误令人不快,但确实有道理-并且该错误告诉我们一些重要的信息。 指出,该协议只能用作通用约束 ,即在尖括号之间。 尝试1 我们知道,将JsonDeserializer用作类型约束的唯一方法是在使用它,但是出于参数的考虑,我们决定使用协议约束来指定一种类型,就像我们对泛型类的处理方式一样。 结果如何? Cannot specialize non-generic type ‘JsonDeserializer’ ❌ 虽然这是预期的。 正如我们前面所讨论的,该协议是一种抽象类型,尽管它可能具有通用要求,但它本身并不是通用类型。 不是class SomeType { … }方式。 尝试2 好吧,让我们尝试使用JsonDeserializer作为一般约束,并将反序列化器放入一个代理对象,我们将其称为DeserializerBox (此处使用Box是为了与以后的类型擦除命名约定保持一致)。 这个错误告诉我们我们需要提供一种类型来满足DeserializerBox的通用类型要求。 不幸的是,这意味着要指定一个JsonDeserializer 。 但是,我们想使用任何为我们提供Payload类型对象的JsonDeserializer ,因此指定特定的反序列化器具体类型将无法达到目的。 这与仅将具体类型用作Session的deserializer属性的类型约束没有什么不同。 令人沮丧的是,这是进步。 尝试3和3.5ish 为了弥补我们缺乏必要的类型争论,我们还需要DeserializerBox成为JsonDeserializer的真正代理对象,这意味着它应与JsonDeserializer 。 这意味着我们应该能够将代理与JsonDeserializer一样对待,并且它应该公开相同的接口。 为此,我们必须坚持使用JsonDeserializer […]

Xcode 10的构建系统和代码生成(R.swift)

Xcode 10包括一个默认启用的新构建系统,该系统可提高构建性能。 这是非常令人欢迎的改进。 R.swift是一个开放源代码库,它使使用图像,字体和segues之类的资源变得更加容易且类型安全。 这是一个非常酷的库,我们已经在Zendesk上成功使用了一段时间。 然而… 当构建使用R.swift和Xcode 10的项目时,构建将失败,并出现以下错误: 错误:找不到构建输入文件:/LOCATION/R.genic.swift R.swift使用Xcode构建脚本阶段集成到项目中。 此阶段生成一个Swift文件R.generated.swift ,该文件在构建项目时进行编译。 生成失败,因为具有新的并行生成系统的Xcode 10试图在创建R.generated.swift文件之前先找到它。 Xcode 10允许我们为构建脚本阶段指定输出文件。 我们可以将R.generated.swift文件添加为输出文件,如下所示: 这样可以成功构建。 太棒了! 🎉 额外 最初遇到此问题时,我们使用R.swift打开了一个错误。 但是,如上所示,该问题是由于Xcode的构建系统中的更改引起的。 而已! 📱🚀👍🏽 也可以在petethedeveloper.com上获得

UIKit:查看阴影

上次我们讨论了如何使视图的角变圆。 今天,按照承诺,我将向您展示如何使用layer.shadowX属性,以使视图看起来像Card,并获得其他炫酷效果。 让我们从简单而永不过时的Card View开始。 我知道你需要这个 myCard.layer.cornerRadius = 10 myCard.layer.shadowOpacity = 1 myCard.layer.shadowColor = UIColor(名称:“ Swift Orange”)!. cgColor myCard.layer.shadowRadius = 4 myCard.layer.shadowOffset = CGSize(宽度:4,高度:4) 该代码是不言自明的: 我按照上cornerRadius UIKit Rounded Views中的描述设置了cornerRadius属性。 我将阴影不透明度设置为从0到1的值,以将其应用于阴影颜色。 我设置阴影颜色。 我设置代表模糊半径的阴影半径。 如果您不愿意像我一样阅读,则只需要知道该值越高,图像就会越模糊。 如果您想学习,请单击此处。 最后,我设置偏移量,该偏移量是阴影相对于以点表示的图层的偏移量。 注意:要使阴影可见,请不要将layer的属性masksToBounds设置为true,否则它将被裁剪。 这还没有结束……还有一个阴影属性可供我们使用,以产生一些很酷的效果: shadowPath。 让我们看看如何制作一个像漂浮在设备屏幕上的视图。 让cardWidth = myCard.frame.width 让cardHeight = myCard.frame.height 让distanceFromCard = 15 myCard.layer.cornerRadius = cardWidth * 0.5 myCard.layer.shadowOpacity = 0.1 […]

Xcode 8.2 Simulator中的新功能

在Xcode 8.2的发行说明中,Apple为其新版本的Xcode引入了功能。 在此博客中,我将解释如何使用这些新功能。 这是Xcode 8.2 Simulator的两个新功能: 您可以使用xcrun Xcode命令行实用工具xcrun Simulator的视频和屏幕截图。 📷要截屏,请运行命令xcrun simctl io booted screenshot 。 📹要拍摄视频,请运行命令xcrun simctl io booted recordVideo . (9887264) 将应用程序拖到“模拟器”窗口中即可安装该应用程序。 (23387069) 捕获 第一个功能是录制视频并拍摄屏幕截图,非常简单。 您可以启动模拟器,在其上运行您的应用,然后可以截屏或开始/停止视频。 此功能非常方便从您的应用程序发送演示视频。 尽管该命令很长,但是却很容易执行! 拖放 第二个功能是将应用程序拖动到“模拟器”窗口中,但并不是那么简单。 至少不适合我😉 我的想法是,当我拥有.ipa格式的应用程序时,只需将其拖到将安装该应用程序的Simulator窗口中即可。 太糟糕了,事实并非如此。 但是苹果的意思是什么? “ 将应用程序拖到模拟器上” ? 因此,我在大型互联网上进行了搜索,并在Twitter上做了一些研究,在那里我收到了Brandon的这条推文。 提出的问题是; 为什么.app在模拟器中可以工作而.ipa不能工作? 这是因为.ipa格式的iOS应用是针对不同于模拟器可在其上运行的架构(ARM)构建的(x86)。 因此,.ipa格式的iOS应用只能安装在物理设备上,而不能在模拟器上运行! 附加:从DerivedData获取应用程序包 现在我们知道了如何将应用程序捆绑包拖放到Simulator上,我也想提供有关该应用程序捆绑包的一些详细信息。 该应用程序包位于DerivedData文件夹中,并在为设备构建项目时进行编译。 此DerivedData文件夹包含所有中间构建信息,调试和发布构建目标以及项目的索引。 模拟器应用程序捆绑包的特定位置可以在这里找到: 〜/库/开发人员/ Xcode / DerivedData / / Build […]

UIStackView:垂直轴肖像,水平轴风景

您是否曾经使用过UIStackView,并认为“ Jeez,此垂直堆栈视图在人像上看起来确实不错,但在风景上看起来像是一场灾难。 如果我能使它在肖像上垂直但在风景上水平……” 好吧,本教程适合您! 😁 如果您只想看技巧,请跳至第2部分! 第1部分仅介绍如何进行设置。 第1部分:设置 从一个名为“ Single View Application”的新项目开始,然后直接跳入Main.storyboard文件。 将UIImageView插入到View Controller的任何位置,添加所需的任何图像。 我选择了柏拉图的图像。 确保将要使用的任何图像都放在项目的Assets目录中,以便该图像显示在“图像选择”中! 2. 在UIImageView下面插入一个标签。 将行数设置为0,并将换行符设置为自动换行。 将行数设置为0允许多行文本。 标签将根据文本的数量占用其需要的任意数量的行。 如果您不知道标签上要显示多少文本,这对动态文本很有用。 将换行设置为自动换行可以使文本在完整的单词处换行。 3. 将UIImageView和Label嵌入到堆栈视图中。 有很多方法可以做到这一点。 在按住Cmd的同时单击图像和标签,然后按底部的堆栈图标。 4. 在堆栈视图上设置约束。 在文档轮廓上选择堆栈视图,然后设置水平和垂直约束。 我选择了:尾随= 5,领先= 5,顶部空格= 20 5. 在堆栈视图上,将“对齐方式”设置为“ 填充” ,将“分布”设置为“ 均等填充”。 将“对齐方式”设置为“ 填充”可使每个项目完全填充垂直于堆栈视图轴的可用空间。 将“分布”设置为“均等填充”可使堆栈视图中的每个项目均等地沿其轴填充空间。 如果需要,请添加一些间距。 我加了3。 6. 在标签上添加一些文本。 好的。 全部设置好了。 😤 第2部分:垂直轴肖像,水平轴风景 要更改堆栈视图在横向上的显示方式,我们需要实现特质变化。 “特征变化”根据设备的配置呈现不同的UI。 在这种情况下,您希望堆栈视图在不同的设备方向(纵向和横向)上看起来有所不同。 在文档大纲上选择堆栈视图后,单击“轴”旁边的“ +”。 […]

使用Pods重命名Xcode项目:简单方法

制作应用程序时,我们可能想在发布应用程序名称之前对其进行重命名。 但是Xcode中的过程有点复杂。 当我们的项目中有一些Podfile时,它将变得更加复杂。 在本文中,我将分享重命名项目的过程。 第1步-重命名项目 在Xcode视图左侧的“项目导航器”中选择您的项目。 在右侧选择“文件检查器” ,项目名称应位于“身份和类型”下 ,将其更改为新名称并按Enter 。 将显示一个对话框,列出项目中可以重命名的项目。 在下拉菜单中单击“重命名” 步骤2-重命名方案 在顶部栏中(“停止”按钮附近),有一个用于您的旧产品的方案,请单击它,然后转到“管理方案” 。 您也可以在此处找到“管理方案”: 菜单栏>产品>方案>管理方案的 单击方案中的OLD名称,它将变为可编辑状态,更改名称。 退出 Xcode。 步骤4 —重命名主文件夹 打开您的项目文件夹,并将OLD.xcworkspace重命名为NEW.xcworkspace。 步骤5 —处理Podfile 在终端中,cd进入项目目录并打开Podfile。 您应该看到带有OLD名称的target子句。 将其更改为新并保存。 执行“ pod deintegrate” ,Cocoapods将删除与pod相关的配置,脚本,生成的框架以及Pods /目录。 现在执行“ pod安装”。 步骤6 —现在打开您的项目 您将看到一个警告: “文件夹OLD不存在” ,请消除该警告。 在左侧的“项目导航器”中 ,您将看到红色的OLD文件夹名称。 单击标识中的文件夹图标,然后键入以打开查找程序并从NewName项目文件夹导航到NewName文件夹。 转到项目导航器-> [您的项目名称]->构建设置->打包-> Info.plist文件,然后将路径的子字符串从“ OLD”更改为“ NEW”。 对产品标识符执行相同的操作。 现在清理并构建项目。

HealthKit数据:读取/写入

该博客涉及iOS中的Health应用程序以及如何从Health应用程序读取数据/向Health应用程序写入数据。 我们将看到HealthKit框架的API。 我们将看到如何从Health应用程序读取数据/向Health应用程序写入数据。 1.在Xcode中创建项目 2.初始设置 3.创建共享管理器(HealthKitManager) 4.获取写权限 5.将数据写入健康应用程序 6.获取读取权限 7.从健康应用程序读取数据 8.注意事项。 1.在Xcode中创建项目 使用Single View Application创建新项目 设置项目详细信息 2.初始设置 一种。 添加HealthKit Framework。 选择“目标”>“构建阶段”>“使用库链接二进制文件”>单击“ +”>键入healthkit并添加。 b。 在开始编写代码之前,我们需要了解等同于读写的术语。 读取=与您的应用共享Health应用数据 写入=从您的应用程序更新Health应用程序数据 我们需要说明为什么要从Health应用程序读取数据或向Health应用程序写入数据。 因此,提供描述。 一种。 需要设置NSHealthShareUsageDescription进行数据读取。 这将在项目中自动添加权利文件 。 3.创建共享管理器(HealthKitManager) 让我们创建一个共享类作为Manager,将代码放入其中。 使用“ 连接”按钮绑定动作, 在此步骤结束时,您的应用程序现在已被授权将“ 步骤”写入“运行状况 ”应用程序。 如果您遇到任何错误/问题,请随时询问您的问题。 5.将数据写入健康应用程序 让我们创建一个函数,该函数将向Health应用程序中写入许多步骤 。 (在HealthKitManager.m中) 6.获取读取权限 请记住,我们已经拥有编写步骤的权限,这意味着我们也可以阅读它们。 因此,对于新的活动类型,我们将获得“健康状况骑车距离”应用程序的数据读取权限。 在“ 读取权限”操作下,您将能够看到权限模态,如下所示。 现在,我们有权从“健康”应用程序读取“ 骑车距离”数据。 7.从健康应用程序读取数据 我们将阅读“距健康的骑行距离”应用程序,但“健康”应用程序中尚无“骑车距离”数据。 让我们手动添加一些虚拟值, 转到健康应用程序>选择健康数据选项卡>活动>骑车距离>单击“ […]

仍然想知道IBDesignable和IBInspectable是做什么的?

现在是2019年,XCode 10在这里,iOS 12在这里,但我们甚至没有提供通过XCode接口构建器为UIView / UIbutton或任何其他UIView子类提供圆角/边框半径/边框宽度的规定。 啊! 有点令人沮丧,对不对? 当然,我们可以通过编程来完成所有这些工作。 但是,请思考一下,为什么您可以编写一些原始代码并想象一下它的外观,当您可以轻松地在Interface Builder中修改值并使用IBDesignable和IBInspectable查看实时更改时! 在本文中,我将说明如何使用界面生成器添加边框颜色,边框宽度和角半径。 因此,让我们开始吧。 IBDesignable和IBInspectable 将@IBInspectable添加到属性时,它将在XCode中将该属性公开给属性检查器。 您可以在属性检查器中修改值,而不用编程方式进行修改。 但是,当您尝试更改值时,界面构建器将不会实时显示更改。 为了查看更改,您需要构建并运行项目。 但是,嘿! 这是聚会的把戏。 我们可以使用@IBDesignable来处理此问题,它会告诉XCode在您修改值时呈现实时更改。 现在,让我们看看下面的示例类。 导入UIKit @IBDesignable 类CustomView:UIView { @IBInspectable var borderColor:UIColor? { 得到{ 返回UIColor(cgColor:layer.borderColor!) } 设置{ layer.borderColor = newValue?.cgColor } } @IBInspectable var borderWidth:CGFloat { 得到{ 返回layer.borderWidth } 设置{ layer.borderWidth = newValue } } @IBInspectable var cornerRadius:CGFloat { […]

面向协议的UITableViewCells

这篇博客文章展示了如何通过使用面向协议的编程 (POP)作为子类化或组合的更好替代方法来实现一组UITableViewCell变体。 准备? 我们走吧! 给我看看细胞! 在构建我的Cast Player应用程序时,我需要添加几个设置页面,以允许用户在应用程序中进行一些调整,并包括指向“发送​​反馈”表单和一些“关于”屏幕的链接。 这是最终结果: 从上面的屏幕中,我们可以识别六种不同类型的单元格: 总体而言,这些细胞具有以下特征(或行为): 单元格突出显示 显示标题 显示人类可读的字节数 我们如何去建立一组能很好地代表这六个细胞变异的类呢? 第一步是列出网格中的所有单元格类型和所需特征: 从上表可以看出: 所有细胞都没有采用这些特性。 一些特征是某些细胞所必需的,而其他细胞则不需要。 这意味着构建UITableViewCell类层次结构在这里无法正常工作。 实际上,这些单元格类型都不是基础类的理想选择。 该怎么办? 🤔 协议和扩展! 好极了! 幸运的是,这篇关于Swift 2.0中Mixins和Traits的精彩文章可以为我们指明正确的方向。 直观地讲,协议和扩展对于该用例确实可以很好地工作,但是如何在此处正确使用它们呢? 这个想法是我们可以使用协议为每个特征定义接口 ,并提供带有扩展的默认实现 。 然后,我们可以创建非常小的UITableViewCell子类,并使它们仅符合所需的协议。 在另一个名为“面向协议的MVVM简介”的精彩演讲中,探讨了一个非常类似的问题。 让我们看看它是如何工作的! 有了协议和扩展,我们可以编写第一个特征TitlePresentable : 在代码中,这表示为: 注意 : HighlightableTableViewCell是通过子类实现的唯一特征,并且可以用作三种其他单元格类型的基类。 一旦为给定类型选择了基类,则只能通过协议扩展来添加其他特征。 结论 使用Swift协议和扩展作为增加行为(特征)的一种方式,可以在我们的类的设计中取得重大胜利,并有助于保持层次结构的平坦。 🚀主要优点: class媚的阶层阶层 生成的API /类可以更轻松地扩展 与添加和删除代码相比,添加和删除协议一致性更容易 减少代码重复 欢迎反馈 这篇文章中介绍的解决方案对我和我的特定用例都非常有效-我希望这个实际示例可以帮助我比起初时更好地理解如何使用协议扩展。 如果您知道这样做的更好方法,请在评论中告诉我! 注意 :这篇文章首次出现 在 2016年6月18日发布的 […]

自定义React Native图标? 是的

2.编辑Info.plist并添加一个名为Fonts的属性,该属性由应用程序提供(如果Xcode无法自动完成/不使用Xcode,则为UIAppFonts),然后键入刚刚添加的文件。 它看起来像这样: 步骤1 在Sketch或Illustrator中创建图标,并将它们另存为svg。 第2步 转到http://fontello.com/并上传您的自定义字体。 您也可以从它们的选择中进行添加,以使它们都保持相同的字体。 第三步 从Fontello下载字体文件并打开它。 复制文件夹(其中的所有内容)并转到您的本地项目。 进入保存资产的目录,并创建一个名为fonts的文件夹,然后将该文件夹粘贴到其中。 我建议将文件重命名为“ fontello”。 接下来,打开Xcode并执行与“基本安装过程”中所述相同的插入过程,但使用新的字体文件。 完成此操作后,返回到项目所在的文本编辑器。 步骤4 创建一个名为“ icon.js”的文件。 创建文件后,添加以下代码。 第5步 然后,在需要图标的组件中,您将可以执行以下操作: 希望这对像我一样挣扎的人有所帮助。 干杯!