Tag: swift

没有情节提要,这有什么大不了的?

不,一点也不……实际上,我不想谈论使用情节提要的缺点,我只会告诉您一些不使用情节提要的缺点。 –在源代码管理上不会有大的冲突 ,尝试删除一些属性,然后告诉您的大学更改其边界,颜色等……您将看到冲突是多么令人恶心。 – 可重用性是编码UI而不是绘制UI的最好的方法。 以编程方式创建对象时,可以在需要类似UI的所有项目中的任何地方使用相同对象。 像这样的波纹管…… 现在,我可以在您的iOS项目中的任何地方使用此android单一线条样式,文本字段,它不必是电子邮件文本字段,最后,在现实生活中,您很少会遇到非定制的内容… CLEAN项目结构…看这个真实的项目示例,这是我从事的第一个示例,在我已经困惑的第五个控制器之后。 基本上,您将花费更多的时间来修复情节提要,然后编写代码… 当您使用情节提要启动项目时,它看起来还不错,但是它如何移动并变得更加复杂,导航将变得更加困难,有时我不知道我在使用哪个控制器。 从一开始,仅编写应用程序中的所有UI并不是那么简单,但是您编写的更多代码将使您有种感觉,即您将再也不会将VC拖放到情节提要中了,这就是我现在写的方式,大约四个月不使用它。

Swift 3 PickerView

文本框üzerinebasılıncaaçılanpickerview ileseçiminizikolaylıklayapabileceğinizbirörnek。 显示文本框,以显示德语。 Kodlarıbiraz incelerseniz kendinizegöreçokkolay birşekildedeğişiklikleryapabileceğinizigöreceksiniz。 Yararlıolmasıdileğiyle🙂 导入UIKit类ViewController:UIViewController,UIPickerViewDelegate,UIPickerViewDataSource,UITextFieldDelegate {@IBOutlet弱var txt_pickUpData:UITextField!var myPickerView:UIPickerView!var pickerData = [“ Yakup”,“ Swift 3”,“ Apple”,“ Macbook”,“ IPhone”, “ Xcode”]覆盖func viewDidLoad(){super.viewDidLoad()} func pickUp(_ textField:UITextField){// UIPickerViewself.myPickerView = UIPickerView(frame:CGRect(x:0,y:0,width:self.view) .frame.size.width,height:216))self.myPickerView.delegate = selfself.myPickerView.dataSource = selfself.myPickerView.backgroundColor = UIColor.whitetextField.inputView = self.myPickerView //工具栏工具栏= UIToolbar()toolBar.barStyle = .defaulttoolBar.isTranslucent = truetoolBar.tintColor = UIColor(红色:92/255,绿色:216/255,蓝色:255/255,alpha:1)toolBar.sizeToFit()//添加按钮ToolBarlet doneButton = UIBarButtonItem(title: “完成”,样式:.plain,目标:自我,操作:#selector(ViewController.doneClick))let spaceButton = U IBarButtonItem(barButtonSystemItem:.flexibleSpace,目标:无,动作:无)let […]

Swift 4的本地通知

Преждечеммыначнем,выможетескачатьначальныйпроект。 Приложениепредставляетизсебятаблицусоспискомтиповуведомлений。 Сейчасеслитапнутьпокакойлибостроке, 警报 сназваниемуведомления。 Кконцуэтоготуторилаэтодействиебудетотправлятьлокальноеуведомлениесссодержимымстроки。 Крометого,пользовательсможетвзаимодействоватьсэтимуведомлением,выбираядляэтоееилиилиили。 Преждечемвашеприложениесможетотправлятькакиелибоуведомления,пользовательдолжеодотьна。 Дляэтого,припервомзапускеприложениянеобходимовыполнитьзапроснаотправкууведомлений,длятого,чтобыпользовательмогегоодобритьилиотклонить。 AppDelegate用户指南UserNotifications import UserNotifications ВсвойствахклассасоздаемновоесвойствоnotificationCenterиприсваиваемэкземплярклассаUNUserNotificationCenterдляуправления。 .тобудетнашцентрнотификаций。 let notificationCenter = UNUserNotificationCenter.current() 使用didFinishLaunchingWithOptions options ,котораябудетсодержатьвсебеопции,доступн之前。 重要信息: badge , sound , alert和carPlay 。 let options: UNAuthorizationOptions = [.alert, .sound, .badge] Определившисьсперечнемпараметровоповещениямыможемзапроситьупользователяразреениенаотп notificationCenter.requestAuthorization(options: options) { (didAllow, error) in if !didAllow { print(“User has declined notifications”) } } Еслисейчасзапуститьприложение,томыполучимзапроснаотправкууведомлений Пользовательможетпоменятьнастройкицентрауведомленийвашегоприложениявлюбоевремя。 ВыможетеотслеживатьэтинастройкиприпомощисоответствующегогетераgetNotificationSettings。 completionтотвызовсодержит […]

MVVM-2:深度学习

在这里,我们又回到了MVVM系列的第二部分。 如果您不熟悉MVVM,则希望阅读本系列的第一个博客MVVM — 1:一般讨论,以使MVVM更加清晰。 为什么只留下一个简单的MVVM演示? 如所承诺的那样,这将是在MVVM公园中进行的详细游览,因此是一个大博客;)。 所以等我直到最后。 你会学到什么? 在实时iOS应用程序开发场景中使用MVVM。 建立复杂的UI尊重MVVM概念。 MVVM中遇到的常见问题并巧妙地解决了这些问题。 激动…… MVVM的缺点: 在探讨主要概念之前,让我们回顾一下MVVM的常见缺点: 难以在嵌套视图和复杂UI中管理视图模型及其状态。 各种MVVM组件和数据绑定之间的通信可能很痛苦。 视图和视图模型的代码可重用性很困难。 初学者的MVVM很难使用。 我们要建造什么? 我们将构建一个应用程序,该应用程序将获取您的当前位置并显示附近的自动取款机,咖啡馆,夜总会和您周围的餐馆之类的地方,因此,如果您想出去玩,这对您来说真的很容易:)。 没有比NEARBY更好的名字了。 该应用程序的外观如下: MVVM的基本经验法则: 视图模型归视图所有 , 模型归视图模型所有 。 View Model仅负责处理输入到输出以及驱动UI所需的逻辑。 视图模型不应修改UI。 该视图应仅负责UI处理。 视图不应与数据模型交互,反之亦然。 在构建我们的应用程序时,我们将尝试维护MVVM的这些基本规则。 因此,不浪费时间,让我们进入竞技场。 样例代码: 您可以下载示例代码,并在MVVM-2文件夹下打开“ Nearby”项目。 代码流: 该项目包含三个页面:主页,位置列表和位置详细信息页面。 为了便于理解,每个页面都被视为一个单独的模块。 对于此讨论,我们将分析HomePage模块。 其他模块的设计类似。 主页模块 通过分析HomePage设计,我们可以将页面中的视图分离为主页视图,分页单元格和带有集合视图的表格单元格。 此外,分页单元格具有水平滚动视图,该滚动视图具有显示位置细节的视图。 如果您考虑如何管理所有视图模型并在组件之间划分职责,您会发现MVVM使情况变得更加糟糕,特别是对于初学者而言。 可能有多种方法来构建下面的UI,但是对于我们的讨论,让我们根据下图分离视图 : 闻到腥味……。 是的,对于MVVM的初学者而言,上述隔离可能是一个错误和时间杀手。 那么,MVVM将导致哪些问题: 管理多个嵌套视图和视图模型 。 通过驱动UI的不同业务逻辑查看可重用性。 (例如,单个CollectionTableCell用于具有不同业务逻辑的多个单元。) […]

