继续第1部分,第2部分,这篇文章将是有关Closures的最后一篇,我们都可以肯定,它可以写成一整本书,只讨论Closures,所以我几乎没有触及任何表面。 这次我要谈的是: 速记参数名称 尾随闭包 速记参数名称 迭代数组的一种方法是使用forEach方法,在以下示例中,该方法将打印其内容: 闭包具有使我们简化代码的功能,而不必通过参数访问其值,而可以使用简写参数名称来访问它们: 您可能会注意到,我们省略了参数名称number甚至省略了关键字in ,并且我们正在通过名称$0访问闭包提供的值,以便减少代码并专注于代码中最重要的部分。 因此,即使闭包有更多的参数,速记名称也将被分配为$0 , $1 , $2 ,以此类推。 尾随闭包 假设我们有一个名为findInteger的函数(不用担心该函数的源代码在结尾),它将使用Integer数组根据条件搜索元素: 因此,在上面的代码中,我们希望获得第一个满足关闭条件的数字,即数字服务器。 我们可以看到我们在第二个参数上收到一个闭包表达式,但是有时像在这种情况下那样,表达式变长了,相反,我们可以这样做: 区别在于,首先我们不需要在函数调用中使用参数标签closure 。 其次,闭包表达式位于函数调用的括号之后,但它仍然是函数的参数。 这种简化方式称为尾随闭合。 让我们来看另一个例子。 这次,我们在Integer的扩展结构中使用了一种称为forEach (末尾的源代码)的方法,该方法将允许我们迭代数字上的数字,如下所示: 该代码本身具有解释性,但是关闭时间较长。 让我们应用一些尾随闭包 。 因此,在这里作为最后一个示例( findInteger function ),我们没有放置称为closure的参数标签,也没有包含括号。 如果闭包表达式是forEach方法中唯一的参数,那么我们也可以消除函数的调用括号。 当闭包表达式很长时, 尾随的闭包可以解脱 。 正如我提到的,示例中使用的方法的源代码: 如果您觉得该文章有用,请帮助我建议单击绿色的心形轮廓图标,以便我可以继续创建更多文章,非常感谢! 我要亲自感谢Bob和Victor激励我与我们的iOS社区分享我的Swift故事。 感谢您阅读我!
Seteleh lama gak nulis di beberapa minggu terakhir karena aktivitas yang padat😌,akhirnya kali ini gua sempetin lanjutan dari artikel sebelumnya。 Ini bakalan singkat dan ga bertele-tele,cukup singkat karna sisanya cuma cara积分密码推送文件Swift kita。 安装Codepush Kita Pakai react-native-code-push yarn add react-native-code-push 喀麦店林克项目计划,印度塞拉利昂共和国 react-native link react-native-code-push Perintah tersebut akan menambahkan文件文件yang dibutuhkan secara otomatis。 dani untuk memastikan lagi,bisa kita […]
为什么还要编写测试呢? 让我们从基础开始,为什么我们甚至需要编写测试? 即使我是编写测试的坚定支持者,但我确实理解有时候由于各种原因,没有足够的时间或资源可以专门用于测试,最常见的情况是缺乏对重要功能的理解,或者换句话说,缺乏公司文化。 通常是我们开发人员必须说服我们的经理我们需要编写测试。 另一方面,有很多开发人员根本不相信编写测试,或者只是出于某种原因不喜欢编写测试。 如果您是这些开发人员或管理人员之一,我将请您仔细考虑以下事实。 在医院洗手是相当近期的做法。 直到1847年,匈牙利医生Ignaz Semmelweis才提出医护人员洗手以降低医院死亡率的想法。 他的想法与当时的科学观点和医学观点相矛盾,并被当时的医学界完全拒绝。 由于遭到拒绝和嘲笑,他感到神经衰弱,并在庇护中死亡。 医学界花了很长时间才开始将洗手作为强制性做法。 毋庸置疑,从那时起,洗手挽救了无数生命,而提到的医生是现代英雄。 杀手bug 我希望我能说,没有人为了让我们(软件开发人员)能够学习到有关编写测试的重要性的类似课程而死,但这已经与臭名昭著的计算机控制放射治疗机Therac的 “杀手臭虫”发生了-25 ,这会导致它发生故障,并给至少6名患者带来大量(有时甚至是致命的)辐射剂量。 如果以适当的方式对Therac-25的软件进行了测试,也许可以避免发生这一系列可怕的悲剧。 测试iOS应用 软件开发社区中有关自动测试的情况看起来像19世纪后期的医学界,在iOS应用程序开发社区中尤其如此。 编写任何类型的测试通常都是iOS应用开发的事后思考,特别是在较小的团队中。 实际上具有大量单元测试的某些项目通常会完全省略UI测试。 作为iOS开发人员,我们的工作与其他软件开发人员没有任何不同,我们应该像其他开发人员一样坚持经过时间验证的做法,并通过测试彻底覆盖我们的代码。 我们可以使用的某些工具可能还不如XCUITest (我在看着你! ),但这并不意味着我们不能在它们之上构建并解决眼前的问题,毕竟,这就是我们要做的正在付款。 在BUX上进行测试 当我开始在BUX工作时,我被分配给一个经验丰富的iOS开发人员团队,他们准备开始构建具有挑战性的新iOS应用程序。 团队已经使用当前的BUX应用程序设置了很高的质量标准,该应用程序已经在App Store上运行了几年,并且非常稳定,有成千上万的用户,几乎没有崩溃。 毋庸置疑,这种稳定性是严格的测试程序的产物,我们也在新应用程序的开发过程中加以应用和改进。 新应用,新挑战 我们正在构建的新应用是下一代股票交易应用。 它是从头开始设计的,其任务是抽象出股票交易的复杂性,将其带给以前从未交易过的人们,同时使用户界面尽可能直观,并为其添加独特的社交组件。 有很多重叠的实时事件,例如股票报价更新,账户余额更新,交易执行,社交事件等,它们可以在一瞬间发生并动态影响用户界面,有时一次会发生多个事件。 另外,可以从应用程序中的多个点触发很多自定义流。 我们的解决方案 为了降低复杂性,我们将应用程序分为几个模块/框架,一个包含核心业务逻辑,一个用于发出和发送http请求,另一个用于Web套接字事件观察,等等。 通过使用单元测试,测试这些框架非常简单,单元测试覆盖了它们的100%。 当要测试应用程序本身时,出现了一个大问题。 测试应用程序的某些部分非常简单,我们的逻辑控件已从其支持的视图中分离出来,因此我们能够通过使用单元测试轻松地涵盖其中的大部分内容。 另一方面,端到端测试所有UI流程并不是那么简单。 手动测试它们会花费时间,消耗人力并且容易出错。 另一方面,使用XCUITest进行自动UI测试并不是有史以来最好的开发人员体验。 有一些出色的iOS UI测试框架可用,但是我们觉得其中大多数都不适合我们,或者仅仅是一个过大的选择,因此我们决定构建自己的简单且最小的iOS UI测试框架。 我们正在尝试做的是通过控制应用程序接收的所有数据,以一种用户使用应用程序的方式来模拟应用程序的使用,但是在受控环境中。 在单元测试的情况下,通过模拟和存根实现非常简单,但是在UI测试的情况下,则变得更加复杂,因为您没有相同级别的访问应用程序代码的权限。 iOS App及其UI测试本质上是两个独立的过程,它们进行通信的唯一方法是在测试开始时通过XCUIApplication变量传递一些参数。 有一些第三方解决方案即使在应用程序和UI测试目标已经运行后也能在它们之间传递数据,但是我们认为这太过hacky和容易出错,因此我们围绕此约束构建了框架。 页面对象模型 我们的解决方案基于Page Object […]
在使用Storyboard多年之后,我最近决定为我的个人项目切换到Programmatic Views和Programmatic Autolayout。 这种选择背后有几个原因,主要原因是“编程视图”使创建可重用的UI组件变得更加容易。 不依赖Storyboard或XIB文件,它更容易实现: 使用新功能扩展UI组件。 通过框架重新分发组件。 在这篇文章中,我将介绍程序化视图和程序化自动布局,我将通过构建一个有趣且具有挑战性的UI功能来做到这一点:视图控制器标题的视差和缩放效果。 最终结果将如下所示: 事不宜迟,让我们开始实现上述效果的旅程。 第一部分:程序化视图 在本节中,我将说明在创建新项目时如何使用程序化视图。 重构一个较旧的项目以使用Programmatic Views是绝对可能的,但是通常需要花费很多精力,并且需要自己的发布。 步骤1:摆脱情节提要 开始使用程序化视图的第一步是摆脱情节提要。 让我们创建一个全新的Xcode项目并将其命名为ParallaxAndScale 。 现在,我们只需要几个步骤就可以删除对Storyboard的依赖: 删除自动生成的主Storyboard( Main.storyboard )。 删除Info.plist的Main storyboard file base name键。 修改AppDelegate.swift以编程方式实例化主视图控制器。 我通常还将自动创建的ViewController.swift重命名为MainViewController.swift 。 AppDelegate.swift 我们将保留LaunchScreen.storyboard因为它需要能够正确启动应用程序。 现在,我们摆脱了对Storyboard的依赖,并准备好充分利用Programmatic View。 为了实现视差和缩放效果,我们将以下视图放置在主视图控制器中: 必要的意见 我们还将需要一些约束引用,以使UI在布局更改时表现适当(当用户通过上下滚动触发特定效果时): 必需的常量和约束引用 步骤2:以编程方式创建视图 对于这一步,我想包装代码以编程方式将每个视图创建到其自己的私有方法中。 这不是严格要求的,但我认为它使代码更整洁,更易于阅读。 我还喜欢采用一种功能方法,并让每种方法都返回它创建的视图实例。 这样的实例将在显示之前适当地添加到视图控制器中。 以编程方式创建视图 步骤3:以编程方式设置自动版式约束 可以将设置Autolayout约束的代码放在单个方法( arrangeConstraints() )中,也可以分为一组私有方法,每个视图一个。 对于此特定用例,我们不需要太多约束,因此将所有Autolayout代码包装到一个方法中就足够了: 以编程方式设置自动布局约束 第4步:结合程序视图和程序自动布局 现在我们已经准备好基本块,让我们看一下如何将它们组合起来以确保正确显示主视图控制器及其内容: 结合程序化视图和程序化自动布局 在viewDidLoad内部,我们首先创建视图,然后将其正确添加到视图控制器中,最后设置Autolayout约束。 警告:记住在调用代码设置约束之前将视图添加到主视图控制器! […]
嗯,多线程,并发等等。 这些都是在Flatiron学校的话题,我们被告知“这确实很重要”,现在我开始寻找工作,阅读工作说明并进行技术面试,现在我意识到Flatiron并不是在撒谎。 因此,在这里,我们只关注一件事: 中央中央调度(GCD) 。 Grand Central Dispatch(以前称为libdispatch的框架)是Apple的框架,用于将并发(管理同时发生的多件事)合并到您的应用程序中。 基本上,GCD会为我们管理队列(为我们完成所有任务调度!),因此我们不必考虑如何合并线程或在哪里“锁定”代码行。 GCD允许我们(开发人员)考虑将代码编写为单个线程或进程,因此,我们只需要考虑在哪里分解我们的部分代码以在另一个线程上运行。 Apple文档指出,“ GCD提供并管理FIFO(先进先出)队列,您的应用程序可以以块对象的形式向其提交任务。 提交给调度队列的工作在系统完全管理的线程池上执行。 无法保证执行任务的线程。” 简而言之,GCD是我们的小帮手,因为它: 因为它在后台运行长时间运行的任务,所以有助于提高我们的应用性能。 通过避免在新线程上设置锁和分离代码的需要,使开发人员更轻松(如果操作不正确,可能会导致并发错误) 可以提高代码性能,例如单例。 因此,让我们退后一步,回顾一些在开始讨论GCD之前需要理解的词汇和概念: 任务=需要完成的一项工作(即API调用)。 线程=操作系统提供的进程,它允许多个指令集(又称代码行)在单个应用程序中同时运行。 进程=代码的可执行部分,可能在多个线程中。 太酷了,既然我们已经把这些术语简化了,让我们来谈谈任务的执行方式。 串行调度队列与并发调度队列 如果一项任务一次执行一次,则称它是串行执行的。 如果可以同时执行多个任务,则称它们是同时执行的。 Grand Central Dispatch提供了调度队列(以“队列”为一行),使您可以在所谓的并发调度队列上并发运行代码块。 使用并发调度队列,我们有多个线程可用于同时处理多个代码块。 这种队列不同于串行调度队列 , 串行调度队列一次只在一个线程上添加一件工作。 同步与异步执行 函数可以是同步的也可以是异步的。 同步功能仅在上一个任务完成后返回 。 我喜欢将其视为“同步”(有趣的事实:NSYNC是我一直以来最喜欢的男孩乐队)。 异步意味着它可以立即运行,而无需等待上一个任务完成就可以开始。 因此,它不是同步的(我喜欢将异步看作是我的NSYNC的后街男孩)。 大中央调度:我们如何使用它? 如前所述,GCD为我们提供了调度队列,用于管理代码块。 这些分派队列负责处理我们提供给GCD的任务,并按FIFO ( 先进先出 )顺序进行处理(第一个任务排在队列的首位,依此类推)。 您还记得在串行调度队列中 ,一次只执行一个代码块。 在GCD中,这些块的执行时间在GCD的控制之下。 换句话说,我不知道代码的第1、2和3块要花多长时间,但是我知道两件事:1)每个块一次要运行一个,2)他们要运行一次以添加它们的顺序运行。 对于并发调度队列,可以同时执行多个代码块。 GCD的工作是决定何时启动每个块。 由于这些是同时运行的多个代码块,并且将重复执行这些代码块,因此GCD 决定何时这些块之一应在其他内核上运行 (一个内核是计算机的处理器之一。我的Macbook […]
我创建代码的过程如下所示: 研究目标的细节(学习) 提出实施计划(创建) 代码(单击并键入) 当我意识到我有一个错误的假设时,请返回步骤1(遗憾) 在进行编码工作之前,正确命名类型是计划中的最后一个障碍。 就像,嗯,我知道计算机不在乎我给我命名的类型。 机器解释指令时,所有这些都将被剥夺。 我的功能不会受到影响。 为什么我花了很多时间来确定角色以及事情如何融合在一起? 因为代码不仅仅适用于机器。 适用于必须充分理解它才能正确操作它的开发人员。 该类别中包括“未来”。 要做到这一点,就需要弄清问题集,并有足够的同理心,以使听众可以预期您选择的名字的所有含义。 真名 有一个古老的想法,即如果您知道某事的“真实名称”,那么您将拥有权力。 这是幻想中的常见现象,也是宗教故事的一部分。 以伊西斯和拉的故事为例。 伊希斯(Isis)是一位出色的治疗师,但只有知道她的真实姓名时才能帮助Ra。 他试图用“小写”的名字满足她的要求,但这仅使Ra未能解决核心问题。 一旦他放弃了他的真实姓名,她就可以治愈他。 这听起来像调试我。 如果您不知道所处理事物的真正含义,就无法解决该问题。 懒惰的标签将欺骗人。 您在阅读代码时让人们做的心理锻炼越多,使用它的认知就越消耗精力。 “是的,被称为 Provider 但实际上只是转换数据。” “该 modelId 不适用于该模型,适用于其他通用模型。” 但是,如果您真正知道什么是东西,则可以轻松地对其进行操作。 这很重要,因为将来必须更改代码。 我的理想是功能与代表功能的标签之间的绝对统一。 既然是理想的,我永远都不会到达那里。 想起名字时会出现回报递减的情况,但是值得花一些时间。 在清晰度和可读性之间取得平衡 某物的最精确名称可能是…… 绝对清晰。 把它收拾好。 该名称公然忽略了所有可用的上下文。 显然,这个例子很荒谬,但是添加不必要的限定词可能很诱人。 即使您觉得这个名字不是最好的,也最好在项目内部保持一致,而不要在两个约定之间来回穿梭。 一旦人们适应了您项目的标准,他们就会知道您在说什么。 一致的信息比冲突的信息要好,即使最终效果不佳。 同样,在引入新元素时也不要害怕重命名旧元素,以澄清它们之间的差异。 我们不是用石碑编码。 有些人梦想着将来验证自己的代码并期待未来的变化。 我宁愿使代码清晰地代表当前的情况,并在反映未来的将来进行更改。 这使我省去了很多我无法控制的事情。 我们控制双方 也许您没有花时间准确地命名某件事,因为它正在做很多事情…… 再塞另一种方法 有时正确的答案可能是重构基础实现以启用更好的名称。 我们都可以控制。 […]
通过编码视图和创造力,该数字可能会比您想象的要少 我在本文中的动机是不评判工具。 但是,展示了另一种无需界面构建器的APP构建方法,即使用iOS本机API并通过创造力享受这一过程。 在这篇文章中,您将了解: 锚点布局 堆栈视图 依赖注入 数据流量 故事板? XIB? 编码视图? 从一个有争议的主题🙃开始。 我进入Xcode的第一步和一些专业的工作都是使用Storyboard完成的。 我无法想象有人可以用代码替换界面构建器的拖放。 因为,它非常简单,快速。 直到情节提要开始困扰我,然后才让XIB困扰。 在我更喜欢使用代码构建的视图之前,我非常抵制此更改。 但是有一天,我开始反思,得出结论,这是我的懒惰。 毕竟,当是全栈开发人员时,我写的是HTML,而不是拖放组件(例如旧的Dreamweaver)。 但是对我来说,Visual Format Language和NSLayoutConstraint构造函数很无聊。 视觉格式语言对拼写错误非常敏感。 NSLayoutConstraint的默认构造函数为long。 因此,我参加了Thiago Lioy @tpLioy关于视图代码的一些讨论。 在这些谈话中,他展示了如何将Storyboard项目迁移到使用Snapkit使用代码创建的视图。 结果令我惊讶的是,结果非常好。 这就是我开始喜欢查看代码的方式,谢谢@tpLioy。 但是我仍然想学习如何使用Apple为我们所做的事情。 那是我遇到锚定布局的时候。 NSLayoutAnchor Apple文档将NSLayoutAnchor描述为一个类工厂,旨在生成NSLayoutConstraint对象。 NSLayoutConstraint对象负责启用自动布局。 简而言之, NSLayoutAnchor将使创建自动布局中使用的约束变得更加容易。 使用NSLayoutConstraint方法代替使用NSLayoutConstraint类的构造函数创建约束。 这样做的好处是代码更简洁,类型检查可以避免创建无效约束。 例如,此检查将不允许将X轴属性与Y轴属性混合。 尽管NSLayoutAnchor类提供了附加的类型检查,但仍然可以创建无效的约束。 例如,编译器允许您将一个视图的leadingAnchor与另一个视图的leftAnchor ,因为它们都是NSLayoutXAxisAnchor实例。 但是,“自动布局”不允许将前导和尾随属性与左或右属性混合使用的约束。 结果,此约束在运行时崩溃。 NSLayoutAnchor 行动时间 为了演示如何在实践中使用布局锚,我创建了一个Playground。 在这个操场上,会有一张名片清单。 根据用户选择的计划,卡片的视图不同。 考虑到这一点,我创建了下面的布局。 一切的根源 如您所见,所有名片都具有相同的数据。 但是,显示方式有所不同。 如果您曾经使用过前端Web,那么它就像只有一个HTML,并且每种布局都有不同的CSS。 […]
如果您仍然不确定如何开始使用RxSwift,那么本文适合您。 我已经阅读了很多有关RxSwift的文章,但是从了解理论到实际利用该知识是一条很深的弯路。 在本文中,我们将创建一个使用RxSwift的非常简单的iOS应用程序。 我们将使用RxSwift的概念并将其应用到此应用程序中。 我将跳过RxSwift的基础知识,因为有许多精美的文章对其进行了解释。 作为参考,您可以在这里看看。 这是塞巴斯蒂安·博尔特(Sebastian Boldt)a的一篇可爱的文章。 我们将在此应用程序中采用一个非常基本的方案,即使视图控制器使用RxSwift进行通信。 让我们开始吧… 基本设定 在Xcode中创建一个新项目,并为该项目初始化pod,然后在pod文件中添加以下内容。 替换YOUR_TARGET_NAME ,然后在Podfile目录中键入: $ pod安装 快速转发…。 添加一个新的View控制器(我将其命名为N ewViewController ),以便您的主故事板如下所示: 当您点击更改背景按钮时,它将打开新的视图控制器,而当您点击NewViewController上的任何按钮时,它将更改MainViewController的颜色。 通过已建立的可可模式进行交流 如果您使用已建立的可可模式来构建它,那么下一步将是添加委托模式,以便我们的N ewViewController可以与M ainViewController对话。 通过可观察对象进行通信 打开您的N ewViewController,将以下变量添加到您的视图控制器类中: 在这里,我们创建了一个名为selectedColorSubject的Subject 。 这将发出选定的颜色,并发出一个名为selectedColor的Observable,它公开了可观察的主题。 要了解主题和可观察对象,请参阅 上面 提到的 链接 。 我们将添加一个名为changeColor的函数,当按下任意按钮时,它将负责发出新的颜色值,一旦发出该颜色值,我们应导航回到上一屏幕。 我们的函数如下所示: selectedColorSubject.onNext(color)发出新的颜色值,然后我们向后导航。 确保我们的按钮动作事件调用此函数 现在,我们的视图控制器如下所示: 现在转到我们的mainViewController 在按钮操作事件中添加以下代码 当我们点击changeColorButton时,我们导航到NewViewController 。 如我们所见, NewViewController中的selectedColor变量返回一个 类型Observable,因此我们可以订阅该序列。 这样,可观察对象发出的任何值都可以在我们的MainViewController上捕获。 您可以将其视为简单的KVO。 欢呼!! 我们已经完成了第一个RxSwift驱动的应用程序。 Github上的源代码。
在本系列的第一部分-第1天-要学习的编程语言-我们讨论了着重于*在*之前*构建有用的东西,甚至考虑学习任何编程语言。 如果您在一天结束之前完成了动作练习,则应该列出可以构建所需产品的技术列表,并按可及性进行排序。 您今天要处理的清单中的第一件事就是获取清单中的第一项,并找到可从中学习该技术的资源:书籍,文章,教程,在线课程。 我将为您提供以下示例资源列表。 为了让您想出自己的OWN清单,您需要重点关注。 记住您昨天学到的第一个原则- 学习与构建 。 当您查看资源时,请遵循以下一条简单的规则对其进行评估: 阅读完本书,观看本教程并完成本课程后,我是否会制作一些东西? 现在,它一定不是您昨天决定构建的产品/服务/应用程序。 它只需要是一个成品。 这本书,教程和课程-必须在结尾处特别提及-您将能够构建:应用程序,网站,服务等。 如何选择正确的学习资源? 您要寻找的东西: 构建现有产品的克隆:Instagram克隆,Facebook克隆,Twitter样服务 该资源必须有明确的时间表-完成它需要多长时间。 非常非常重要! 您必须预先了解-您将花费多少时间来构建它。 没有截止日期的目标-根本不是目标。 课程/书籍/教程的评分,评论和评论 很重要!!! 有没有办法直接与作者联系? 在Facebook上找到? 推特? 良好学习资源示例清单 您将构建的内容:人工模拟生活,编程语言,平台游戏,绘画程序和动态网站。 时间表:页数有限,您可以在开始阅读本书时确定自己的进度。 我花了15天才完成这本书。 评分: 4.5星,亚马逊,基于77条评论 联系人:作者活跃在GitHub,Twitter上,您甚至可以通过他的网站向他发送电子邮件。 您将构建的内容:社交网络(Facebook克隆),聊天应用程序(WhatsApp克隆),教程应用程序(youtube克隆)。 时间表: 71.5小时的视频。 因此,如果您努力学习,则可以在2周内成为拥有现有工作应用程序的真正的iOS开发人员。 评分: 4.5星级基于9,190评分 联系人:课程的创建者在Twitter上很活跃,但在Udemy本身上,更是积极地回答学生的问题。 我确定如果您在北斗的个人学习平台上挖北斗,就会发现更多与他联系的方式。 您将构建的内容:视频目录网站,该网站将抓取youtube视频并将其显示在页面上,并提供用户身份验证,管理,两种不同的前端构建方式-使用模板和使用javascript框架。 完成完整的堆栈开发。 时间表:页数有限,您可以在开始阅读本书时确定自己的进度。 我花了10天的时间才能完成该项目。 评分:这是来自 Sails.js的创建者本人-Mike McNeil! 相信我,这很棒。 联系人: Mike McNeil的GitHub,他的Twitter帐户和他的Blog是一个很好的起点。 完成今天的动作练习 选择一个将用于构建一个产品的资源。 设定明确的目标-将来-一星期,两周,三周-当产品准备就绪时。 计划您的时间-这样您就可以每天学习。 […]
问题 :我们曾遇到过这样一种情况,我们想通过在屏幕截图(如下图)中具有相等的宽度来显示两个水平放置的按钮。 在某些情况下,我们可能需要隐藏其中一个按钮,并将按钮的中心显示在视图的下方,如屏幕截图所示。 我们知道这是安静的常见情况,可以通过使用约束来实现。 但是,通过使用约束,我们最终需要添加许多约束来查看并在需要隐藏一个按钮时对其进行更改。 通过使用堆栈视图,我们可以轻松地做到这一点而无需处理约束。 当我们使用堆栈视图时,当我们需要隐藏一个按钮时,我们最终会拉伸按钮(在具有填充对齐的水平堆栈视图中)。 为了避免这种情况,我们需要像下面的代码片段一样适当地更改StackView的轴,对齐方式和分布。 在这里,我们将堆栈视图轴修改为垂直,以对齐为中心 , 分布为fillProportionally,当我们隐藏按钮之一时。 注意: Modify(forAxis:.vertical……是UIStackView扩展中的辅助方法。 Github链接以获取完整代码。 LeelaRamala / ButtonsInStackView 这是一个示例代码,用于通过使用堆栈视图在视图中显示动态调整大小的按钮。 通过使用堆栈视图,我们可以… github.com 希望这可以帮助!。 欢迎建议🙂