Tag: 教程

适用于iOS和macOS的Building Moments 2

三年前,我开始了这个构建移动应用程序的项目,作为对我的长子奥尔顿的礼物。 是的,他的确是网站上显示的可爱宝贝。 该应用程序做一件简单的事情,每次录制1秒的视频,并将所有这些连接在一起,成为一部成长电影。 在过去的两年半中,我大部分时间都在录制短片。 合并的电影现在总共约15分钟。 每次回顾放映他年轻时代的电影时,我都会微笑。 自己使用该应用程序并吃了自己的狗食后,我发现了许多我想改善的问题。 它们包括但不限于: 提醒我每天录音 回顾最近的时刻 人像模式 与我的妻子合作记录瞬间 从照片导入 允许静态照片 跨设备同步 备份到iCloud并使其可还原 分享给家人 支持新的iOS和设备 清单继续。 但是,只有一项功能使升级应用程序具有很高的优先级。 这是: 我的第二个儿子即将到期-奥尔顿的父亲 一方面,我想对每个孩子公平。 因此,小弟弟也应该得到一份礼物。 我曾经有一个单独的应用程序的想法。 但是,随着时间的流逝,迫切需要为两个儿子度过难关。 我无法在一部手机上安装两个Moments应用,并且我每天都不会随身携带两部手机。 因此,基本上,我需要两个时间表。 由于该应用程序现在已经过时,因此iOS基础架构发生了很大变化。 仅仅更新代码库是行不通的。 (是的,我已经尝试过了)因此,我决定重写该应用程序。 我已经决定升级Moments几个月了。 但是,我仍然没有开始。 除了全职研究Sorted 3,我还想知道保持Moments的价值。 在2016年,我设定了一个目标,将Moments提升到一个新的水平,希望这可以创造收入来源以支持我们的家庭。 您可能会猜到,它不是那样工作的。 到目前为止,我可能已经卖出了100本,赚了70美元。 这还远远不够。 由于市场上存在类似产品,因此这可能无法为用户创造足够的价值。 但是,如果有人感兴趣,我想分享我在制作应用程序方面的经验(包括市场营销和技术方面)。 我想分享的知识清单: 开源Moments的代码库 制作应用程序中的教程视频 制作应用程序之路的博客文章 我将把这些内容包装到一个包中,并使它们免费提供 。 实际上,我想知道这些值有多大。 拥有支持我的工作的支持者将非常高兴,这样我就可以将更多的时间用于工作。 我正在为此设置一个Patreon页面。 谢谢阅读! 😎 如果喜欢,请测试 5秒钟内 可以击打 […]

如何创建自定义表格视图单元格(快速)

这个故事最初发布在AppMakers.Dev 在iOS中,您可以使用“自动布局”来定义表格视图单元格的高度。 在本教程中,我们将向您展示如何使Table View Cells自动调整大小。 首先,创建一个简单的TableView,它属于您的ViewController。 创建名为Table QuoteCell的自定义TableViewCell类。 在StoryBoard中打开ViewController并将CellID添加为tableViewCell标识符。 将两个名为quoteLabel和authorLabel的标签添加到自定义单元格。 向它们添加约束。 在QuoteTableViewCell类中为这些标签设置IBOutlets。 我们的应用程序将显示引号。 假设我们要在TableView中包含以下带引号的数据。 在您的ViewController中添加dataForTableView变量。 让dataForTableView = [(“我没有失败。我刚刚找到了10,000种行不通的方法。”,“ Thomas A. Edison”),(“一个人不过是他思想的产物。他在想什么,他成为。”,“圣雄甘地”),(“业余者坐下来等待灵感,我们其余的人都站起来去上班。”,“斯蒂芬·金”),(“智慧不是教育的产物,而是终身尝试获得它。”,“阿尔伯特·爱因斯坦”)] 让我们设置TableView。 我们的ViewController将包含以下代码: // // ViewController.swift // SelfSizingTableViewCells // //由Apps-Top.com团队创建 // Apps-Top.com // 导入UIKit ViewController类:UIViewController,UITableViewDelegate,UITableViewDataSource { @IBOutlet弱var tableView:UITableView! 让dataForTableView = [(“我没有失败。我刚刚找到了10,000种行不通的方法。”,“ Thomas A. Edison”),(“一个人不过是他思想的产物。他在想什么,他成为。”,“圣雄甘地”),(“业余者坐下来等待灵感,我们其余的人都站起来去上班。”,“斯蒂芬·金”),(“智慧不是教育的产物,而是终身尝试获得它。”,“阿尔伯特·爱因斯坦”)] 覆盖func viewDidLoad(){ super.viewDidLoad() //加载视图后进行其他任何设置,通常是从笔尖进行。 self.tableView.delegate =自我 self.tableView.dataSource =自我 } 覆盖func didReceiveMemoryWarning(){ […]

