Tag: Objective C

Xcode 8.1 GM的新增功能

苹果已经发布了Xcode 8.1 GM-这是新版本中的新增功能和改进功能: 快速更新 将C和Objective-C代码导入Swift时,将定义一个新的宏__swift__。 该宏的值的格式为XYYZZ,其中X是语言的主要版本,YY是次要版本 语言的版本,而ZZ是“补丁”版本(YY和ZZ始终为两位数)。 Swift标准库中添加了两种类型:UnsafeRawBufferPointer和UnsafeMutableRawBufferPointer。 它们表示固定内存区域(缓冲区)上的非所有视图。 它们将底层缓冲区公开为UInt8字节的集合,而与该内存中保存的值的类型无关。 一个新的withUnsafeBytes(of :)函数将值的内存表示形式公开为UnsafeRawBufferPointer。 Swift标准数字类型现在作为NSNumber桥接到Objective-C。 NSValue类为其提供工厂方法的结构现在作为NSValue桥接到Objective-C。 由乔·格罗夫(Joe Groff)建议。 当Optional值桥接到Objective-C对象时,当Optional传递给采用非空ID的API或[T?]数组桥接到NSArray时,如果有一个值,Swift运行时将桥接已包装的值。 如果桥接了nil值,并且API不接受nil指针,则Swift将使用NSNull。 由乔·格罗夫(Joe Groff)建议。 快速修复 Swift 3.0.1现在生成一个const UnsafePointer而不是UnsafeMutablePointer。 现在可以正确处理C属性swift_error(zero_result)。 覆盖和满足协议要求的成员的访问检查已修复为与SE-0025更紧密匹配。 如果需要保持Swift 3代码与Xcode 8.0兼容,请对顶级类和结构使用private而不是fileprivate。 解决了使用@NSManaged属性来满足协议要求的问题。 Objective-C更新 现在,使用“手动引用计数”的Objective-C文件支持__weak引用,而不是忽略它。 您需要在项目设置中启用它,否则将触发编译器警告。 核心数据更新 现在,在创建新实体时,Xcode 8将为实体名称和类名称设置相同的值。 更改实体名称也将更改类名称,除非它们已经不同。 核心数据修复 使用自动代码生成保存后,现在可以对数据模型进行更改。 界面生成器更新 新的“更新框架”按钮将更新所选对象及其子对象的框架。 固定按钮已重命名为添加新约束。 自定义手势识别器已添加到对象库,以允许继承UIGestureRecognizer或NSGestureRecognizer而不是使用NSObject。 界面生成器修复 修复了使用重力区域分布的NSStackView的自动布局性能。 解决了布局不明确时Xcode不能始终从情节提要和xib恢复视图帧的几个问题。 现在,您可以解决歧义,并且Xcode将继续存在。 将内容拖动到画布上的静态UITableView单元中,将再次起作用。 创建IBAction连接不再使用Swift 2.3插入WithSender。 在非视网膜上的设备栏中选择横向方向 在OS X 10.11上运行时显示的内容现在将不再挂起。 调试修复 […]

使用Objective-C可以做的5件事,但是使用纯Swift却做不到