Swift 4和@objc警告

最近,我参与了一个迁移到Swift 4的项目,该项目在其代码库中混合了Swift 3和Objective-C。 因此,在接受来自Xcode 9的邀请以将项目转换/迁移到Swift 4之后,我遇到的第一件事是一个可怕的警告,说: 不建议在Swift 4模式下使用Swift 3 @objc推断。 请解决已弃用的@objc推断警告,启用“使用已弃用的Swift 3 @objc推断”日志记录来测试代码,然后通过将“ VarageSale”的“ Swift 3 @objc推断”构建设置更改为“默认”来禁用推断。目标。 @objc推论? WTF! 好的,这就是我所拥有的,正如您所知,Swift生成的代码仅对其他Swift代码可见/可用。 就像《猿人星球》电影中“猿不杀死猿”的扭曲版本一样。 因此,如果您有一个Swift类,要在Objective-C中使用哪些成员(函数,协议,变量),则需要通过使这些成员具有@objc属性来显式指示这些成员。 这是棘手的部分,在Swift 3中,编译器非常纵情,为某些类成员添加了@objc ,即使您可能不需要它。 但是在Swift 4中,在此问题上限制更大或更宽泛,因此我得到了警告(也可能是您)。 解决方案 1-使用@objc 就像我提到的,您可以使用@objc属性标记函数或属性, @objc会将标记的成员公开给Objective-C。 2-使用@ objcMembers 现在,如果要将所有类成员公开给Objective-C,则可以使用@objcMembers标记该类。 但是使用@objcMembers时要明智,因为由于需要在Swift和Objective-C之间映射的额外代码,它会使二进制文件更大。 参考文献 迁移到Swift 4 @objc推断 限制@objc推断