Swift 101 —类型别名

这是遍历Swift声明( typealias )的超快速博客。 苹果公司将其描述为: 类型别名声明将现有类型的命名别名引入程序。 简单来说,这意味着您可以命名( 别名 )现有类型,例如String , Int或Bool ,实际上几乎是任何名称(不包括某些swift keywords )。 这可以使您的代码更具可读性。 让我们看一下我们之前使用的示例: //此示例中的购物篮是一个Items数组。 其中项目是字符串的类型别名 typealias项目=字符串 typealias篮子= [物品] var篮子:篮子= [] basket.append(“ Apple”) 这意味着可以将Items添加到Baskets 。 这比将Strings添加到[String]更具可读性。 此处的Items可以与其父类型String完全相同的方式创建。 让项目:项目=“苹果”

Swift中的Redux模式

在Swift中进行Redux吗? 是否可以在Eine iOS App中恢复JavaScript库并消除JS Zeug残酷的问题? 在设计模式和建筑设计中的修女,以及其他的书目。 标准MVC模式和ViewController之间的问题,由Gerl mal ins Endlose reichen负责。 Testbarkeit istfürnArsch,死于Übersichtüberdas ganze Projekt。 Dann haben wir noch den viel zu oft kopierten Code um wieder and wieder die gleichen Dingeauszuführenetc pp。 Natürlichgibt es daunzähligeMöglichkeiten(Wie immer)死于问题zulösen。 iOS Swift Blase lebe的应用程序之类的应用程序,以及React Native的其他应用程序。React.js在Webprojekte网站上的发布,请立即订阅。 Eine kleineErläuterung,我们的人eigentlich sich dieMühemachte,sich das Redux Prinzip zuüberlegen: 在React ist中,Komponenten aufgebaut ist中的dass eine […]

Swift:在两分钟内了解变异函数

如果您曾经尝试过在Swift的类方法中使用mutating关键字 ,则编译器肯定会对您大喊大叫,因为您做错了什么。 迅速地,类是引用类型,而结构和枚举是值类型 。 默认情况下,不能在其实例方法中修改值类型的属性。 为了修改值类型的属性,必须在实例方法中使用mutating关键字 。 使用此关键字,您的方法便可以更改属性的值,并在方法实现结束时将其写回到原始结构。 以下是Swift中Stack的简单实现,说明了变异函数的用法。 我相信这很容易理解。 但是,如果您需要任何澄清或问题,请在下面给我留言,我将为您解答。 谢谢阅读。

PhotoKit的迷你教程