我喜欢使用Swift进行编程,就像喜欢使用Objective-C或Python或C#进行编程一样,因此,本文并非旨在偏爱这两种语言。 在以后的文章中,我将尝试介绍您可以使用Swift进行的操作,但是不能使用Objective-C进行的操作。 话虽这么说,但是在写了很长时间的Objective-C之后,有时用纯 Swift进行编程时似乎缺少一些工具,尽管通常有一些方法仅使用Swift就能获得大致相同的结果。 用Objective-C编写的许多应用程序和框架都依赖于这些工具,有时还依赖于骇客,这使我们的代码更简洁,更易于使用。 我将以可能是Objective-C中最具争议的主题开始我的列表。 1.)方法混乱 混乱是有争议的,因为它允许您通过更改类选择器的实现来在运行时更改类的行为。 这意味着您可能会拥有一项服务,该服务为您提供类名或方法名作为字符串,并更改应用程序在运行时的行为方式。 不能从NSObject继承而来的纯Swift类(我们想要转换为@dynamic缺乏此功能,但本质上动态性较低且类型安全的语言首先吸引了大多数Swift开发人员。 那里有许多Objective-C框架/库,它们使用方法混乱使我们的生活更轻松并且代码更简洁。 Aspects是一个功能强大的库,它使用复杂的特性使在Objective-C中实现面向方面的编程成为可能。 这使您能够为诸如应用程序分析之类的事情实现非侵入式代码,如另一个库ARAnalytics中所示。 OCMock在很大程度上依赖于Objective-C运行时,而Swift并没有真正支持它。 Rollout.io使用方法混乱,将实时更新推送到您的应用程序。 Rollout.io发生了一个有趣的发展,他们在其中描述了他们甚至如何使用Swift应用程序进行实时更新! 2.)C ++互操作 Objective-C通过名为Objective-C ++的结构支持与C ++代码的互操作性。 许多项目/库都使用C ++作为其核心组件,以便能够更快地交付该库的跨平台版本,而不是用平台的本地语言重写整个库。 PSPDFKit和Realm是很好的例子。 当然,您可以将C ++代码包装在C或Objective-C中,然后通过Swift与该代码对话,但这会增加代码量和代码库的维护量。 3.)performSelector: performSelector:是NSObject类的实例方法,该方法将指定的消息发送到接收方并返回消息的结果。 在这样的对象上进行方法调用会触发一系列事件,这些事件将调用objc_msgSend函数(在Swift中也不可用)。 如果该类的方法调用存在实现,则该函数进行查找,否则,将其链接到超类,直到到达NSObject的根级别为止,在该根级它将引发unrecognized selector sent to instance ,该unrecognized selector sent to instance NSInvalidArgumentException 。 这种机制使您可以在不预先知道对象类型的情况下向对象发送消息,如下所示: 类personClass = NSClassFromString(@“ Person”); id object = [personClass new]; NSString * name = […]

Swift对Objective-C应用的影响。