使用扩展来组织您的UIViewController

什么是扩展? 扩展为现有的类,结构,枚举或协议类型添加了新功能。 这包括扩展您无法访问原始源代码的类型的能力(称为追溯建模 )。 扩展与Objective-C中的类别相似。 (与Objective-C类别不同,Swift扩展没有名称。) 以正确的方式使用扩展可以极大地改善代码组织。 我将展示如何改善UIViewController类中的代码组织,并保证您将一直使用这种方法。 开始吧! UIViewController +扩展 UIViewController类可以包含许多代码,这可能导致文件大而混乱。 这就是为什么我们需要通过将代码分成单独的扩展块来正确组织代码。 您可以在文件中添加无限数量的扩展名,但我将向您展示一些使用它的示例。 注意:我在该故事的末尾添加了一个文件(由于太长而不得不将其放在此处),其中包含一个简单的代码演示文稿,以供您阅读。 类块–在此我声明变量( fileprivate和public ),出口,覆盖方法,生命周期方法( viewDidLoad() , viewWillAppear()等)以及内部方法。 私人分机–这是 首先 最常见 我在每个控制器中创建的扩展。 它包含所有需要保密的方法,动作,事件。 因此,无需在每个方法之前添加private关键字,Swift即可让您将所有内容保持在同一块内。 协议扩展 –如果您需要在控制器中实现委托方法,这是最好的方法。 假设您需要在控制器内部实现UICollectionView。 这意味着您将需要UICollectionViewDelegate,UICollectionViewDataSource和UICollectionViewDelegateFlowLayout扩展。 只需为每个协议创建一个扩展,然后添加所需的方法(请参见下面的Gist示例)。 MARK:// – 是一个简单的指令,可以帮助我们更好地组织实现代码(在Objective-C中称为#pragma标记 )。 在每个扩展名上方添加标记,说明其功能。 这样,您的文件看起来就像被分成几部分。 查看我最新的项目: App Store上的“VIP体育投注技巧和比分” 此应用程序仅在iOS设备的App Store中可用。 通过遵循我们的专业投注来增加您的利润… apple.co 阅读我在Medium上撰写的更多文章: 引入Clean Swift体系结构(VIP) 立即忘记MVC! hackernoon.com 使用Swift 4的iOS版Google Maps SDK终极指南 许多iOS应用程序都使用Google […]

Swift Generics的力量-第1部分

泛型函数,泛型类型和类型约束 当他们工作时,您爱他们,当他们不工作时,您恨他们。 😀😀 在现实生活中,每个人都知道仿制药的功效:早上起床,决定喝什么,加满杯子☕️ Swift是一种类型安全的语言。 每当使用类型时,都需要指定它们。 例如,我们需要一个可以处理多种类型的函数。 Swift已经提供了Any和AnyObject但是除非必须使用,否则最好不要使用它们。 使用Any和AnyObject将使我们的代码易碎,因为在编译期间我们将无法捕获类型不匹配的情况。 泛型是我们需求的解决方案。 通用代码允许您编写可重用的函数和数据类型,这些函数和数据类型可与任何与您定义的约束匹配的类型一起使用,同时提供编译时类型安全性。 它使您可以编写避免重复的代码,并以清晰抽象的方式表达其意图。 例如,诸如Array, Set and Dictionary类型的类型在该元素上是通用的。 假设我们必须打印整数和字符串数组。 我可以创建2个函数来完成这项工作。 让intArray = [1,2,3,4] 让stringArray = [a,b,c,d] func printInts(array:[Int]){ print(intArray.map {$ 0}) } func printStrings(array:[String]){ 打印(stringArray.map {$ 0}) } 现在,我必须打印浮点数数组或自定义对象的数组。 如果我们看一下上述功能,则所使用的类型只是区别。 因此,无需重复代码,我们可以编写可重用的泛型函数。 泛型函数可以使用由占位符类型T标识的任何类型。占位符类型名称并没有说明T必须是什么,但是它确实说两个array必须是T类型,无论T代表什么。 每次调用print(_:)函数时,都会确定要代替T使用的实际类型。 func print (array:[T]){ 打印(array.map {$ 0}) } 上例中的占位符类型T是类型参数。 通过在尖括号内用逗号分隔多个类型参数名称,可以提供多个类型参数。 如果我们看一下Array 和Dictionary ,它们有一个命名的类型参数,即Element&Key,Value,它说明类型参数与它所使用的泛型类型或函数之间的关系。 注意:始终为类型参数提供大写的驼峰名称(例如T和TypeParameter ),以表明它们是类型的占位符,而不是值。 […]