我正在创建一个简短的教程,说明如何从照片库中获取图像并将其显示在故事板上。 这将要求用户许可,然后自动显示图像。 本教程将从库中获取第一张图像并显示它。 我们将使用PhotoKit ,有关更多信息,请阅读Apple指南。 我们首先创建一个名为loadImage的新方法,该方法将返回可选的UIImage 。 我们将使用此方法来抓取图像以显示在屏幕上。 将其设为可选,以防万一我们无法从照片库中获取任何图像。 创建一个用于获取照片资产的管理器对象。 PHImageManager会缓存资产图片,从而使我们重新请求的资产能够更快地加载。 默认方法返回管理器对象。 接下来,创建类型为PHFetchResult的fetchResult 。 此类为我们提供了从Photos fetch方法返回的资产的有序列表。 PHAsset实例表示我们将检索的图像。 fetchAssets方法将检索图像。 选项使我们可以对获取的资产进行过滤和排序,而fetchOptions是接下来要创建的方法。 我们实例化PHFetchOptions类。 此类将使我们能够从获取的资产中过滤,排序和管理结果。 sortDescriptors属性指定获取的对象的顺序。 我们将使用一组键路径和排序顺序来使用NSSortDescriptor数组。 我们将使用creationDate键根据资产的创建日期对资产进行排序。 您可以在此处了解有关关键路径的更多信息。 请求选项方法将返回PHImageRequestOptions 。 我们将使用此方法来影响图像的传递方式。 我们将isSynchronous的布尔值设置为true。 此属性使我们可以设置图像的质量或获取请求的传递速度。 我们返回requestOptions ,我们将在loadImage()方法中使用此方法。 让我们回到我们的loadImage方法并添加以下代码: 我们将创建一个可选图像,并在没有功能的情况下返回该属性。 使用requestImage查找指定的资产。 我们将使用之前创建的fetchResult对象通过使用object(at :)方法来获取特定索引处的资产。 我们还指定了图像尺寸和内容模式,该模式告诉我们如何使图像适合请求尺寸的宽高比。 我们将创建的requestOptions()方法传递给options参数。 这说明了我们的请求将如何处理。 创建一个保护声明,以确保我们的img不为空,否则我们只将图像返回nil。 然后,我们将最终返回我们的形象。 接下来,在情节提要中。 将ImageView添加到View Controller中,然后将插座连接到您的swift文件。 @IBOutlet弱var imageView:UIImageView! 现在,我们将创建一个处理用户权限的photoAuthorization方法。 此方法将检查用户是否向我们授予了访问照片库的权限,如果获得我们的授权,我们将运行其余方法。 如果没有,我们将只打印一份声明。 如果愿意,可以使用UIAlertController提示警报消息。 这会检查我们当前的授权状态。 PHPhotoLibrary对象代表“照片”应用程序管理的整个资产集。 switch语句用于检查我们的状态并确定我们应该做什么。 如果身份验证成功,我们将使用loadImage方法将图像返回到imageView出口。 […]

迅捷网络层-更新

首先,我要对拍手的每个人表示感谢,对我以前的文章发表评论:“在Swift中编写网络层:面向协议的方法”。 经过评论中的反馈和更多研究后,我认为解决本文中建议的改进将是有益的。 我们可以对项目进行两个简单的修改,以改善其功能。 在我们先前的URLSession实现中,我们使用了URLSession.shared 。 此代码有效,但不是最佳方法。 每次发出请求时,我们都会实例化一个新会话。 建议有一个URLSession和多个任务。 以前的实现。要解决此问题,我们将在使用默认配置创建路由器时实例化会话。 您可以使用3种不同类型的配置来创建会话。 我建议您从Raywenderlich.com阅读本文。 使用此代码,我们可以创建一个会话并执行多个任务。 这里的另一个优势是,我们可以调整路由器初始化代码以具有会话参数,通过使用模拟,我们将使编写测试变得更加容易。 为此,我要感谢Koen Punt和ilya stroganov的评论。 我不知道URLQueryItem已经编码了我们的参数。 这是一个快速更新,只需删除 .addingPercentEncoding(withAllowedCharacters:.urlHostAllowed)。 并做了。 我永远不会表现出我所了解的一切。 我在Medium上写作时正在学习所有这些内容。 有时候,我会引用自己的帖子来提醒如何实现目标。 具有终身学习者的态度将使人成长。 我喜欢分享自己的发现,并希望能在此期间帮助某人。 话虽如此,如果有任何主题,您可能希望我发表评论,请在评论中提及。 再次感谢您的所有👏🏾。 在Swift⚡️中继续学习和思考。