作为我在阿姆斯特丹软件公司Oberon实习的一部分,我最近将iOS应用程序的业务逻辑从Objective-C重写为Swift。 该应用程序是My T-Mobile。 当时的Swift版本是3.0。 除了重写业务逻辑之外,我还写了一篇关于Swift的影响的研究论文。 从上下文来看,自Swift 2.0发行以来,Swift现在是iOS上Oberon的事实上的开发语言。 由于My T-Mobile应用程序是Oberon上运行时间最长的应用程序之一,因此用Objective-C编写的应用占80%。 Oberon认为,当应用程序在Swift上运行时,软件质量将会提高。 因此,我不得不重写业务逻辑,因为它是应用程序中使用最频繁的部分,但是在自然的开发过程中不太可能被重写为Swift。 定义软件质量 对于我的Swift影响研究论文,我需要定义软件质量。 我决定使用CISQ(IT软件质量联盟)模型。 CISQ的标准基于ISO标准,但更强调源代码,因为我正在使用和重写源代码,所以源代码与我的项目非常匹配。 CISQ模型着重于四个特征:可靠性,性能效率,安全性和可维护性。 我决定专注于模型的可维护性方面,因为Swift的功能和标准对软件质量的那些方面影响最大: 非结构化和重复的代码 高圈复杂度 文字的硬编码 组件尺寸过大 重复的业务逻辑 符合初始架构设计 架构层之间严格的调用层次 在本文中,我不会将重点放在这些点上,因为仅需一点上下文即可。 过程 因为懒惰的程序员是高效的程序员,所以我首先研究一下Objective-C-> Swift转换器。 有很多: https://objectivec2swift.com/ https://iswift.org/ https://github.com/dzenbot/XCSwiftr 但是,他们每个人都有问题。 前两个选项不是免费的,一次只能转换几十行。 最后一个不能与Xcode 8一起使用,因为Xcode不推荐使用插件。 即使使用转换后的代码,我始终觉得这是从Objective-C到Swift的直接转换。 例如,转换器永远无法以显示防护语句或让模式提供更安全代码的方式来转换Objective-C代码。 需要考虑的另一件事是,Swift和Objective-C具有不同的编码范例,因此,通过使用转换器,将无法实现这一目标,并且还必须以某种方式检查和更改代码更迅速。 对于我来说,听起来比从头开始还需要做更多的工作。 简而言之,我决定手动重写和重构应用程序,而不是使用工具。 作为一个没有这个项目经验的人,很难理解代码。 例如,当使用诸如NSArray或NSDictionary之类的类型时,旧的Objective-C代码更难于推断进入了哪种对象。 在重构过程中,我注意到,随着函数和属性的类型被显式声明,尤其是对于数组和字典,它们的功能和属性变得更加清晰。 另一个优点是,与使用Objective-C两文件副本相比,Swift的单一文件使在整个项目窗口中导航更加轻松。 在重构了整个业务逻辑之后,我不得不找出它对软件质量有什么样的影响。 由于本文是关于使用Swift的影响,因此我决定使用一个名为SonarQube的工具,这是一个开放源代码平台,用于检查代码质量。 初始结果如下所示: 如您所见,可维护性,安全性和可靠性是完全相同的。 Swift版本减少了1000行代码,并且减少了重复,但是这些差异并没有真正使人震惊。 因此,我对SonarQube的发现进行了更深入的研究。 我发现以下内容: 如果您忽略了新的代码味道-当您不更改代码时就不会得到新的代码味道-您会发现Swift版本的代码味道比其Objective-C的更少。 我研究了一下代码的味道,发现Swift版本完全没有一种代码味道:认知复杂性。 认知复杂性试图在某种程度上说明方法的控制流程难以理解,从而难以维持。 […]

Objective C项目中的Swift Pod库

如果您像我一样从事旧的Objective C项目的工作,则可能必须使用在线提供的Swift 3rd party库。 在Objective C项目中检测Swift文件不能按预期进行。 因此,必须确保正确执行了所有步骤。 我在这里提到的几点可以帮助您快速完成此过程。 确保取消注释use_frameworks! 在pod文件中。 检入“ 构建设置” >“标题搜索路径”,添加Pods文件夹作为递归搜索。 3. Objective-C桥接标头存在于项目中,并包含在“构建设置”中。 如果没有,那么您只需添加一个Swift文件,Xcode就会要求您进行配置。 说是! 4.确保在安装Pod之后,请清理并编译一次代码。 5.要从pod访问swift文件,您必须使用: #import“ -Swift.h” 例如,如果使用的是NVActivityIndi​​catorView,则最终会得到: #import“ NVActivityIndi​​catorView-Swift.h” 如果要访问用Objective C代码手动添加的Swift文件,请使用: #import“ -Swift.h” 您可以在“ 构建设置”>“ Objective-C生成的接口头名称”中确认“文件名”。 编码愉快!

模型视图控制器(MVC)

