如何仅使用一个元素制作无限提要并一次又一次地重用它? 让我们在快速指南中使用UITableView创建一个简单的项目! 表格视图在单个列中显示项目列表。 UITableView是UIScrollView的子类,尽管UITableView仅允许垂直滚动,但它允许用户滚动表。 组成表格中各个项目的单元格是UITableViewCell对象; UITableView使用这些对象绘制表的可见行。 单元具有内容(标题和图像),并且在右边缘附近可以具有附件视图。 标准附件视图是公开指示符或详细信息公开按钮。 前者导致数据层次结构中的下一个级别,而后者则导致所选项目的详细视图。 辅助视图也可以是框架控件,例如开关和滑块,也可以是自定义视图。 表格视图可以进入编辑模式,用户可以在其中插入,删除表格并对其进行重新排序。 阅读有关Apple Developer的更多信息 创建一个新的Single View App项目。 热键:shift + Command + N 打开主板 如何将UITableView添加到情节提要? 只需按: Shift + Command + L 选择“表视图”并将其拖动到情节提要。 凉。 您的第一个表格视图已出现。 让我们设置约束以使表大小成为超级视图。 让我们在该模块中添加对该表的引用。 打开拆分模式 在视图上按Ctrl并将光标拖动到代码 写参考名 按连接 打开ViewController.swift文件。 修改文件中的代码。 你完成了! 拍! 拍! 请记住,成功的秘诀是不断学习和与同事沟通,包括自我教育。 这是有关UITableView和数据源的小指南。 在Apple Developer网站上了解更多信息。 不要停止自我教育。 GitHub项目 订阅我的帐户以获取有关新故事的通知。 如果您还有问题,请在评论中写。 我将在以后的文章中回答。
尼采,梭罗和黑森最有可能试图逃避他们一生的一个概念:依赖性。 即使一个人不同意或拥护他们的哲学,程序员应该还是必须? -在编程时运用他们的思维方式。 让我们先定义问题: 耦合 想象一下,没有一部可以拆卸的汽车。 从座椅到车轮,从底盘到天窗都是一体的。 如果由于在高速公路上钉了一些讨厌的钉子而使轮胎漏气,我不能只买新轮胎,就需要买一辆新车。 因此,我们将此设计称为耦合设计,或者以一种更真诚,更礼貌的方式进行; 愚蠢的设计。 编程没有什么不同。 如果某个类或功能的更改需要我重构程序的许多其他部分,那么我已经设计了这款不可拆卸的汽车。 不酷 一点都不酷。 那么,当我们意识到我们的代码紧密耦合时,我们该怎么办? 我们花了片刻的沉默。 我们意识到我们编写了一些糟糕的代码,并宣誓不再这样做。 靠这些话活着: 封装 , 单一责任和继承构成 。 我将以一些简单的示例开始,这些示例说明了我们如何在程序中尊重这些概念,然后将其构建为相当(但不是真的)复杂的示例。 钢琴家或小提琴家 您的功能签名应严格执行其声称的功能; 不多一点。 让它成为钢琴家或小提琴家,而不是两者。 所以我有一个函数应该打印字符串中某些字符的数量: func printNumber(of char:Character,in string:String?)} 如果让string = string { var count = 0 对于字符串{中的s 如果s == char {count + = 1} } 打印(数) } } 此功能做不到预期的。 如果为空字符串,则不打印任何内容,而应打印“ 0”。 […]
我的目标是创建一个私有的Cocoapods,将Google Analytics(分析)包装起来供团队使用。 这是我如何制作的演示。 您可以在下面看到我的项目。 ji3g4kami / GAReporter Google Analytics(分析)包装。 通过在GitHub上创建一个帐户为ji3g4kami / GAReporter开发做出贡献。 github.com 不使用依赖 最初我想在我的GAReporter.podspec文件中使用s.dependency = ‘GoogleAnalytics’ 。 第一个障碍是桥接标头在iOS项目中有效,但在框架中无效。 但是,在pod install之后,无法使用上面链接中提供的module.modulemap的解决方案。 在参考了Stanwood_Analytics_iOS和Challenges构建一个Swift框架(C ++,Objective C和Swift)之后,我得到了我的解决方案:直接将Google Analytics(分析)添加到Objective-C和Swift的混合框架中。 环境设定 设置Swift框架 添加.gitignore和许可 推送到您的远程存储库 导入Google Analytics(分析) 制作一个伪造的Single View iOS项目,并安装Google Analytics(分析)。 将整个Google Analytics(分析)复制到GAReporter。 添加必需的Google Analytics(分析) Linked Frameworks and Libraries 。 创建自定义module.modulemap 在构建设置中添加Module Map File 。 将“ Defines Module Yes设置为“ Yes 。 […]
解析文本的明智方法是使用ANTLR,yacc或解析器组合器甚至Xtext之类的工具。 但是,要聪明就意味着要研究那些工具和框架。 如果您不想学习,该怎么办?如果您只想编写一个解析器而又不花很多时间在学习“ 正确的 ”工具上,该怎么办? 比您应该继续阅读,因为这正是本文的主题。 看起来我可以解析文本!!! 通常,我们不仅仅为了踢球而解析文本。 我们进行分析,因为我们需要从文本表示中提取一些数据。 在本文中,我将使用:https://github.com/mzaks/FlatBuffersSwiftCodeGen 作为如何在Swift中扮演自己的解析器角色的示例。 我的代码不是超级健壮和干净的代码,但是,嘿,它是分析文章的愚蠢方式 。 目的是激发您学习我的错误并做得更好。 另外,如果您有兴趣全面了解文本解析术语和技术,我建议您阅读以下内容: 解析指南:算法和术语 我们已经介绍了一些解析术语,同时列出了用于Java解析的主要工具和库… tomassetti.me 无论如何,让我们从愚蠢的解析方式开始。 首先,我们需要了解文本是一维数字数组。 基于不同的编码,它可以是代表相同文本的不同数字。 因此,为了能够解析文本,我们需要就一种编码达成一致。 我定义了要解析的文本以UTF-8表示。 现在,正确的文本解析方法基于词法分析和词法分析两个阶段(有关更多详细信息,请参阅我之前提到的“分析指南”)。 我说搞砸了,我们处于愚蠢的解析状态 ,所以我们只有一个阶段,我们称之为吃eat 。 请看以下文件: mzaks / FlatBuffersSwiftCodeGen FlatBuffersSwift的代码生成器。 通过在以下位置创建帐户来为mzaks / FlatBuffersSwiftCodeGen开发做出贡献 github.com 在那里,我们有一个eat函数,它具有: 静态字符串-我们要吃的字符串 指向我们要开始进食的记忆的指针 和长度,这告诉我们我们想吃多远 它返回一个可选的指针,这意味着如果我们能够食用该字符串,那么我们将返回停止进食的指针,如果我们无法食用,则将返回nil 。 但是,在我们开始吃弦本身之前,我们先吃了空白。 空格是字符,对人类没有任何语义含义。 如果我们看一下前128个ASCII字符的字符编码表,它等于UTF8: ascii代码表新的优秀ascii家庭设计符号发生器代码表ascii代码tabelle.png 我们看到前0..<33是不可见的字符,可以视为空白。 因此, eatWhiteSpace函数的愚蠢实现: 公共功能eatWhiteSpace( _ p:UnsafePointer , 长度:整数 )-> […]
我打算暂时就Swift的日常实验写一些关于我的发现的“简短”文章……🕵 这是第一篇闪电文章! 🚀 问题:地图,flatMap和过滤器功能随附的中间杂波 假设我们在一个假想项目中具有以下要求: 可以下载6帧格式为animation_.jpeg 。 –使用Request对象下载动画帧。 –丢弃第二帧以获得更好的性能。 在现实世界中,我们很可能会有更多的帧,但可以将其视为简化示例。 我们将不使用这6帧的for循环,而是使用map , flatMap和filter方法。 让frameIndexes:[Int] = Array(1 … 6) 让imageRequests:[请求] = frameIndexes //通过每隔一帧过滤进行优化: .filter {$ 0%2 == 1} //将帧号转换为图像名称: .map {“ animation _ \($ 0).jpeg”} //将图片名称转换为网址: .flatMap {URL(string:“ https://www.somehost.com/\($0)”)} //转换网址以请求对象: .map {Request(url:$ 0)} 这比具有for循环更具可读性。 但是性能如何? 让我们逐行遍历此代码块来详细研究。 filter块对数组中的每个帧索引运行6次。 使用3个过滤的帧索引创建一个新数组。 每个图块运行3次。 将使用3个图像名称创建一个新数组。 flatMap块对每个项目运行3次。 将使用3个URL创建一个新数组。 (假设将在每个图像名称上成功创建URL。) map块在每个URL上运行3次。 使用3个请求对象创建一个新数组。 呼叫顺序将如下所示: […]
ПредставляяпервыйiPhone于2007年年初发行,СтивДжобсапеллировалкустареваниюконцепциифизическойклавиатуру Сэтогомоментанаразвитиеустройствскачественнымитачскринами,позоои Теперьпалец – главныйинструментуправлениядевайсомимыможемтапатьпокнопкам,свайпатьсписки,пинчитьфотографии…Давайтеразберемсякакэтореализованососторонысофтаинаучимсяиспользоватьвсюмощьмеханизмараспознаванияжестов。 UITouchиегообработка Нодавайтепопорядку。 Передтем,какначинатьраспознаватьжесты,надопонять,каквообщеприложениеполучаетинформациюокасаниях,свайпах,нажатияхнаэкраниктоихобрабатывает。 Чтопроисходит,когдапалецпользователякасаетсяэкрана? Системасоздаетобъекттипаевоетере Этозначит,чтонавремявсейцепочкисобытий “палецкоснулсяэкрана→палецдвижетсяпоэкрану→палецоторвалсяотэкрана” длякаждогопальца,касающегосяэкрана,существуетуникальныйобъектUITouch。 Далее,используямеханизм命中测试’,находитсясамаяглубокаявиирархииUIView,框架которойсодержиевсеб ПолученнаяUIViewстановитсяfirstResponder ,使用UITouchипрокидыватьихдальшепоresponseerChain 。 Дляобработкипоступающихсобытий,UIViewпредоставляетнесколькометодов: touchesBegan(_ touches:设置,并带有事件:UIEvent?) —началокасания(экранакоснулисьпальцы) touchesMoved(_ touches:Set ,事件:UIEvent?) —изменениепараметровкасания(позициянаэкране,сила(ForceTouch)) touchesEnded(_ touches:设置,带有事件:UIEvent?) —конецкасания(пальцыбылиубранысэкрана) touchesCancelled(_ touches:Set ,事件:UIEvent?) —отменакасания(далеерассмотрим,чтоэтозначит) ТаккакэкранiPhoneподдерживаетмультитач,товодинмоментвремениможетизменитьсясостояниесразу Например,еслипользователькоснетсяэкранадвумяпальцамиодновременно,системавызоветtouchesBegan лишьодинраз,новомножестве 设置 мыполучимдваобъекта—图库矢量图片。 Первыетриметода( 的touchesBegan,touchesMoved,touchesEnded)отвечаютза“нормальный”жизненныйциклUITouchивызываютсяприначалекасания,измененииегопараметров(позициянаэкране,силанажатия)иконцекасаниясоответсвенно。 Однако, 触摸 выбиваетсяизихряда已取消。 Насамомделе,концомжизненногоциклаUITouchможетбытьнетолькофизическийконецжеста,ноикакое-либопрограммноесобытие,вследствиекоторогосистемабудетвынужденапрерватьобработку данногокасания 。 Этоможетпроизойти,например,вслучае,еслипоявилсяинтерфейсвходящегозвонкаипродолжениеобработкикасаниябудетнекорректным – пользовательуженаходитсявконтекстедругогоприложения(телефон)。 Ожидается,чтоприполученииtouches已取消 приложениеотменитвседействиякоторыемоглибытьпротевреивведен。 Дляпониманиялогикиэтоготребованиярассмотримкнопку。 Пустьпользовательнажалнанее,ноещенеподнялпалецивэтовремяпроисходитвходящийзвонок。 ЕслиобработатьtouchesCancelledаналогичноtouchesEndedивызватьобработчикнажатиякнопки,топослеокончаниязвонкаивозвратавприложение будетпроизведенокакое -тодействие,котороепользовательмогнеожидать。 […]
非官方watchOS通过教程更新主页 入门 代码杀手 选择器显示样式 p。 106 Series 4手表默认启用了触觉反馈。 我不会添加将其禁用到项目的代码,因为默认行为很棒。 但这是一个示例: 覆盖func awake(withContext context:Any?){ super.awake(withContext:context) self.crownSequencer.isHapticFeedbackEnabled = false } 有关更多详细信息,请参阅Apple的WKCrownSequencer文档。 清单样式 堆叠式 序列样式 您的第一个选择器 p。 109这是我的代码编辑版本。 我避免魔术数字。 覆盖func awake(withContext context:Any?){ super.awake(withContext:上下文) // 1 var weightItems:[WKPickerItem] = [] 为我在Constants.Weight.minOunces … Constants.Weight.maxOunces中 { // 2 让item = WKPickerItem() item.title =字符串(i) weightItems.append(item) } // 3 weightPicker.setItems(weightItems) // 4 weightPicker.setSelectedItemIndex(盎司-1) […]
非官方watchOS通过教程更新主页 探索手表 操作系统 相互作用 p。 62 Series 4 Apple Watch的数字表冠具有触觉反馈 ,可提供更直观的用户体验。 有关如何禁用它的信息,请参见第5章:选择器-选择器显示样式和第7章:表-入门。 手表展示 p。 63 Apple Watch Series 4具有两个新的显示屏尺寸:40和44 mm。 要了解有关它们的所有信息,请观看“ Designing for Apple Watch Series 4”技术讲座和/或阅读文章“支持多种屏幕尺寸”。 3系列42毫米和40毫米系列的手表尺寸相似。 要定位所有四个尺寸,请定位40/42毫米,并确保显示屏缩小至38毫米和最大44毫米。 Series 4手表的边缘呈圆形,因此watchOS 5提供了内容安全区域插图和最小的布局边距 ,类似于iPhone X系列的安全区域 。 使用“ 固定到屏幕边缘”属性可以使用全屏。 Watch OS现在可以使用可缩放的PDF资源。 2x PDF资源将在以下4种屏幕尺寸中缩放: 介绍WatchKit 这是什么 那不是什么 WatchKit应用 由于现在有4种不同尺寸的手表可供选择,因此Apple彻底改造了watchOS图标集 。 这是新清单。 请注意,所有图标都是正方形 ,因此40px x 40px我将简单地写为40px 。 对于Sketch和Photoshop模板,请查看Apple设计资源。 苹果手表通知中心 […]
创建者: Jared Sinclair 考虑将您的iOS或macOS应用程序从一堆NSLog或print语句迁移到新的(ish)统一日志记录系统? 继续阅读一些可能会让您感到惊讶的事实和花絮,以及一些有关如何充分利用过渡的建议。 如果不确定为什么要使用统一日志记录,则可以快速了解一些主要优点: 这是新标准。 统一日志记录系统是多年来在Apple平台上登录的最大变化。 它具有苹果公司打算作为未来日志记录方式的所有迹象。 在不牺牲日志覆盖率的情况下提高应用程序的性能。 新的日志记录系统从头开始设计,以限制日志记录传统上对生产代码产生的观察者影响。 您现在可以同时使用两种方式:全面的日志覆盖和出色的性能。 升级调试工作流程。 可以使用自定义的子系统和类别来“标记”使用新API记录的消息,这些子系统和类别使Console.app能够使用富有表现力的搜索过滤器来显示或隐藏消息。 在调试跨越多个模块或过程的复杂问题时,这可以节省大量时间。 我可以继续讲其他好处,但是随着我们探索统一日志记录及其替代之间的区别,这些好处将变得显而易见。 统一日志记录与传统日志记录技术不同的四种方法 以下不是统一日志的新增功能或不同功能的详尽列表,而是一些关键差异,这些差异可能会对您从旧式日志记录功能迁移的方式产生巨大影响。 1:OSLog不是功能。 这是一种数据类型。 有时您会听到人们通俗地将统一日志称为“ oh-ess-log”,这可能会使您OSLog对OSLog函数的Foundation文档的OSLog 。 没有一个。 NSLog的真正类似物是中定义的各种函数,例如os_log ,其中大多数都将os_log_t (也称为通过Swift覆盖的OSLog )作为参数。 OSLog类型用于关联相关消息,以便它们可以参与Console.app的搜索和过滤器功能。 2:Console.app是强制性的。[¹] 统一日志记录不会以纯文本或人类可读文件格式序列化日志消息。 相反,所有消息均以不透明的数据格式写入磁盘,只能通过在Console.app中打开日志归档文件(请参阅下面的获取方法)来读取。 Console.app可以解压缩存档的消息,以易于搜索和过滤的方式显示它们。 数据格式的不透明性与您可能熟悉的日志记录系统有很大的不同。 它是由Apple采取的,旨在限制传统上记录对性能和磁盘空间的有害影响。 3:在Swift中,您只能将StaticString作为日志消息传递。 以下Swift代码将无法编译: 这是因为Swift编译器将原本不受限制的字符串文字的隐式类型解析为String ,但是os_log函数需要一个StaticString 。 您可以通过为变量指定显式类型来解决此问题: 或通过消除变量: 静态字符串字符串也可以是C样式的格式字符串: 请注意,在记录消息时不能使用Swift的愉快的字符串插值: 将您的Swift代码从NSLog迁移到统一日志记录时,这可能是您遇到的最重大的偏离。 在用os_log调用替换每个NSLog或print调用的方式时,请做好git工作目录中的准备工作, os_log 。 可以记录String ,但只能作为静态格式字符串的参数来记录: 这种解决方法会带来很大的麻烦,我们将在接下来看到。 4:除非有例外,否则格式参数将为。 默认情况下,当您将String记录为格式参数时: 该消息将在Console.app中呈现为: 处理消息MyApp什么是? […]
函数是执行特定任务的独立代码块。 下方是一个简单的函数,目前实际上不执行任何操作。 func emptyFunction(){ //您的代码应该放在这里 } func关键字用于定义函数,而emptyFunction是赋予函数的名称。 创建函数时,必须随时使用func ,并且函数名称会根据函数的作用而有所不同。 可以在我的代码中调用上面的函数,如下所示 emptyFunction() 有时我们需要将参数传递给函数,我们可以将参数传递给如下函数 func functionWithParameter(parameterOne:Int){ print(“这是我的参数:\(参数)”) } paramterOne是传递到函数中的参数,而Int表示参数的数据类型。 data type (Int)是一种在我们调用函数含义时必须遵守的契约,参数必须是Int.类型Int. 我们需要包括在调用如下函数时传递的参数 functionWithParameter(parameterOne:32) 通过用逗号分隔参数,我们可以在一个函数中使用多个参数 //声明函数 functionWithParameters(parameterOne:Int,parameterTwo:String){ } //调用函数 functionWithParameters(parameterOne:32,parameterTwo:“ Hello”) return type用于表示函数应返回的值的数据类型。 就像参数类型一样,Xcode将强制我们确保该函数返回其指定的类型。 func functionWithReturnType()->字符串{ 返回“我必须返回一个字符串” } 快速有许多数据类型,包括整数,布尔值,字符串,浮点数,双精度。 -> String表示该函数必须返回String类型。 任何不返回值的函数都有一个名为Void的特殊返回类型。 当我们不指定函数返回类型时,我们只是简单地告诉swift,该返回类型为void,因此我们的函数不得返回任何内容。 //声明Voidfunc noReturnType()的不同方法{ // swift会自动将此函数设为void //因此,我们不能返回任何东西 } 函数returnWithReturnType()->无效{ //与上面相同,但是我们自己声明了void } 函数returnWithReturnType()->(){ //这是宣告void的另一种方式 } 有时我们需要函数返回多个值,我们可以借助如下所示的元组迅速完成此操作 //声明函数 […]