Swift-适用于iOS 11大标题的自定义导航栏图像🎨

标准的iOS组件可能会很无聊……幸运的是,有了Swift,自定义随处可见! 本文将演示如何在导航栏中使用自定义图像,同时仍保留导航控制器中提供的所有功能。 🚀 TL; DR :使用少量代码清除导航控制器提供的默认导航栏图像,并将其约束在视图的顶部,前导和尾随锚点上,以将其放置在适当的位置(请确保不要约束到安全区域) 。 您可能需要手动创建可能是您要记住的自定义导航栏标题。 有很多方法可以做到这一点,但最简单的方法就是使用Sketch。 使用矢量工具,我能够在几分钟内创建出我想要的设计。 这里的尺寸并不重要,因为Sketch默认具有出色的导出预设(iOS预设提供标准的Xcode要求的@ 2x和@ 3x大小)。 假设您已经在导航控制器中嵌入了视图控制器,则下一步是从提供的默认标题图像中剥离导航栏。 这相当简单,可以用几行代码来完成。 这是我用来执行此操作的功能; 请注意-我将其用作重用的struct ,但这是可选的。 既然导航栏已经清晰了,我们就可以提供自己的图像了。 出于本文的目的,我将使用界面生成器来完成此操作。 这就像将UIImageView拖到视图控制器上,提供适当的图像并设置约束一样简单。 为了设置约束以使iPhone X不会裁剪图像,我们需要约束imageView的顶部锚点以view的顶部锚点(而不是安全区域)。 在我的情况下,将约束设置为0在边缘沿边缘留一个小间隙,因此值-2应该可以解决该问题。 当然,高度限制将根据所使用的图像而变化。 并且,由于我的图像较暗,因此我还将大标题文本的颜色设置为白色,并将状态栏设置为.lightContent 。 此时,自定义标头应按预期工作 您可能会注意到标题图像在iPhone X上看起来不错,但在其他任何设备上看起来都太大了。 这是因为view的顶部锚点和X上的view的顶部安全区域锚点之间存在间隙。幸运的是,可以通过IBOutlet引用轻松地调整图像的高度,以参考图像视图的高度约束。 完整的设备尺寸可在此处找到。 将此代码放在同一区域,我们清除导航栏默认图像: 您可能还会注意到,将设备旋转到横向时,标题图像的高度过高。 这可以通过视图控制器中提供的willTransform(to:with)方法轻松处理。 我没有在示例中包含它,但这也可以在导航栏中添加栏按钮项。 而已! 您的自定义导航栏图像现在应该可以正常工作work 随时在Twitter和Github上关注我,以获得更多类似this‍👨🏻的内容

征服ReactiveSwift:简介