Model-View-Controller(MVC)设计是一个与应用程序的全局体系结构有关的高层,并根据对象在应用程序中扮演的一般角色对对象进行分类。面向对象的程序通过适应MVC可以从多种方面受益他们设计的设计模式。 这些程序中的许多对象倾向于更可重用,并且它们的接口倾向于更好地定义。 它主要包括三层: 1)模型层 2)查看图层 3)控制器层 1)模型层: 模型层包含以下组件: 网络代码 :此代码对于整个应用程序的网络通信非常有用 持久性代码:此代码用于实现核心数据,或仅通过将NSData blob直接保存到磁盘即可。 解析代码:解析网络响应之类的任何对象也应包括在模型层中。 模型对象封装了数据和基本行为,它们保存了应用程序的数据并定义了处理数据的逻辑。设计良好的MVC应用程序将其所有重要数据封装在模型对象中,任何数据都是应用程序持久状态的一部分一旦将数据加载到应用程序中,它应该驻留在模型对象中。 理想情况下,模型对象与用于呈现和编辑它的用户界面没有显式连接。 模型对象不应与界面和表示问题有关。 2)视图层: 当用户与您的应用进行交互时,他们正在与视图层进行交互。 视图不应该包含任何业务逻辑,因此被认为是应用程序的“哑巴”部分。 用代码术语,您通常会看到: UIView子类:这些类从基本的UIView到复杂的自定义UI控件。 UIViewController: UIViewController与自身的根UIView及其不同的周期(LoadView,ViewDidLoad)紧密耦合。 动画和UIViewController过渡。 UIKIT / APPKIT,Core Animation和Core Graphics的一部分的类 检查视图图层时,请使用以下内容作为检查清单: 它是否与模型层交互? 它是否包含任何业务逻辑? 它会尝试执行与UI不相关的任何操作吗? 如果我们很好地编写了这些类,则几乎可以随时重用它们。 视图对象向用户提供信息。视图对象知道如何显示并可能允许用户编辑应用程序模型中的数据。视图不应负责存储其显示的数据。视图对象可以位于负责仅显示模型对象的一部分,整个模型对象,甚至许多不同的模型对象。 视图有很多不同的种类。 视图对象倾向于可重用和可配置,并且它们在应用程序之间提供一致性。 在Cocoa中,AppKit框架定义了大量的视图对象,并在Interface Builder库中提供了许多视图对象。 通过重用AppKit的视图对象(例如NSButton对象),可以确保应用程序中的按钮的行为与其他任何Cocoa应用程序中的按钮一样,从而确保了应用程序之间外观和行为的高度一致性。 视图应确保其正确显示模型。 因此,通常需要了解模型的更改。 由于模型对象不应绑定到特定的视图对象,因此它们需要一种通用的方式来指示它们已更改。 3)控制器层: 控制器层是应用程序中最少可重用的部分,因为它涉及特定于域的规则。 控制器对象将模型绑定到视图。控制器对象充当应用程序的视图对象及其模型对象之间的中介。 控制器通常负责确保视图可以访问他们需要显示的模型对象,并充当视图了解模型更改的渠道。 控制器对象还可以为应用程序执行设置和协调任务,并管理其他对象的生命周期。 在典型的Cocoa MVC设计中,当用户通过视图对象输入值或指示选择时,该值或选择将传达给控制器对象。 控制器对象可能以某种特定于应用程序的方式解释用户输入,然后要么告诉模型对象如何处理此输入。 基于相同的用户输入,某些控制器对象还可能告诉视图对象更改其外观或行为的某个方面,例如告诉按钮禁用自身。 相反,当模型对象发生更改时(例如,访问新的数据源),模型对象通常会将更改传达给控制器对象,然后控制器对象请求一个或多个视图对象进行相应的更新。 MVC作为复合设计模式: Model-View-Controller是一种设计模式,由多个其他基本设计模式组成。这些基本模式共同定义了MVC应用程序的功能隔离和通信路径。与可可分配的基本模式不同的一组基本模式。 […]

轻松管理Swift项目中的不同环境

