我知道使用情节提要构建单个视图应用程序很容易。 Xcode实际上为您设置了所有内容。 我将让您用谷歌搜索为什么停止使用情节提要的原因。 我将向您展示如何设置一个以匹配Apple为您创建的内容。 创建项目后,进入Project-> Targets-> Deployment Info,从主界面中删除“ Main”一词。 接下来,删除Main.storyboard。 现在,您需要添加代码来绘制窗口,使其成为关键且可见,并在AppDelegate.swift中将ViewController.swift设置为根视图控制器以创建视图。 这是代码: 窗口= UIWindow(框架:UIScreen.main.bounds) 窗口?.makeKeyAndVisible() 窗口?.rootViewController = ViewController() 随时阅读有关UIWindow的Apple文档,以了解代码中使用的方法。 现在,转到ViewController.swift并将背景更改为白色,使其与Apple在情节提要中提供的内容匹配。 view.backgroundColor = .white 至此,您已经完成。 如果现在运行该应用程序,则模拟器中将出现白屏,这与Apple为您提供的情节提要完全相同。 但是您问,如何添加按钮,文本字段,图像视图? 所有以编程方式。 我不会在这篇文章中介绍所有内容,但是下面是一小段代码,向您展示如何在ViewController.swift中添加文本字段。 //在ViewController类中,在任何方法之外 let textField = UITextField(框架:CGRect(x:0,y:10,宽度:200,高度:40)) //在ViewDidLoad()方法中 textField.text =“世界你好” view.addSubview(textField) 这就是它的样子。 而已。 当然,还有更多的东西:使用布局锚来设置约束; 更改字体类型,字体大小和颜色; 添加目标。 清单继续。 但这是一个好的开始。
嘿! 我想分享我在玩BEMCheckBox时学到的东西。 https://github.com/Boris-Em/BEMCheckBox 我们将以“ 风味”部分为例。 假设我只能选择一种口味。 我将必须将所选调味料的属性设置为true ,而其余复选框的属性设置为false 。 1.为复选框创建出口。 @IBOutlet弱var vanillaFlavourCheckbox:BEMCheckBox! @IBOutlet弱var ChocolateFlavourCheckbox:BEMCheckBox @IBOutlet弱var StrawberryFlavourCheckbox:BEMCheckBox! 2.将复选框存储在数组中。 var flavourCheckBoxes:[BEMCheckBox]? 覆盖func viewDidLoad(){ super.viewDidLoad() flavourCheckBoxes = [vanillaFlavourCheckbox,chocolateflavorCheckbox,strawberryFlavourCheckbox] } 3.将标签添加到每个复选框。 0、1、2。 标签是我们将用来识别已选中哪个复选框的标签。 4.制作您的 ViewController 符合 BEMCheckBoxDelegate ,并添加 didTap 函数。 ViewController类:UIViewController,BEMCheckBoxDelegate { … func didTap(_ checkBox:BEMCheckBox){ //在这里做事 } … } 我们将使用模式匹配和where关键字。 让我们先编写代码,我会解释! 5.填写 didTap 。 func didTap(_ checkBox:BEMCheckBox){ // […]
深入了解.map和.flatMap运算符 自从我开始使用Swift进行编程以来,我不禁在对数组执行各种操作时使用map , reduce , filter等函数。 关于它们的事情是如此令人愉快,以至于我永远不会错过将我通常的数组处理例程变成这些漂亮的函数运算符链的机会。 但是,如果我告诉您可以将这一概念的使用范围扩展到集合类型之外呢? 对于您来说,这可能不是什么大新闻,但您可以将map运算符与Optional类型一起使用。 没有什么比老的“ Hello world”更好地说明编码问题了。 这是一个接受字符串并以“ Hello”为前缀的函数: map用于将可选值转换为另一个值(可能也是不同类型)。 如果可选值中有一个值,那么它将遍历整个转换链。 如果不是,它将继续返回nil 。 简单。 map用于将一个可选值转换为另一个可选值。 nil的行为不会改变,但是对于非nil值,其他所有转换都会增加一层嵌套,例如,您将从.some(T)转到.some(.some(U)) ,然后.some(.some(.some(V)))等。 就像前面的示例一样, flatMap用于将值转换为另一个可选值。 但是,每个新层都被“展平”到当前级别,因此最后只剩下一个Optional对象。 类似于保龄球从车道上掉下来并不断滚滚落下,一旦该值变为nil所有后续转换都将被忽略,并且一直保持nil直到链结束。 希望这可以使您更好地了解这些功能的行为方式以及它们为您带来的好处。 您可能还会注意到,此概念经常针对各种数据类型实现。 例如,一种非常流行的Result类型,广泛用作来自网络请求的值和错误的容器。 许多实现(例如这种实现)也支持map和flatMap功能。 但是,等等,还有更多。 再次查看图片,特别是flatMap部分。 这种行为会让您想起某些事情吗? 执行会沿着可选值的链进行下去,直到成功完成或达到nil为止。 如果您考虑一下,“可选链接”的工作方式完全相同。 因此,必须有一种方法可以仅使用map和flatMap运算符提出我们自己的Optional Chaining实现。 假设我们不使用转换函数,而是要访问某些属性。 从Swift版本4开始,我们可以通过传递属性名称作为函数参数来使用KeyPath语法来访问属性。 然后,我们将使用flatMap读取可选属性并map以访问非可选属性。 为了模仿原始语法,我们将编写一个扩展名并使用最喜欢的某个运算符,即~> 。 扩展名如下所示: 借助方法重写的强大功能,我们在处理普通变量和可选变量时都可以使用相同的方法签名,这将导致语法均匀,因此使用这些运算符的人将不必知道底层的方法。 试试看! 此新运算符可以用作内置链接语法的替代方法。 像这样: 几乎没有区别,您可以互换使用它们! 如您所见,“可选链接”并不是什么魔术,而仅仅是一种语法糖,它是一种机制的糖,您可以使用高阶函数的功能自行实现该机制。 现在,您知道了如何利用map和flatMap来编写更多声明性代码,并且已经准备好处理RxSwift之类的功能范例。 不要忘记Swift是开源的! 如果您想了解更多信息,可以自己研究Optional类型的源代码。 编码愉快!
Optionals是一个后缀运算符,可以附加到任何数据类型。 可选项目以问号( ? )表示。 我们使用可选参数来指示变量所分配给的数据类型可以不包含任何值。 我们使用关键字( nil )分配一个没有值的可选内容。 只有声明为可选变量的变量才能分配nil值。 我们在某些情况下声明了可选变量,在这种情况下我们不知道输入源是否包含数据。 可选选项使程序更安全地进行编码。 例如,声明为( Int? )的变量; 告诉系统该变量可能没有任何值。 我们可以测试变量是否有值,如果有值,可以从变量中解包值。 用于指示或声明可选选项的语法如下: ? 例如,要声明一个可选变量,我们执行以下操作: var someOptional1:Int? var someOptional2:String? var someOptional3:Double? var someOptional4:Bool?someOptional1 someOptional2 someOptional3 someOptional4 请注意,在声明可选变量时,我们不需要初始化变量,因为可选变量数据类型变量会自动初始化为无值或nil。 但是, 自动初始化仅适用于变量,不适用于常量。 我们可以使用值设置可选选项,如果程序需要设置为nil,则将它们重置为nil。 例: //从先前的代码继续 someOptional1 = 766 someOptional3 = 7123.98 someOptional4 = falsesomeOptional1 =无 someOptional4 = nilsomeOptional1 someOptional2 someOptional3 someOptional4 请注意,在Objective C中找不到可选参数。尽管我们可以在Objective-C中将对象设置为nil,但在Objective-C中,nil指向空指针,而在Swift中,我们可以将任何数据类型设置为可选参数。 我们还可以同时声明和分配可选内容。 […]
我在说的api调用看起来像这样: 在这里,我们正在Almofire类上调用一个称为request的方法。 接下来是一个称为validate(statusCode:)方法,然后是另一个名为validate(contentType:) 。 最后,我们可以看到一个名为responseData的方法,该方法带有一个trailing closure ,该trailing closure返回api调用的输出。 它是如何工作的?? 好吧,逻辑很简单。 使函数可链接非常容易,并且可以允许我们使用几乎类似于DSL的语法进行编写。 我们将添加一个执行某些操作的新函数,然后返回 self 。 就这么简单。 让我们更清楚一点。 我们通常有一个init方法来初始化类的对象。 我们可以有多个designated convenience初始化程序,以使我们的工作更加轻松。 我们可以使用自定义参数来初始化类对象。 考虑一个叫做Celcius的类。 class Celsius {var temperatureInCelsius:Doubleinit(fromFahrenheit华氏度:Double){temperatureInCelsius =(fahrenheit — 32.0)/ 1.8} init(fromKelvin kelvin:Double){temperatureInCelsius = kelvin — 273.15} func printTemperature(){print(“温度为( temperatureInCelsius)”)}} 我们有两种初始化方法,一种以kelvin接受温度,另一种以fahrenheit接受温度。 下面的语法创建一个Celcius类的对象,并使用该对象,我们可以调用一个实例方法。 摄氏(来自开尔文:400).printTemperature() //打印温度为126.85 如果您知道上面的代码是如何工作的,那么很容易理解本文开头提到的almofire方法链接。 链接方法示例: 让我们创建一个APICaller类。 一个api调用通常有一个url ,一个http method和parameters 。 如果我们使用上述类进行API调用,它将看起来像这样。 let params = [“ key1”:“ […]
当您的朋友为您做这些事时,您会想到“在哪儿学到的?” 这篇文章是为Meetup组OC Hack Nights的研讨会而创建的。 如果您在Irvine地区附近,并且想与好人一起做一些有趣的事情,请加入我们! 这是后面的Github链接:https://github.com/huyanhh/DebuggingDemo 调试。 好玩的东西。 这是没人想做的事,但却是必不可少的罪恶。 “ 如果调试是消除软件错误的过程,那么编程必须是将其引入的过程。 ” — Edsger Dijkstra 幸运的是,我们拥有使生活更轻松的工具。 让我们直接深入。 使用的工具和语言:Xcode 8,Swift 3 穴居人调试 有趣的名字,但是它的名字很准确。 命名是在Objective-C时代的某个地方发明的。 这种调试类型是快速,易于使用的调试类型。 除了输入代码外,无需进行任何设置。 我们可以选择打印报表: print 经典的打印功能,您可以打印出大多数带有完整描述的对象,而无需以任何特定方式对其进行格式化: print(self.view)//产生 <UIView:0x7f896850a810; 框架=(83 96; 203 138); 自动调整大小= RM + BM; 层= > NSLog 作为Objective-C函数,在Swift中也可以使用。 主要区别在于您将使用格式说明符来指定要在运行时传递的参数类型。 它类似于Java中的System.out.format() 。 在正常情况下,您可能希望使用print ,但是假设我需要观察语句上打印了哪个线程,然后可以在两个不同的函数上使用NSLog进行检查。 容易吧? NSLog(“某些视图:%@”,self.view) //收益 //格式:日期时间process_name [process_id:thread_id] 2017-03-28 10:46:11.222 DebuggingDemoFinished […]
我们花了三天的时间,一直下降到两位数。 现在,无需再理会的错误了。 我们必须使用助手视图来并排修复剩余的错误。 大多数错误被证明是对类vars的可选类型的错误猜测。 Converter始终选择隐式展开的变量,而不是可选变量。 否则它将尝试猜测局部变量类型错误。 (您不需要在大多数时候声明变量类型,因为Swift可以推断出它们)。 只是因为我渴望看到该应用程序已构建,所以我选择了一条捷径。 我使用强制展开和强制强制转换只是为了消除构建错误。 我几乎不知道,以后我将为此付出高昂的代价。 一堆var允许转换后(转换器将所有变量都定义为var),我们有了一个内置的应用! 别这么大肆宣传,我们才刚刚开始。 是的,我们的应用正在构建中,但是没有返回任何数据并且在启动时崩溃。 我们花了接下来的100个小时进行调试,以查找所有 空错误 if not null检查,则错误, 以及许多可选性修复。 之后,我们的应用程序正在初始化。 那是“差不多”的铸造,还有另一个力解开错误。 有样式指南的原因。 它们可以帮助您按照设计使用的语言来使用该语言,并且可以在创建大多数错误之前将它们阻止。 当时,SwiftLint进行了营救。 您可以在Xcode上运行SwiftLint来查看所有样式指南异常,并快速对其进行修复。 我决心摆脱所有可选性错误,并尽可能与风格指南保持联系。 我甚至启用了加入规则。 修复样式不仅有助于提高可读性,而且还提高了我们对错误的信心。 我们在途中发现了其他错误。 我们摆脱了所有强制展开,强制转换,显式类型声明以及隐式展开的可选内容。 我们尽可能地if let和guard let语句成为可能。
这太容易了。 设置完项目后, 删除情节提要。 从现在开始,我将不会在演示图板上显示任何内容,也许以后我会谈论为什么,但请相信我,这是出于您自己的利益。 步骤2:将ViewController.swift设置为rootViewController 我们可以在AppDelegate.swift中轻松完成此操作。 如果单击Image Literal它将使您从放入文件夹的图像中进行选择。 因此,添加您想要的图像数量。 如果您不使用Xcode 8,或者想知道如何使用打字方式,则如下所示: 现在,我们已经在数组中包含了图像,我们可以创建一个循环遍历图像的函数,然后将其添加到scrollView中。 您不必像我一样将函数放在viewDidLoad之外,但我希望保持其干净。 这是我们的功能: 希望你不要对此感到困惑。 实际上,这很简单。 第一行说的是func setupImages(_ images: [UIImage]){ 这只是意味着我们有一个名为setUpImages的函数,它将使用UIImage数组。 现在我们有了for loop我们给循环赋予了变量i 。 i包含每个UIImage所以如果您有10张图像,它将循环10次。 很简单 我们还将imageView的图像设置为与images[i]相等。 它将遍历每个对象并设置图像。 然后,我们设置UIImageView的框架。 我们需要确保每个imageView不在同一页面上。 因此,我们将屏幕的宽度乘以i 。 这使我们的图像从不同的“页面”开始。 设置scrollView的contentView很重要,我们需要告诉我们的滚动视图需要多大。 然后,将其添加到scrollView的子视图中。 确保在viewDidLoad中添加scrollView并调用我们的函数: 就是这样,您应该可以运行它,然后在图像中滑动。 如果您有任何问题或建议,请在below以下评论。
如何使用Git子模块向Xcode项目添加框架。 介绍 在Xcode中构建iOS应用时,我们经常需要从另一个项目中添加代码。 向其他应用程序添加功能的项目通常旨在构建“框架”目标。 框架使您的项目受益于其他人的辛苦工作,因此您不必重新发明相同的轮子。 我们可以下载框架代码文件的副本并将其添加到我们自己的项目中。 但是,我们的副本将立即与原始存储库不同步。 为了继续享受别人的工作带来的好处,我们最好使用使我们的副本与原始副本保持同步的机制添加“子项目”。 添加外部存储库,子项目和框架 通常,要在Xcode中使用外部框架,您需要: 将某种同步链接添加到外部存储库并下载。 在Xcode的文件浏览器中,将外部.xcodeproj (Xcode项目)文件作为子项目添加到您自己的项目中。 将框架添加到项目的构建阶段。 实际上,这实际上比听起来简单得多。 例如,步骤2是一次拖放操作,而步骤3涉及单击两个按钮。 在本教程中,我们将详细介绍这些步骤。 如果在任何时候都让您感到困惑,那么我建议您阅读“构建像Lego这样的应用程序”教程,该教程假定您以前没有Xcode或编码知识,并逐步构建应用程序,包括添加框架(在教程中)。 8)。 管理外部存储库的选择 有多种机制可用于将子项目同步到您自己的项目中。 它们包括: Git的子模块 可可豆 迦太基 使用子模块是Git版本控制系统的固有组成部分,并且已经存在了很长时间。 这样一来,您无需安装其他任何东西即可工作,并且相对易于使用。 它已集成到主要的Git流中,因此,例如,当您提交代码时,Git会自动知道要提交子模块代码中的所有更改。 如果您为Git使用GUI,例如SourceTree,它将为您处理子模块。 我听说过,子模块中引用最多的限制是难以管理子模块之间的交叉依赖关系,其中两个子模块可能需要各自加载第三个子模块。 CocoaPods处理交叉依赖关系,并处理上述所有三个步骤。 但是,我认为在没有GUI工具的情况下进行设置需要花费更多时间,并且这阻碍了我对子模块进行更改的能力。 在本教程中,我们将使用一个子模块。 BFWControls框架 在本教程中,我们将向Xcode项目添加一个名为BFWControls的框架。 这些步骤与添加任何框架相同。 如果要添加其他框架,可以按照此处的步骤进行操作,但只需将BFWControls引用替换为所需的存储库即可。 BFWControls包含大量功能,可简化Xcode的Interface Builder中的可视化应用程序制作。 创建自己的Xcode项目 如果您已经有一个要在其中添加框架的Xcode项目,那么您都准备开始本教程。 如果您尚未准备好Xcode项目,则可以使用任何iOS模板创建一个新项目。 或者,在添加框架后,跳至在Storyboard教程中嵌入Xib以创建具有自定义视图的基本应用程序,以测试框架是否正常运行。 在本教程的其余部分中,我将使用XibSample项目中的快照。 如果您使用的是不同的Xcode项目,那么您的屏幕当然看起来会略有不同。 准备一个子模块文件夹 我们可以将子模块代码放在Xcode项目中的任何位置,但是让我们创建一个Submodules文件夹以使其明显分开。 X在Xcode中,添加一个名为Submodules的新组。 👉启动Terminal并cd到新的Submodules目录。 只需将Xcode的Submodules文件夹直接拖到“终端”窗口中,并在松开鼠标按钮的同时按住Command键即可做到这一点。 添加子模块 👉仍在终端中,键入(或复制并粘贴): git submodule add […]
快速浏览XCode 9和Swift 4的详细信息。 JSON格式的可解码和可解析的JSON格式的可转换代码。 Es bastantefácilde usar可以使用cquiquier arquitectura。 1.¿可编码和可解码吗? 可编码的无定形变换是一种外部代表性的变换。 JSON格式的转换对象。 易腐烂的,可变形的和不透明的代表。 JSON和JSON的可解释性。 2.,可编码吗? 前可编码的简单编码。 可编码和可解码的可实现的Cucando实现方式 typealias可编码=可分解和可编码 3. Objeto可编码 结构体枚举的可编码的实现类 。 Para formar un objeto可编码partiremos del siguiente JSON: [ { “ firstName”:“ Alvaro”, “ surName”:“ Royo”, “ alias”:“ FreeWorld”, “年龄”:22, “身高”:1.8 }, { “ firstName”:“ Nacho”, “ surName”:“García”, “年龄”:26, “身高”:1.84 } ] Y crearemos un […]