“反应式编程具有陡峭的学习曲线。” 在学习函数式反应式编程(FRP)时,我一直在听到这些。 从命令式编程的背景出发,我努力掌握了FRP的各种概念。 从最基本的角度来看,FRP的好处是它使您可以建模时间。 但这很难使您动脑子。 为了帮助您克服学习难题,我将在“征服ReactiveSwift”系列中分享我的学习经验。 我的目的是为初学者提供一个循序渐进的指南,以学习ReactiveSwift。 这是该系列的第一篇文章。 它介绍了功能性反应式编程,并说明了它与命令式编程的区别。 命令式与功能式反应 为了理解这些编程范例之间的区别,让我们举一个例子。 假设我们要实现一个用户界面,该用户界面具有一个UILabel (我们称之为label )和一个UITextView (我们称之为textView ),其中UILabel反映了在UITextView中输入的文本。 为了实现这种行为,我们编写如下代码: func textViewDidChange(_ textView: UITextView) { label.text = textView.text } 上面的代码可以正常工作。 我们一直在这样做。 那是什么问题呢? 让我们调查一下。 考虑一下旨在更新标签文本的语句: label.text = textView.text 这是一个赋值语句。 这是什么意思? 这意味着在label.text时, label.text等于label.text 。 该语句不封装有关分配点之前或之后的label.text状态的任何信息。 换句话说,一旦将时间概念引入模型,语句label.text is equal to textView.text不一定成立。 因此,我们需要将此语句封装在委托方法textViewDidChange ,以使label的状态保持一致。 以命令方式,很难优雅地表示这样的关系。 欢迎使用反应式绑定 在反应式编程中(特别是在ReactiveSwift中),可以通过绑定解决相同的问题。 label.reactive.text <~ textView.reactive.continuousTextValues 该语句暗示在label的整个生命周期内, label的文本与textView的文本相等。 […]

iOS / Swift —创建多个动态选择器视图:快速教程

我一直在为我在Facebook上的项目完成最后的接触而努力,您可以在这里了解更多信息。 在我为应用程序püler贡献的所有功能中,我最喜欢的功能之一是汽车选择器视图: 为了实现这一点,了解UIPickerView对象和选择器视图与您拥有的数据进行交互的方式非常重要。 就我而言,我的数据结构如下所示: {make1:{model1:{year1,year2,…},model2:{year1,year2,…},…},make2:{…},…} 所以基本上是字典的字典,是的,我知道您现在可能已经讨厌我了,但请听我说。 由于汽车的工作结构,这是必要的,对于仍然不了解正在发生的事情的你们来说,看起来像这样。 (请原谅丑陋的图画^)。 无论如何,在宏伟的计划中,有多个品牌,每个品牌都有多个型号,每个型号都有几年。 现在,为了制作动态选择器视图,我们首先在情节提要中添加三个UIPickerViews并为其创建出口。 相应地命名,我的被称为: 之后,我们需要设置PickerViewDelegate,以便Xcode知道我们将为pickerView提供数据/指令,而不是它。 为此,请确保在类标题中添加UIPickerViewDataSource和UIPickerViewDelegate 。 在将这两个函数相加后,您应该得到错误消息,表明您尚未声明某些函数,但不要担心,我们马上就可以解决这些问题! 我们现在必须实现的三个功能是: func numberOfComponentsInPickerView(pickerView:UIPickerView)-> Int func pickerView(pickerView:UIPickerView,numberOfRowsInComponent组件:Int)-> Int func pickerView(pickerView:UIPickerView,titleForRow行:Int,forComponent组件:Int)->字符串? 第一个询问在pickerView中应包含多少个组件。 我选择有1,但是具有多个组件的pickerView看起来像这样: 我选择不使用它的原因是一个简单的设计决定,但是我的代码也可以进行编辑以适合这样的内容(也许会在将来发表文章?)。 因为我决定每个pickerView仅保留一个组件(并且在一个pickerView中不包含3个组件),所以我在函数中简单地返回了1: func numberOfComponentsInPickerView(pickerView:UIPickerView)-> Int { 返回1 } 现在来看两个稍微复杂的功能。 让我们开始 func pickerView(pickerView:UIPickerView,numberOfRowsInComponent组件:Int)-> Int 该函数要求每个组件中需要的行数,但是由于每个pickerViews只有一个组件,因此我们可以为每个组件返回一个特定的整数。 我们要返回makePicker的品牌数量, modelPicker的模型数量以及yearPicker的年数。 如果我们拥有所有品牌,型号和年份的阵列 ,那么我们要做的就是: func pickerView(pickerView:UIPickerView,numberOfRowsInComponent组件:Int)-> Int { 如果pickerView == makePicker { 返回listOfMakes.count } 否则,如果pickerView […]