想象一下,您已经完成了应用程序的开发和测试,现在可以将其提交生产版本了。 但这是问题所在:您所有的API密钥,URL,图标或其他设置都针对测试环境进行了配置。 因此,在提交您的应用程序之前,您将必须修改所有这些内容以适合您的生产模式。 显然,这听起来不太好。 另外,您可能会忘记在庞大的应用程序中进行某些更改,因此您的服务将无法正常运行。 代替这种凌乱的方法,最好有几个环境并在需要时简单地更改它们。 今天,我们将通过最流行的方法来尝试组织不同的环境: 使用注释。 使用全局变量或枚举。 使用带有全局标志的配置和方案。 将配置和方案与多个* .plist文件一起使用。 1.使用注释 当您有2个分离的环境时,您的应用程序需要知道它应该连接到哪个环境。 想象一下,您拥有Production , Development和Staging环境以及API端点。 处理此问题的最快,最简单的方法是拥有3个不同的变量并注释其中2个: 这种方法非常肮脏,凌乱,会使您哭泣很多。 有时我会在黑客马拉松上使用它,因为代码的质量不起作用,而速度和灵活性才是关键。 在任何其他情况下,我强烈建议您完全不要使用它。 2.使用全局变量或枚举 另一种流行的方法是使用全局变量或Enum (这会更好)来处理不同的配置。 您将必须在3种环境中声明您的Enum ,并在某处(例如在AppDelegate文件中)设置其值: 这种方法要求您每次更改代码时都只在代码中设置一次。 与以前的方法相比,此方法要好得多。 它非常快速,可读性强,但有很多局限性。 首先,在运行任何环境时,您始终具有相同的捆绑ID。 这意味着您将无法同时在设备上拥有两个具有不同环境的相同应用程序。 一点都不舒服。 同样,在每个环境中使用不同的图标也是一个好主意,但是采用这种方法,您将无法更改图标。 同样,如果您忘记在发布应用程序之前更改此全局变量,则肯定会遇到问题。

使迦太基再次伟大!

您好,我是Max,我是iOS开发人员超过7年。 本文是关于依赖项管理的,因为我认为即使使用所有这些工具,它也是iOS开发过程中的薄弱环节。 感觉就像您只需要处理它,但这不是应该的样子。 在我的职业生涯中,我使用了许多依赖管理工具,从简单的拖放源代码到尖端的Swift依赖管理器。 但是仍然是我最喜欢的工具之一,仍然是Carthage:去中心化,易于管理,构建一次就可以忘记。 例如,与Cocoapods相比,它允许将所有依赖项分别并独立地构建为一堆二进制文件,这些二进制文件可直接链接到您的项目而无需复杂的配置。 我认为这是非常灵活和一致的方法。 (顺便说一句,不要忘了Cocoapods需要框架作者的大量动作。还记得pod repo的设置/更新时间吗?) 我不会在这里深入探讨可可足与迦太基。 您可以阅读很多这类文章。 我只是想表达我对迦太基的态度作为该主题的序幕。 然而,这并不完美。 我告诉你为什么以及如何修复它。 为什么迦太基不完美? 首先,如果您曾经使用过Realm,Alamofire,ReactiveCocoa等笨拙的大型框架之一,那么您可能已经注意到,您的CI / CD工作者花费大量的时间来建立依赖关系。 即使依赖项提供了预编译的二进制文件(但通常不提供),它也可能经常不适合您的Xcode / Swift版本。 因此,您花费大约80%的CI / CD时间来准备依赖项。 此外,邀请新成员加入团队或直接将现有项目克隆到另一台计算机,都会导致“让自己入睡”事件。 仅仅将框架添加到依赖项列表并不快。 当您挖掘过去的长期项目时,我什至没有在谈论过时的依赖关系。 最后但并非最不重要的一点:对静态框架的怪异支持。 为什么奇怪 因为Realm不会使用ld.py脚本构建到静态库中(例如,迦太基的推荐方法)。 您必须手动检查每个损坏的依赖关系,并为团队中的每个人将其替换为二进制文件。 金田挣扎。 顺便说一句,如果您错过了静态框架如此重要的原因,我告诉您:它显着降低了应用程序的大小和启动时间。 苹果也建议最多使用不超过6个动态库。 但是我们都为“只是一个框架”而感到内🙂 如何使它更好? 即使迦太基值得使用它。 但是有一种方法可以使它变得更好。 当我与许多团队一起处理大量应用程序时,我制作了一个工具,可将每个迦太基框架分别缓存到Amazon S3中。 因此,“已解决”文件中还有多少其他内容都没有关系,您可以根据需要下载它们中的每一个。 我的意思是,例如,如果有人至少为Swift 4.0.1构建了Realm 3.0.1,那么您可以立即下载它,而无需等待或编译。 Tbh我已经看到了很多用于Carthage的缓存工具,但是其中大多数要么需要拥有个人S3帐户,要么立即保存所有项,等等。 因此,我制作了一个工具来修复这些缺陷。 我想与您分享它,希望它可以使您的iOS编码体验至少好一点。 它称为迦太基缓存,可以在Github上找到。 如何使用它? 步骤1:下载至您的路径: 该工具将从云下载现有框架到Carthage的构建目录。 或者编译它们(如果以前没有人缓存过您的框架),然后将其上传以供公众使用。 但是静态框架呢? 这很简单: 它将下载或构建依赖项的静态版本。 […]