JSON编码和解码– Swift 4

Swift 4中JSON编码和解码的简短详细介绍 Swift 4为我们提供了一种新的且更轻松的JSON处理方式。 假设我们创建了一个使用用户个人资料的应用程序。 在.get请求之后,我们收到了一个人。 让我们创建它的结构: 现在,我们可以创建Struct的实例并打印其数据,以确保它是我们的正确实例: 如果我们需要在Swift 4中将我们的person实例表示为Data ,则可以在一行中完成: 想象一下,您必须以JSON表示形式在服务器上发送此实例,如果首先拥有实例,则必须将其转换为Data类型,然后可以创建JSON: 如果您收到的人是JSON,并且需要先将其转换为struct实例,则必须先将其转换为Data ,然后再将其转换为struct : 上面的代码看起来不太易读,但我想向您展示确切的步骤流程,您可以在上面的要点中轻松看到它。

Swift数据结构:堆栈

堆栈是一个简单的数据结构,可让您创建项目的线性“堆栈”(因此得名)。 它是一种LIFO(“后进先出”)数据结构,这意味着添加到堆栈中的最后一个项目是可以删除的第一个项目。 它有一些非常实用的用例,如果您今天在计算机上做过任何事情,那么您已经与Stack进行了交互。 您将了解当前在何处使用Stack以及如何使用它。 对于您的视觉学习者,这是一个图表。 堆栈显示有6个项目。 如您所见,我为每个项目赋予了绿色索引。 尽管在与Stack本身进行交互时并不会真正使用它,但它使我们能够依赖于已内置的数据类型Array来帮助我们组织Stack。 堆栈中的值没有按照任何特定的方式进行组织,除了以下事实:添加新项目时,所有当前值都向下移动一个索引,然后将新的索引添加到堆栈的顶部,就像这样做一样与一叠饭菜。 堆栈具有3个可以与之交互的函数。 我们将在下面简要讨论每个对象及其作用: 函数1:peek() 我们的第一个函数称为peek() ,它使您可以做到这一点–窥视堆栈中最顶层的元素。 它将返回该项目在顶部以供使用或仅供参考。 它不会改变堆栈中的数据。 函数2:pop() 顾名思义, pop()从堆栈中返回顶层项目,然后将其删除。 如果要删除最上面的项目并允许撤消该操作,此功能特别有用。 由于返回并删除了最上面的项目,请设想我们有一个应用程序,可让您输入要完成的任务。 提交后,它将位于堆栈的顶部。 如果您犯了一个错误或输入了错误的内容,则可以通过调用pop()并继续进行操作来删除它,也可以修改刚刚输入的内容,因为会返回该值。 您可以使用返回的文本填充文本字段,对其进行修改,然后重新提交到堆栈。 函数3:push() 函数push()将允许我们向堆栈中添加值。 就那么简单。 由于新的值已添加到堆栈的顶部,因此它会更改堆栈中的值。 现在,您知道堆栈是什么以及它如何工作(理论上),让我们继续。 聊够了,让我们动手吧。 💪打开Xcode并创建一个新的Playground。 删除所有样板代码并import Foundation 。 然后,在该行下面创建Stack结构,并添加一个私有变量数组,称为String类型的items 。 将其值设置为空数组:

Swift 4 Introduction系列1.4 — Swift数据类型转换

我们无法对具有不同数据类型的变量执行计算。 例如,我们不能添加带有整数(Int)变量的浮点数(Double)。 为了能够执行这样的计算,我们必须将整数转换为浮点数。 同样,我们不能使用UInt16变量添加属于数据类型Int8的变量。 对于数据类型之间的转换,语法如下: 让 = () 要么 var = () 要么 = () 数据类型转换的基本规则是: 要转换的数据类型可接受要转换的数据 。 因此,我们必须知道数据类型限制,以便我们能够正确执行转换。 要在位大小数据之间转换,我们需要使用以上语法。 例: 设numberA:UInt8 = 87 让numberB:Int16 = 43 设numberC = 23个let numberD = Int16(12)let numberE = Int32(numberA) var numberF = UInt16(numberB) 令numberG = UInt64(numberC)numberF = UInt16(numberD) 如上面的示例所示,我们可以在转换括号中包含数字文字,如NumberD所示。 要重新分配变量,我们需要将转换器的数据类型与等式左侧的变量匹配,如最后一条语句中的numberF所示。 对于声明,请注意,变量将采用转换器指定的任何数据类型。 我们还可以先声明常量或变量,然后再执行赋值。 请注意,转换器必须与声明的变量或常量具有相同的数据类型。 例: 设numberI:UInt64numberI = UInt64(numberA)var numberJ:Int16numberJ […]