消息传递应用程序中的一个常见主题是使消息气泡带有尾巴,这比将一堆块彼此叠放更好,并且这是区分谁发送了特定消息的简便方法。 尽管在您现在的iOS开发经验中,您可能会想知道如何创建这些自定义视图,所以在这篇文章中,我将向您展示如何制作自己的视图! 注意:对于本教程,我已经准备了一个在Github上可用的项目,该项目具有动态调整UITableViewCell设置的大小。 这是使用Xcode 8.3.3在Swift 3中编写的。 贝济耶救援之路 创建一个方形的消息单元并不难,即使是圆角的消息单元也不错,但是您必须改变通常创建单元的方式,以便在消息底部添加一条尾巴。 在下面,我将指导您完成一些步骤,不仅在消息单元下方绘制一条尾巴,还根据发送消息的人将其向左或向右绘制,类似于iMessage。 为了获得最终结果,我们需要使用UIBezierPath绘制消息气泡的形状,然后用所需的颜色填充它。 乍一看似乎令人望而生畏,但想起来就像在纸上画一个正方形一样。 您从给定点开始,思考(0,0),然后开始将第一条线绘制到下一个点(1,0)。 再过三边,您又回到起点,准备关闭形状并填充它。现在,我们只需要在代码中执行相同的操作即可! 绘制邮件正文 跳至MessageBubbleView类,让我们开始在draw(_ rect)编写代码。 (删除调用super.drawRect因为我们将提供自己的绘图代码。)现在,我们可以使用以下代码开始路径: 让bezierPath = UIBezierPath() bezierPath.move(收件人:CGPoint(x:rect.minX,y:rect.minY)) move视为拿起铅笔并将其放置在给定点的代码。 这将是我们信息泡沫的起点。 现在我们要画顶线。 bezierPath.addLine(至:CGPoint(x:rect.maxX,y:rect.minY)) 这将在rect的最右边绘制一条线,即maxX 。 现在,我们可以遵循相同的逻辑来绘制其他三个边缘。 bezierPath.addLine(至:CGPoint(x:rect.maxX,y:rect.maxY-10.0)) bezierPath.addLine(至:CGPoint(x:rect.minX,y:rect.maxY-10.0)) bezierPath.addLine(至:CGPoint(x:rect.minX,y:rect.minY)) 现在您可能想知道为什么我没有一直画线一直到rect或maxY的底部边缘。 这是因为我为绘制尾巴留了10.0点的空间。 我鼓励调整这些值,并查看您自己的代码中的不同结果! 画尾巴 现在添加尾巴。 我们将在这里再次使用move功能。 就像您从rect的左上边缘(我们刚刚结束最后一行的地方)拿起铅笔并将其移动到尾巴的起点一样。 在此示例中,我将绘制一条指向右下方的尾巴,然后绘制一条平坦的边缘,该边缘再次向上并与我们的邮件正文相遇。 bezierPath.move(至:CGPoint(x:rect.maxX-25.0,y:rect.maxY-10.0)) bezierPath.addLine(至:CGPoint(x:rect.maxX-10.0,y:rect.maxY)) bezierPath.addLine(至:CGPoint(x:rect.maxX-10.0,y:rect.maxY-10.0)) 我们有自己的形状! 但是,如果您运行该代码,则会发现看不到它。 这是因为我们需要关闭路径并填写。 UIColor.lightGray.setFill() bezierPath.fill() bezierPath.close() 大! 我们将路径封闭并用浅灰色填充。 现在,我们的draw方法应如下所示: 覆盖func draw(_ rect:CGRect){ 让bezierPath […]
结果:『Learn to Code2』 参数 ,放置在特定位置→双峰 最后,我完成了Parameters区域 。 我花了大约三天的时间。 这段代码是我对“ 参数”区域中最后一项任务的解决方案。 让totalGems = randomNumberOfGems var gemCounter = 0 让专家= Expert() 让character = Character() func collectJump(){ 如果character.isOnGem { character.collectGem() gemCounter = gemCounter + 1 } character.jump() } 而gemCounter!= totalGems { world.place(字符,面向:北,at列:5,行:0) 因为我在1…7 { collectJump() } world.place(字符,面向:北,at列:4,行:0) 因为我在1…7 { collectJump() } world.place(字符,面向:北,at列:3,行:0) 因为我在1…7 { collectJump() } } 希望这个周末完成《学习密码》。
在上一篇文章中,我指出您的视图模型应尽可能精简。 这意味着您的视图模型不应执行数据访问或联网任务。 很少有读者指出,使用MVVM模式已久的Microsoft提倡通过视图模型调用网络和数据访问层的概念。 在本文中,我想采用Microsoft的方法,并在视图模型实现中移动网络代码。 我已经将ArticleListViewModel的定义更新为以下内容: ArticleListViewModel现在是一个类,并且需要初始化Webservice的实例。 因为现在在上一篇文章中使用过初始化器,所以现在忽略将其作为参数的初始化器。 ArticleListViewModel包含一个get函数,该函数负责将填充的视图模型返回给调用者。 而不是返回ArticleViewModel对象的列表,而是返回一个填充所有子对象的单个ArticleListViewModel对象。 现在,在视图控制器内部,您可以调用视图模型的get方法,如下所示: 调用域对象并将其转换为相应的视图模型对象的复杂性从视图控制器转移到视图模型实现。 如果您还记得我最初对视图模型的定义,则视图模型负责将数据提供给视图。 这种新方法当然可以做到这一点,但要以使视图模型复杂化为代价。 没有正确或错误的方法。 MVVM具有不同的形状,形式和实现。 在进行项目时,请采用最适合您需求的方法。
曾经遇到您找不到或需要的一切的情况吗? 因为互联网应该可以解决所有问题,所以您会感到沮丧,因为过量的互联网应该可以解决所有问题,但是当涉及到您时,它却没有向您展示您所需要的东西。 好吧,不用担心。 我来营救…。 哈哈 我想与您分享如何进行网络调用,并为那些仍在寻找编程方式的开发人员在您的视图上显示结果。 我将尝试给出最简单的解释和简单的示例,以免让您费心尝试准确地了解代码在做什么。 这篇文章假定您具备使用Xcode使用单个视图应用程序创建应用程序以及将插座链接到视图控制器的知识。 让我们潜入。 我将使用openweather api检索https://openweathermap.org/current的天气数据。 为此,您需要使用提供的链接进行注册以获取自己的唯一api ID。 请注意 ,本文不涉及获取唯一的api ID,但该说明在网站上非常简单。 下面是来自openweather api的json示例。 提供的json仅用于演示目的,因此不应包含在项目中。 在情节提要中,在视图中添加搜索栏和4个标签 ,将以下代码添加到视图控制器中,最后链接您的商店。 注意:用于api的温度单位是开尔文(Kelvins),往返于开尔文(Kelvins)的转换不属于本帖子的一部分。 在ViewController中,我们更新主队列中的UI,以便在从服务器检索数据时不会阻塞UI。 运行该应用程序,在搜索栏中输入有效位置,然后单击Enter。 您应该在搜索栏下方看到天气详细信息。 pp! 就是这样,现在可以快速轻松地进行网络请求了。 没有更多的汗水。 祝你好运&编码愉快!!!!!!!!
单一责任原则(SRP)规定,每个软件模块或类都应该有一个且只有一个更改理由。 除佛陀本人外,任何人都不承担透露神秘秘密的责任。 。 。 将因相同原因而发生变化的事物聚集在一起。 分开那些由于不同原因而改变的事物。 鲍勃·马丁 难以理解,因此难以维护。 重用困难。 由于职责在同一个类别中紧密联系在一起,因此很难在不损害其他职责的情况下更改其中一项职责(刚性),并且最终可能破坏软件的其他部分(脆弱性)。 高耦合,即该类具有过多的依赖性,因此,由于其他类的更改(同样是脆弱性),因此更容易发生更改。 让我们考虑一些可能需要分开的职责: HTTP API调用 -如果需要修改标头或基本URL,则只能将其修改为HTTPClient 。 无需为此其他文件做任何更改。 创建视图状态-创建视图状态应该由工厂或转换器负责。 验证 — 所有验证逻辑都应封装到单独的Validation类中,以便将来只有一个人负责修改验证逻辑或添加新行为。 坚持不懈 通知 错误处理 记录中 格式化 解析中 制图 导航 商业逻辑 创建视图 https://blog.cleancoder.com/uncle-bob/2014/05/08/SingleReponsibilityPrinciple.html https://www.scaledrone.com/blog/solid-principles-for-becoming-a-better-ios-swift-developer/ 单一责任原则@清洁代码联盟聚会,来自Eyal Golan 感谢您阅读文章。 您可以在以下位置找到我: Linkedin: Aaina Jain 推特: __aainajain
面向对象编程自80年代中期开始出现,我们大多数人每天都在使用它。 它使我们能够在程序中模拟现实世界的情况。 就像您有一家大公司的汽车管理应用程序一样。 一辆汽车将以“ 汽车”类别表示,您将为池中的每辆汽车创建对象。 通过抽象,您可以轻松地对更复杂的事物建模。 也许在典型的汽车旁边,您还有卡车或摩托车。 它们都具有马达,但并非都具有门或其他特征。 如您所见,这个概念使编程变得容易得多,这就是我们大多数人使用面向对象的编程语言的原因。 Swift也是面向对象的,但也有一些缺点。 面向对象设计的阴暗面 复杂 摩托车是双向的 , 双向的是机动车 , 机动车是可运输的 。 在大型应用程序中,继承树可以快速增长并变得非常复杂。 项目中的新程序员可能需要一些时间才能解决。 这是个大问题。 我们应该始终尝试降低复杂性并使其易于实现新功能。 并发 您可能希望使用线程来提高软件性能。 但是,处理数据时会遇到困难。 类在所有线程之间具有“共享状态”:类的数据位于堆内存中。 虽然每个线程都有自己的堆栈,但堆是共享的。 当多个线程尝试操纵对象的数据时,事情变得非常困难。 最后,您将创建一个互斥锁,这会导致性能高昂且容易出错(死锁)。 超类的实现 想象一下,您想实现一辆电动踏板车。 电动踏板车是MotorVehicle。 现在,MotorVehicle迫使您实现方法“ openDoors()”和“ closeAllDoors()” 。 实施MotorVehicle类的人没有想到某天某人想要实施电动踏板车的情况。 我已经看过很多次了,尤其是在大型复杂项目中。 您可能最终以空的正文和愚蠢的注释来实现这些方法。 这是不好的 Swift中没有抽象方法 在Java中,我可以使用抽象函数声明抽象类。 您不能创建抽象类的对象,但是每个实现都会继承该类中定义的非抽象方法。 Swift不支持此功能。 这就是为什么我最近在生产代码中遇到以下问题: 使用协议和值类型! 了解发生了什么:值类型与引用类型 创建类的对象时,程序将分配内存。 这项工作将由操作系统完成。 并且由于您以后可能想读取或修改数据,因此操作系统会告诉您内存中数据的存储位置。 这是您的数据位于内存中的“地址”。 该地址是一个十六进制数,例如“ 0xCAFEBABE” 。 以后,当您访问数据时,可以通过引用内存中的地址来访问数据。 […]
让闭包在函数外继续使用的@escaping @escaping是个让closure在功能外部继续使用的特殊语法。它有点难懂,但你却不能忽略,因为iOS SDK里太多功能的参数都加了… medium.com 在Swift中转义和不转义闭包 对于那些使用闭包的人,您可能会遇到@escaping或@nonescaping。 这他妈到底是什么? 至… medium.com 斯威夫特@noescape与@escaping Swift 1.2之后,就推出了@noescape语法,已修改了闭包参数。但我想或许有人跟我一样,直到换了Swift 3.0后才知道有这东西存在。事实上,在Swift … www.jianshu.com iOS架构模式 揭秘MVC,MVP,MVVM和VIPER medium.com 第一章–类,结构和枚举的必然选择·邂逅Swift你需要知道的n事件 编辑描述 gradyzhuo.gitbooks.io Swift_关键字static和class的区别 关键字静态和类别的区别在方法的功能关键字之前,加上关键字静态或类别都可以用于指定类方法。不同的是用类别关键字指定的类方法可以被子类替换,如下… www.jianshu.com 模仿Apple教学范例,写出一手好Swift 对许多刚学会App开发技术的初学者来说,他们懂得Swift语法,也熟悉各种常见功能的iOS SDK,但在实际开发App时,却常遭遇2个问题:不知如何写出容易理解和维护的程式。… www.appcoda.com.tw
今天,我将要集成一个尚不支持CocoaPods的库。 手动执行此操作很麻烦,因为您必须配置xcconfig , framework search path , assets ,而且这些步骤的文档记录也不够充分。 您可以使用自定义podspec进行此操作。 就我而言,我需要安装PinchSDK。 首先,在您的项目文件夹中声明一个PinchSDK.podspec 。 Pod :: Spec.new do | s | s.name =“ PinchSDK” s.version =“ 1.9.14” s.summary =“将捏捏信标发送给捏手samler dessuten旅馆数据。” s.homepage =“ https://bitbucket.org/fluxloop/pinch.installpackage” s.source = {:http =>“ https://bitbucket.org/fluxloop/pinch.installpackage/raw/master/iOS/PinchSDK.zip”} s.authors =’Fluxloop’ s.license = {类型:’MIT’} s.platform =:ios,’8.0′ s.requires_arc = true s.resource =’PinchSDK / Pinch.bundle’ s.vendored_frameworks =’PinchSDK / PinchLibrary.framework’ […]
奎兰芝! Masih dengan教程Pembuatan iOS App bagi pemula。 Seperti judulnya,达拉姆教程ini akan dijelaskan bagaimana membuat sebuah登录表单,dengan komponen sebagai berikut: 文本字段khusus输入jenis电子邮件地址 文本字段khusus输入jenis angka(untuk密码bertipe PIN) Button bertuliskan“登录” 表格布局 商业逻辑 登录按钮的IBAction 文本字段的IBOutlet Ngoding业务逻辑 演示! Buka Xcode,lalu buat项目iOS / Swift baru。 卢帕/贝拉Pernah膜吗? Silahkan mempelajari教程ini dulu。 挑战! Cari komponen 文本字段 dan 标签 ,自然布局dan ubah属性-nya hingga menjadi seperti ini: 贝贝拉帕(Beberapa yang harus diatur): […]
今天早些时候,我想知道在过去的几周中,哪种形容词最能唤起我们iOS团队的情感氛围,而且我认为令人振奋的事情将非常接近。 我们推出了一个新的应用程序Apple,苹果公司发布了iOS 11,我们开始在生产中使用Xcode 9,有一个令人兴奋的新iPhone即将面世,当然,这篇文章的主角是Swift 4。 这个新版本是社区在一年中提出的30项提案的结果。 这并不是像Swift 3那样的压倒性的重塑,并且没有像Swift 2那样包含很多新功能,但是确实有很多不错的添加。 这篇文章重点介绍了在迁移我们的应用程序时我们遇到的一些挑战,并希望将为计划不久的您提供一些有用的见解。 在Runtastic博客上阅读全文