删除核心数据关系规则

要开始处理核心数据的关系,您应该对核心数据框架有所了解。 今天,我将通过适当的示例向您展示删除规则如何与核心数据关系一起工作。 首先设置项目,从xcode创建新项目,名称为Department,如下面的屏幕截图所示。 不要忘记选中使用核心数据复选框。 现在,是时候借助xcode接口创建数据模型了。 打开Department.xcdatamodeld并创建数据模型。 在这里,我将创建两个名称分别为Department和Employee的实体。 部门和雇员实体具有一个类似于名称的属性,更重要的是在这两个实体之间添加关系。 我创建了Department和Employee实体名称之间的一对多关系 ,因为departmentToEmployee因为部门有很多员工。 另外,我还添加了Employee和Department名称之间的To One关系,因为employeeToDepartment因为雇员只有一个部门。 下面的屏幕快照显示了两个实体之间的关系。 删除核心数据规则 现在是时候通过删除一个实体对象来考虑其他实体对象的影响了。 意味着如果员工被删除会怎样? 员工所属的部门是否也应删除? 否。但是,如果删除部门会怎样? 应该有没有部门的员工吗? 在这里图片处理这种情况。 为此,我们在核心数据框架中有删除规则。 每个关系都有删除规则。 删除规则定义删除拥有该关系的对象时发生的情况。 核心数据支持四种基本删除规则。 没有行动 无效化 级联 拒绝 无操作删除规则 如果将删除规则设置为对该关系不执行任何操作 ,则不会发生任何事情。 让我们举个例子,如果部门有很多员工,如果部门被删除,那么员工什么都没有发生。 员工认为其仍与删除的部门有关。 取消删除规则 如果将删除规则设置为对关系无效,则关系的目的地将变为无效。 在我们的情况下,如果部门有很多员工并且部门被删除,部门与员工之间的关系将失效。 这是默认的删除规则,我们经常在项目中使用此规则。 级联删除规则 此删除规则很重要,并且在将规则设置为realtionship时,请确保所有可能的情况。 当数据模型具有更高的依赖性时,通常使用此规则。 在我们的情况下,这意味着,如果部门有很多员工,并且部门被删除,则属于该部门的所有员工都会自动删除。 在使用此规则之前,请确保您的项目要求。 因为如果删除关系对象,此规则将删除所有记录而不会产生任何暗示。 拒绝删除规则 此规则功能强大,与级联规则完全相反。 它可以防止删除记录,而不是按照级联规则删除所有记录。 在我们的情况下,如果部门有很多员工,则仅当删除属于同一部门的所有员工或没有员工与同一部门捆绑在一起时,部门才被删除。 这全部与核心数据的删除规则有关。 在处理两个实体之间的关系之前,请先了解此概念。 在设置删除规则之前,请先了解您的要求。 我希望你们喜欢阅读这个故事。 如果您对此有任何疑问,请与我们联系。

