Tag: swift

自学系列| iOS Swift | 第二课:介面开发(UIKit)第1部分

前言:为什么会有「自学系列」 当我还是程式初学者时,觉得自学最麻烦的就是:那些课程大纲,专有名词我根本看不懂。如果有个已经会的人直接跟我说要学什么,给我一个概述,可以省下很多时间。 关于iOS App自学系列我已经写了两篇,有兴趣可以去看看。 自学系列| 斯威夫特| 用免费的线上学习资源入门iOS App 初学者到底有什么基本东西要学? medium.com 自学系列| iOS Swift | 第一课:开发工具+ App基础观念+基础UI 用AVFoundation做一个简易变声App medium.com 简介文章是Udacity iOS应用程序Nanodegree第二课的导读,透过做成这个影片中的App,熟悉介面开发常见的几个元素。 第二课连结在此 ,我们将学会底下几个主题。 UIKit基础知识:了解iOS用户界面库| Udacity 了解iOS UIKit框架,这是在所有iOS应用程序中创建用户界面的基石,对任何其他应用程序都至关重要。 www.udacity.com 1.重点观念 代表 Delegate对初学者而言是一个逃不掉的魔咒,记得自己初学Delegate时,不懂为什么要有这种东西,只会一个案例,一个案例照抄。三个月后大概可以不再参考案例,顺顺地自己写出Delegate,直到最近写这篇文章,我才觉得有点理解它了。 先帮大家打个预防针: 有时候学东西是这样:先照抄➙会自己写➙练习很多很多次之后,终于理解为什么要这样写。 Delegate是代理人的意思,在上一篇有提提过,它是一种写程序的方法(设计模式),用于当A想叫B做事情的时候。还记得MVC吗?View(介面)负责呈现画面给用户,Controller则是负责处理逻辑,例如Controller会根据一些逻辑,告诉查看现在要变成什么画面。 所以,很多时候查看会分配控制器为Delegate(代理人),问Controller现在要如何呈现自己。 举凡为呈现多种资料的UITableView,UICollectionView,呈现文字的UITextView,UITextField,选择日期,数字的UIPickerView …等等,都会用到Delegate。 协议就是这样的东西,遵从Protocol的代表就会有要执行的功能。底下用UITextField视为示例。 UITextField UITextField用于输入文字(如左图红色框局部)。 在第二课的范例中(右图),三个TextField的文字呈现都不同,表示这三个TextField是不同的代理人(代表): 第一个Delegate可以把动物的单字变成表情符号(例如cat变成🐱) 第二个Delegate会根据单字改变句子的颜色(例如红色) 第三个Delegate会算出句子的字数 这三个Delegate都遵从UITextFieldDelegate这个协议,所以当我们输入文字时,三个代理人就要执行该协议 func textField(UITextField,shouldChangeCharactersIn:NSRange,replaceString:String) 这个功能,差异只是功能里的逻辑要写什么,决定文字会怎么变。就像外交官出席活动一定要发新闻稿,但新闻稿内容要写什么,则因人而异。 2.资料呈现 UITableView / UICollectionView 仔细观察的话,你会发现多数的App都用到TableView或CollectionView。 TableView就是一行一行排下来的,像iPhone内建的设定(左图),Line,Messenger,邮件,备注,YouTube,Facebook …等等,CollectionView则是一格一格的,像instagram(右图),照片,旅行青蛙购买道具和放明信片的页面…等等。 TableView跟CollectionView都要用到Delegate(所以Delegate真的逃不掉!),以TableView来说,就有UITableViewDelegate,UITableViewDataSource这两个。UITableViewDelegate负责处理使用者产生的行为,例如当使用者点选表格,编辑表格时,要怎么回应; […]

如何调整textView的大小以适合其内容(根据contentsize调整textview的大小)