2 iOS中的高性能Feed UI框架

点击后,它将在单元格顶部显示另一个视图。 即使您向下滚动并返回,它也会停留在单元格上。 听起来很正常很容易,对吧? 通常,这里倾向于发生的是在单元格中检测到动作,并且单元格直接在单元格上添加视图,因为它仅更新视图,而不是用户状态等。当单元格被重用或当单元格被重新使用时,这将是一个巨大的问题。用户回到此单元格。 为什么选择ComponentKit ComponentKit的一大功能是视图是不可变的。 由于它是不可变的,因此数据存储和视图之间的通信将更加简单。 仅当数据存储发生任何更新时,视图才会更新。 话虽如此,这是从数据存储到视图进行通信的一种方式。 性能 ComponentKit还使我们在保持简单性的同时具有良好的性能,因为它们仅更新视图层次结构中的更新视图组件。 这将使我们更容易更新,插入和删除组件。 缺点 用Objective-C ++编写,表示.mm文件。 没有雨燕。 与Swift互操作没有简单的方法,因为Swift无法桥接到C ++。 Few.swift或Katana等实验项目正在探索如何将React的概念应用到Swift中。 来自 http://componentkit.org/docs/uses.html 由于语言的原因,额外的括号。 如果您是Objective-C爱好者,那么这将不是问题。 您仍然需要根据需要更新UICollectionView 。 IGListKit 另一个不错的选择是Instagram团队构建的IGListKit。 Instagram / IGListKit IGListKit –数据驱动的UICollectionView框架,用于构建快速灵活的列表。 github.com Ryan Nystrom详细讨论了如何构建框架。 大规模重构–汲取的经验教训重写Instagram的Feed 当Instagram团队从头开始重写他们的iOS提要时,他们学到了比预期更多的信息…… realm.io 总览 IGListKit替换了UICollectionView。 它为集合视图接收数据数组。 当它接收到一个新的数据数组时,它将检查差异并自动处理具有O(n)运行时复杂度的批处理更新。 该框架是为从服务器获取数据并在集合视图上显示它们的服务而设计的。 它是用Objective-C编写的,但是您也可以将它们与Swift一起使用。 他们也有很好的示例项目,在仓库中有很多示例。 Raywenderlich也有关于IGListKit的精彩文章。 IGListKit教程:更好的UICollectionViews 每个应用程序都以相同的方式启动:几个屏幕,一些按钮,可能还有一两个列表。 但是随着时间的流逝和应用程序的发展…… www.raywenderlich.com 摘要 我研究了Facebook和Instagram用于时间轴供稿UI的框架,它们都解决了扩展时面临的特定问题。 例如,Instagram团队拥有大量的控制器和大量的提要对象,以支持各种功能。 简而言之,出于只显示从服务器获取的项目列表的目的,我决定使用IGListKit。 但是,这当然取决于您要解决的问题。

将背景视频添加到登录屏幕

您是否不认为有时小的设计细节就可以通过一点点的努力就能将任何视图的无聊体验变成有趣的视图? 登录屏幕中的视频背景是在一些热门应用(例如Spotify和Vine)中引起我注意的这些很酷的细节之一。 我决定试一试,看看如何在应用程序中实现它。 我发现这可以通过不同的方式来实现,例如将imageView与GIF,AVFoundation或MPMoviePlayerController一起使用。 对于此博客,我将演示如何使用AVFoundation,它非常简单,直接,只需几行代码,您就可以构建一个漂亮的登录屏幕。 首先,您需要一个视频将其添加到您的Xcode项目中,我正在使用.mp4视频。 我通常更喜欢为视频创建一个单独的视图,然后将其导入到登录VC,或者您也可以直接在登录VC中执行所有下一步。 在VideoView.h文件中,我添加了以下方法: 希望这篇文章对您有所帮助,并随时在下方留言! 快乐的编码:)。