我正在尝试调整textView的大小以适合其内容,该内容是多行长文本。 我不明白的 对于stackoverflow有一个直接的答案,它基本上使用“ sizeThatFits”方法。 此方法要求UIView计算适合其内容的大小。 多好。 但这对我来说不起作用,我也不明白为什么。 我做了什么 我的代码如下所示: 导入UIKitclass ViewController:UIViewController { @IBOutlet弱var topTextView:UITextView! @IBOutlet弱var bottomTextView:UITextView! 覆盖func viewDidLoad(){ super.viewDidLoad()让LONGTEXT = “hogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehoge” topTextView.text = LONGTEXT bottomTextView.text = longText topTextView.isScrollEnabled = true bottomTextView.isScrollEnabled = false 调整大小(textView:topTextView) 调整大小(textView:bottomTextView) } fileprivate func resize(textView:UITextView){ var newFrame = textView.frame 让width = newFrame.size.width 让newSize = textView.sizeThatFits(CGSize(width:width, 高度:CGFloat.greatestFiniteMagnitude)) newFrame.size = CGSize(width:width,height:newSize.height) textView.frame = […]

持续的iOS学习-第1部分(文章)

我想与大家分享我所订阅的网站,博客和新闻通讯 ,每天我都会学到有关iOS , watchOS , tvOS和OS X应用开发的新知识。 随意添加自己喜欢的。 http://swiftsandbox.io http://www.cimgf.com http://ios-goodies.com http://en.swifter.tips https://littlebitesofcocoa.com https://iosdev.tools https://www.natashatherobot.com http://appcoda.com http://iosdevweekly.com https://www.objc.io http://swiftdevweekly.co http://realm.io http://useyourloaf.com http://nshipster.com http://nsscreencast.com http://www.pomo.tv http://www.cocoawithlove.com https://www.skilled.io https://www.weheartswift.com http://www.sososwift.com https://www.mikeash.com/pyblog/ http://swiftdeveloperblog.com http://jamesonquave.com http://www.learnswift.tips

在Swift中与后端交互

如果开发应用程序,则很可能在某个时候会遇到对服务器进行API调用的需求。 有时,这在开始时可能会造成混淆,因此我会帮助您,并为您提供有关如何使用Alamofire进行GET和POST调用的快速概述。 显然,您首先需要安装Alamofire Pod,然后在Podfile文件中添加: pod ‘Alamofire’ 然后在终端中,运行pod install 。 完成后,您可以在Xcode中import Alamofire 。 由于我们只是在创建演示,因此可以将代码示例放入AppDelegate 。 简单要求 在这些示例中,我们将使用https://jsonplaceholder.typicode.com/。 它将允许我们与API交互,而无需我们自己的服务器等。 假设它起作用了,您应该在我们的控制台中得到以下内容: 那么我们在这里做了什么? 好吧,我们告诉Alamofire,我们想要对URL“ https://jsonplaceholder.typicode.com/posts/1”的GET请求,并且希望响应以JSON格式返回。 Alamofire如何知道我们想要GET请求? 好吧,默认情况下,Alamofire将执行GET请求,尽管您可以通过添加method参数并使用Alamofire的HTTPMethod枚举(.get,.post,.patch,.options,.delete)来更改它。 这是一个明确表示我们需要.get请求的示例。 现在您很好奇,我们可以获取数据,但是如何获取数据以在我们的应用程序中使用? 如您所见,我们正在请求.responseJSON这意味着我们将响应作为JSON对象返回,我们还可以执行.responseString 。 对于我们的示例,我们将坚持使用JSON。 要获取JSON对象,我们需要读入response.result.value 。 如您所见,您收到一条警告,指出response.result.value是可选的。 因此,让我们使用guard let语句来处理它。 现在,我们创建了一个名为json的dictionary ,现在可以打印响应的正文。 应该在控制台中像这样获得body : 现在,我们知道了如何执行GET请求并将JSON响应解包到字典中并访问该值,让我们来看看如何进行POST请求。 POST请求 这是POST请求的简单示例: 一旦运行,您应该在Xcode控制台中看到一个输出,其中的标题已打印出来: 包起来 我希望本文对使用Alamofire进行GET和POST方法提供了有价值的信息。 与往常一样,如果您有任何建议或问题,请随时与我们联系。 谢谢!

学习以编程方式创建iOS视图

在上一篇文章的结尾,我答应展示如何编写“自动布局”约束并以编程方式创建视图。 这篇文章是涵盖Swift和iOS开发许多方面的一系列文章中的第一篇。 从iOS 9开始,编码约束变得容易得多。 Auto Layout NSLayoutAnchor类在以非常流畅的方式创建约束方面提供了巨大的帮助。 但是,在达到这种流利程度之前,您需要了解和学习两个非常重要的知识: 了解视图,子视图以及两个视图,两个子视图或视图与子视图之间的关系。 学习并了解用于创建自动布局约束的语法。 因此,让我们开始吧。 参考上图,有两个全角和等高的视图,它们垂直居中放置。 视图1和视图2都是其父视图的子视图-在这种情况下,控制器的主视图位于视图1和视图2的顶部。 还需要注意的是,视图1的底部边缘正在触摸视图2的顶部边缘。 View 1的顶部,左侧和右侧边缘与Superview的顶部,左侧和右侧边缘对齐。 View 2的左,右和底边与Superview的左,右和底边对齐。 添加标签只是为了创建引用。 我们不会在这篇文章中介绍UILabel类。 让我们开始编码。 1.为了开始,我们必须首先在UIViewController类(或View类,如果愿意)中声明变量-view1和view 2。 2.我们必须添加视图1和视图2作为控制器主视图的子视图。 3.这行代码非常重要。 在这里,我们必须设置view1和view2的translationsAutoresizingMaskIntoConstraints属性。 此属性的含义是,如果将其设置为true,则会将其自动调整大小的蒙版转换为Auto Layout约束。 我们不希望那样,因为我们要定义自己的约束。 因此,我们需要将property设置为false。 4.现在我们必须为view1设置约束。 上面的代码的前三行将view1的顶部,左侧和右侧锚点设置为与superview的顶部,左侧和右侧锚点相同。 这是因为view1的顶部,左侧和右侧边缘与其superview的顶部,左侧和右侧边缘对齐。 为了激活这些约束,您必须将isActive设置为true。 这非常重要,因为默认情况下isActive设置为false。 在第4行中,view1的高度锚点设置为超级视图高度的1/2。 这是因为view1的高度是超级视图的高度的1/2。 注意:类似于在这种情况下使用的“乘数”公式,您也可以使用可以加或减的“常数”。 第5行设置背景色。 5.现在我们必须为视图2设置约束。 上面代码的前两行将view2的左锚和右锚设置为与superview的左锚和右锚相同。 这是因为view2的左右边缘与Superview的左右锚点对齐。 您也可以添加bottomAnchor约束,但是由于我想向您展示两个视图之间的关系,因此我们将其留待以后使用。 第三行将view2的高度设置为超级视图的高度的1/2。 第4行强调了自动版式的一个非常重要的方面。 它定义了view1和view2之间的关系。 这行代码将view2的顶部锚点设置为等于view1的底部锚点。 这是因为view2的顶部边缘与view1的底部边缘对齐。 这是完整的代码: 这是您应该尝试创建自己的另一个示例: 参考上图,“视图”是控制器的主视图。 您将需要为其添加背景色。 子视图1和子视图2具有相同的大小,并且是View的子视图。 子视图1和子视图2水平居中,两者之间有50个点的间隙。 子视图1的左边缘与视图的左边缘相距100个点。 […]

可选扩展

是空还是零? 您知道扩展对Swift来说是一个奇妙的事情,但是当我们可以有意义地使用它时,它会更好。 所以今天我想分享我学到的东西,我非常喜欢,有时候我们需要同时检查一个字符串是空还是空,我们有一些方法可以做到这一点,例如: 你喜欢它吗? 不幸的是,它不是String类型的本机属性,但添加起来很容易,如下所示: 它正在检查与Collection类型有关的可选参数,并验证它是否为nil并返回true,否则它会检查其本机属性“ isEmpty”,这很简单,对吧? 我希望它可以帮助您提供干净且可读性强的代码。 再见

iOS(Swift):具有可变高度的TableView节标题-适合内容

由于要求,必须根据“设置”更改动态更改TableView的Header部分的内容。 问题 :随着节标题内容的动态变化,节标题的高度必须改变以适应变化的内容。 解决方案 : 以下是实现解决方案的步骤 步骤1 : 设置TableView以支持自动调整大小 覆盖func viewDidLoad(){ super.viewDidLoad() self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension; self.tableView.estimatedSectionHeaderHeight = 38 } 步骤2 : 区段标题 使用自动布局创建节标题视图,这里我们使用NSLayoutConstraint动态创建自动布局UIView func tableView(_ tableView:UITableView,viewForHeaderInSection部分:Int)-> UIView? { 让headerView = UIView() 变量约束= [NSLayoutConstraint]() 如果section == 0 { 让flightStatsNoticeLabel = UILabel() flightStatsNoticeLabel.text =“ Lorem Ipsum只是印刷和排版行业的虚拟文本。 自1500年代以来,Lorem Ipsum一直是业界标准的伪文本,当时一位不知名的打印机拿起一个厨房,然后将其打乱成一本样本书。” flightStatsNoticeLabel.numberOfLines = 0 flightStatsNoticeLabel.sizeToFit() 让goToSettingsButton = UIButton() goToSettingsButton.setTitle(“ GoToSettings”,用于:.normal) […]

更好的Swift测试设置

在编写测试时,我们必须以良好的代码和质量来进行测试,使其变得更加干净,简单和快速,对吗? 但是有时候很难做到。 我们开始在测试中看到一些可重复的代码,设置和期望值。 今天,我将向您展示提示/技巧 ,以在没有框架的情况下为您的测试创建可重用,更简洁的设置。 让我们开始展示一个使用swift默认测试库的示例。 XCTest。 初试班 该类将以不同的方式测试UserRepo存储库类中名为findAdminsBy的函数。 上面的测试代码易于理解和重用,对吗? 具有一些帮助程序功能,安装程序在每次测试之前运行并重用变量。 是的,很简单并且可重用。 但是,让我们列出一些“问题”: 我们只测试UserRepo的一个功能,即findAdminsBy : –如果要测试UserRepo的另一个功能将增加一些复杂性; –要测试另一个功能,我们需要更改setUp功能或将其删除并将其放入期望功能中。 什么不好,因为这将是一个冗长的考验; 需要更改默认设置时,作为第一个功能测试。 在期望函数内添加了一个设置; 每个期望函数都在调用可重复代码: result = userRepo.findAdminsBy(email: email) 如有必要,添加新参数,我们需要在所有期望函数中进行更改。 那么,我们如何才能为上面的列表改进并创建一些解决方案? 我们将使用闭包概念用作设置并执行可重用的动作。 为了更好地了解闭包 ,这里是官方文档。 首先,我们需要创建两件事来帮助我们的测试。 #1 —动作结构 该Struct将有助于保持关闭状态直到被调用为止。 在闭包内部,将包含您需要保留的操作。 例如: result = userRepo.findAdminsBy(email: email) 。 用法将在稍后显示。 #2 —执行功能 该功能将有助于通过一些设置配置来运行/执行操作 。 波纹管是Executer.swift文件: 第二级考试-重构 现在,让我们使用这两个助手实现一个新的Test类。 我们可以看到的第一件事是操作和设置特定于findAdminsBy函数。 如果我们需要测试UserRepo的其他功能,只需使用自己的设置添加其他操作。 该代码现在更加灵活,可重用和更简洁。 该测试继续简单易懂。 如果您像我一样参加BDD测试,那么我将向您介绍测试框架Quick。 这将帮助您以BDD样式进行测试。 […]

在Swift中使用通道进行数据流📻

最初发表在 Swift Post上 。 Apple框架大量使用委托和观察者模式(NotificationCenter)来传递信息。 尽管这些模式没有错,但实际的实现始终对我来说有点矛盾。 首先让我们看一下这些模式的基本特征: 委派:支持一对一的双向通讯。 观察者 :支持一对多,单向通信。 让我们看一些UITableViewDelegate方法。 可选的func tableView(_ tableView:UITableView,heightForRowAt indexPath:IndexPath)-> CGFloat UITableView :发件人 UITableViewDelegate (主要是 UIViewController ) :接收器 此方法是一对一双向通信的一个很好的例子。 由于表格视图要求控制器返回高度,因此通讯是双向的,不能一对多。 (否则,我们将无法决定应使用哪个返回的高度值。) 但是,以下方法不返回任何内容。 可选的func tableView(_ tableView:UITableView,didSelectRowAt indexPath:IndexPath) 在此,发送方仅通知接收方。 因此,通信是单向的,可以是一对一或一对多。 在这种情况下,授权是一个不错的选择吗? –也许… 如果我们需要通知多个组件会怎样? –我们不能。 如果我们不在乎行选择,而是想自己提供行高怎么办? 我们还需要提供空的实现吗? –如果这是一个纯Swift协议, 是的 ,我们将需要为每个我们不关心的委托方法准备空的实现,这很烦人。 由于UITableViewDelegate继承自Objective-C,因此为了向后兼容,我们可以将方法标记为可选。 但是Swift出于某种原因禁用了此“功能”。 具有庞大的协议会违反接口隔离原则,并使它们无法读取。 表视图是我作为开发人员生活的重要部分,但我仍然不记得UITableViewDelegate和UITableViewDataSource协议中定义的内容,因为列表太长了。 那么……为什么我们不对每个单向动作都使用观察者模式呢? 我们可以提供具有更大灵活性的相同功能,并且还可以清除大型委托协议中的大多数方法。 我们有一个设置页面,其中包含主题选择。 每当主题更改时,我们都希望更新主屏幕。 解决方案1:使用委派 此解决方案有效,但是否足够灵活? 如果我们有5个选项卡要与此主题更改进行更新,会发生什么情况? 解决方案2:使用NotificationCenter 现在,我们支持一对多通信,但是我们将线路数量增加了一倍,对吗? […]

生活的东西:更新

哇 最近两个月一直是旋风。 我希望我可以说我一直处在一个狭窄的焦点通道中,干扰了像freakin-Robot先生这样的代码,但是不,我已经完全被生活所取代。 6月,我收拾了自己在俄勒冈州波特兰的生活,搬到阳光明媚的洛杉矶,与一些朋友,工作机会,温暖以及我可爱的女友Nina更加亲近。 七月花在从佛蒙特州一直延伸到哥伦比亚特区的东海岸小巷中,一路上看到家人和老朋友。 现在,定居在金州,我又回到了流程中,终于能够花时间再次为这样的个人开发项目降温。 这是我们离开的地方。 现在,大多数阅读此书的人都知道,我正在自学如何在公共场合构建应用程序。 该应用程序将使乘坐同一飞机旅行的人们能够相互交流,并有希望见到IRL。 这就是它的工作方式。 自上一篇文章以来,我已经完成了Udacity大约一半的免费在线课程,这些课程向人们教授Apple的iOS编程语言Swift的基础知识。 该课程非常有趣。 该平台具有巨大的潜力,一开始看起来很不错,但是实际功能有点笨拙(您怎么说)。 在大多数情况下,内容就在那里。 有些课程视频可以很轻松地指导您完成每节课。 有时候,我完全迷路了。 有些视频丢失了,我不得不在YouTube(所有的课程视频都在此托管)上进行挖掘,以找到丢失的课程。 另一个重大的失败之一,这不是Udacity的错,是没有活着的老师,当您陷入困境时,没有人可以帮助您。 您所拥有的只是视频讲师的声音和Google的重复。 在某些情况下,他们让我构建的练习应用程序出现了随机错误,并停止了工作。 我无法启动它或无法按预期的方式使用它,而且我也不知道自己做了什么使它变成狗屎。 因此,我不得不从头开始重建整个事情。 事实证明,这实际上是重复练习的好方法,但是却不是很多乐趣。 在亮的一边。 苹果公司专有的开发环境Xcode让我感到惊喜。 开发环境是一组软件,可模拟本地计算机上的实时应用程序(iOS应用程序,网站)。 它使您可以在将最终产品发布给全世界之前,在计算机上安全地编写和测试代码。 在Xcode中,用户界面几乎都是图形的。 它们具有代表应用程序所有部分的图像,这使查看应用程序不同部分之间的相互关系变得非常容易。 您也可以轻松地在内部进行浏览以查看和编辑基础代码。 这种设置使学习Swift就像观看带有外国字幕的英语电影一样。 在故事中浏览时,您可以直观地了解正在发生的事情,但是您始终可以窥视到如何将其翻译成与图像相对应的外语。 实际上,这是学习如何阅读该语言的好方法。 因此,我很享受使用Xcode的舒适感。 不必是这种方式。 我本可以放到一个黑色的终端屏幕中,而只有绿色字母垂直向下移动才能使用。 我很高兴不是那样。 接下来。 我期待着在接下来的几周内重新振作起来,并为您准备一份有关如何计划结束本项目的大量报告。 目前,我觉得我只是在测试水域,因此我们应该能够尽快制定出切实可行的计划。 感谢您的跟进! 直到下一次。