Tag: uikit

iOS。 如何实现可滚动视图?

作为iOS开发人员,我们经常会遇到需要在控制器中使用可滚动视图的情况。 基本上,有几种方法可以实现此目的。 在此博客文章中,我们考虑使用代码构建UI,即不使用故事板。 首先,如果您不知道什么是滚动视图,则它是UIScrollView类的对象。 我们在开发中需要它,因为设备的框架或显示器在水平和垂直轴上都受到限制。 因此,当我们需要显示比设备框架(尺寸)大得多的内容时,滚动视图会为我们提供帮助。 UIScrollView是一个特殊的视图,其内容视图在水平和垂直轴上都比其自身大得多。 上图的用例是当我们放大图像并滚动y,x尺寸以移动它时。 但是在本教程中,我们考虑了第二个用例,当我们需要滚动视图仅水平滚动时,如下所示: 这用于显示内容,该内容仅长于设备的大小,但不宽于设备的大小。 那么代码在哪里? 我们到了: 1-我们创建UIView类的实例,将其用作滚动视图的内容视图。 因为滚动视图需要具有内容视图才能显示UI元素。 0 —我们创建UIScrollView的实例。 1-在这里,我们将滚动视图添加到控制器的视图,然后将scrollViewContentView添加到我们的scrollView 2-设置scrollView约束。 我们将其边缘设置为等于视图的边缘。 3 —设置scrollViewContentView约束。 4-我们使它的边缘等于scrollView的边缘。 然后另外使其宽度等于视图的宽度,这一行代码非常重要。 如上所述,滚动视图可以在两个维度上更大,因此通过编写此行代码,我们让scrollView认识到我们希望它更长,即仅在y维度上更大。 而已! 此外,我们可以轻松地将视图添加到我们的scrollViewContentView上,它将垂直滚动! 完整的源代码可以在这里找到! 谢谢!

iOS App中的社交服务文件浏览器

社会服务浏览器 是一个库,提供了一种简单的方法来浏览,预览和导入来自外部服务(如Dropbox,Amazon Drive,Google Drive等)的文件。我将其编写为通用代码,可以集成自定义服务,您所需要做的就是实现一些协议方法,仅此而已。 它支持自定义UI /布局,并基于UICollectionViewController,在下面您将找到默认UI的外观。 它最初是为了从外部服务导入文件而编写的,但是我认为这对于预览文件也可能有用,因此在GitHub上找到的示例中,您将找到如何与UIDocumentInteractionController一起使用它 我想尽可能地简单,因此如果您想使用Dropbox,已经有实现预览和导入功能的类。 用法仅限于几行代码: 为了能够实现自定义浏览器客户端,您所需要做的就是从SocialServiceBrowserClient协议中实现方法: 除此之外,您还必须为每个节点(文件/目录)实现SocialServiceBrowserNode协议。 @objc公共协议SocialServiceBrowerNode { var nodeId:字符串? {得到} var isDirectory:Bool {get} var nodeName:字符串{get} var path:字符串? {得到} } 将其与某些外部SDK集成的最简单方法是使用扩展。 我已经为Dropbox创建了示例客户端,并使用了SwiftyDropbox。 在下面,您可以看到使用扩展将其集成起来有多么容易。 SwiftyDropbox返回Files.Metadata节点的集合,他们为文件Files.FileMetadata和目录Files.FolderMetadata创建了子类,但出于我的目的,我为父类创建了扩展。 最后一步是处理SocialServiceBrowserClient协议的方法,这是针对Dropbox客户端完成的方法: 希望不久我们将涵盖每种常见社会服务的实施。 我建议您在此处检查示例和源代码,这些示例和源代码可在我们的GitHub存储库中找到! – 请享用。

在Interface Builder中布置动态UIScrollViews

如果您正在学习或已经使用iOS一段时间,您可能已经意识到使用UIScrollViews是构建甚至稍微复杂的UI的必要条件。 您可能还意识到,要使滚动视图及其内容与AutoLayout配合使用可能会非常痛苦。 在本文中,我将解释如何在界面生成器中布局滚动视图。 我们还将看到如何使可滚动区域动态化,以便它将可改变其大小以及所显示的内容。 我不会详细介绍滚动视图的真正含义以及它可以做什么和不能做什么。如果您想了解更多有关滚动视图的信息,请查看Apple文档或本教程。 就是说,关于滚动视图,我们必须了解一件事,它们需要某种方式来了解其内容大小。 内容大小是让滚动视图知道其水平和垂直滚动区域应多大的内容。 例如,如果将内容大小(宽度和高度)简单地设置为滚动视图的框架,则它将不会滚动任何内容……但是,如果内容高度大于scrollViews框架的高度,则它将垂直滚动。 现在您可能在想:“好吧,我明白了,滚动视图的内容大小决定了可滚动区域,但是我们如何设置此内容大小的宽度和高度?”。 好了,可以显式和隐式地设置内容大小。 明确设置此方法的一种方法是直接对内容的高度和宽度进行硬编码: scrollView.contentSize = CGSize(宽度:300,高度:900) 这种做事方式既有趣又有趣,直到您意识到这不是我们想要的一切为止! 我们希望事情是动态的。 我们不一定知道内容的高度和宽度应该是什么,毕竟,这可能取决于设备的大小,方向或滚动视图实际显示的更改内容。 由于我们计划使用界面构建器和AutoLayout,因此我们希望通过设置约束来隐式设置滚动视图。 我们将使视图控制器的整个视图成为一个垂直滚动页面(这是滚动视图的常见用例)。 首先,我们将使用一个空的视图控制器“刷新对象库”并在其上拍一个滚动视图。 因此,将UIScrollView拖到视图控制器的视图上,并将其约束设置为其超级视图的边缘。 现在我们已经设置了scrollView,我们将把UIView作为子级添加到scrollview中。 此视图是“虚拟视图”,因为它仅用于布局目的。 不过,不要上当,这是一个非常重要的虚拟视图。 该视图用于确定我们喜欢的contentSize ,并包含我们希望在scrollView中显示的所有内容。 由于此视图非常重要,因此我们将其重命名并将其称为contentView 。 另一个非常重要的步骤是将内容视图的每个边缘固定到scrollView的边缘。 这些是“ 特殊”约束,它们使滚动视图知道该视图(内容视图)将用于确定内容大小。 添加这些约束后,您仍然应该会看到自动布局错误,如果您问自己为什么,我也不会怪您。 我们将内容视图固定在顶部,底部,前边缘和后边缘……为什么我们仍然遇到问题? 记得我们说过这些是“特殊”约束吗? 好吧,是的,AutoLayout与scrollViews的工作原理略有不同。 我们所做的就是告诉scrollView我们的内容视图将用于定义其contentSize,但是我们实际上并未定义内容大小。 实际的内容大小将由内容视图的高度和宽度确定。 由于目标是使屏幕垂直滚动而不是水平滚动,因此我们首先在内容视图上设置宽度约束。 此约束的目的是完全禁用水平滚动。 我们将从内容视图到滚动视图本身设置相等的宽度约束 有了这个约束,无论滚动视图占据整个屏幕还是仅占据一部分,滚动视图都知道其内容宽度将与框架的宽度完全相同。 我们仍应具有自动布局警告,因为我们尚未设置任何定义内容高度的约束。 只是为了使此工作正常进行,而不会引起界面构建器的任何投诉,让我们为内容视图的高度定义静态值。 为此,我们将对我们的内容视图应用高度限制1000(完全任意)。 恭喜你! 如果一切操作正确,您将不会再看到有关我们布局的警告。 但是,如果您注意到滚动视图继续向下经过主视图,您可能会感到恼火。 在界面生成器中延长主视图的长度是一个好主意,以便我们可以查看和操纵滚动视图的内容。 为此,我们将选择视图控制器(而不是其视图),然后转到属性检查器。 在这里,我们应该看到“模拟指标”列表,我们需要将“大小”字段从“推断”更改为“自由格式”。 这将使我们可以调整视图的高度,请记住,这些“ 模拟 指标 ”仅是在设计和布局界面时为我们提供帮助,实际上不会影响我们的应用程序。 接下来,转到视图控制器的大小检查器,并将高度设置为更适合此场景。 […]

与UIScrollView的简短相遇

我与UIScrollView进行了简短的接触,这是我要写的,因为我想记住我在工作中的Hack Day摔倒的一两件事。 但是,内容与工作有关。 而且,在尝试提出一个引人注目的与工作无关的示例时,我学到了很多有关Swift Codable的知识 ,所以我决定写些关于它的内容。 好的好的。 很好 。 我会写两个。 对于本文,我将仅介绍滚动视图。 关于绊脚驱动的开发 这是我如何通过滚动视图迷失于杂草中的故事。 巨魔和巨型蜘蛛的故事。 好吧,像那样。 这种开发风格可以称为“绊脚驱动的开发”( SDD ),有点像“沿着已知的轨迹朝着明确的目标前进,直到进展发生。” 有问题的应用程序是为工作中的Hack Day而设计的; 我很高兴实现UI。 这个应用程式打算在iPhone上显示资料资讯提供,让您放大细节,因此我选择了iOS Master-Detail范本。 通常,我立即用UITableView替换细节视图并实现自定义单元格,但是这次我不想麻烦,无论如何,在这种情况下,总体布局基本上是固定的。 布置视图 急着,我首先使用自动布局在没有UIScrollView的情况下直接在局部视图中布置局部视图。 而且,在花了很多时间进行布局之后,我犯了一个错误,那就是将它们全部都嵌入到了Editor > Embed In > Scroll View的UIScrollView中。 一切都松散了。 到处都是红色。 绊倒,绊倒,课程,课程等,等等。 为了帮助您了解所见,我在Intertubes上寻找了引人注目的数据馈送示例,并最终选择了USGS地震馈送。 只是。 因为。 为了整理提要,我认为我可以快速给新的Swift Codable协议打转,那时候我就知道了Frickin 很棒的 Codable是什么。 但这是下一篇文章。 抓紧。 细节视图的初始布局看起来像这样,与我在Hack Day应用程序中使用的布局极为相似: 我把MKMapView扔在那儿以占用空间,以备不时之需。 但是它还不够高,无法滚动。 接下来,我使字体变大,添加了更多标签视图以将其进一步垂直扩展,添加了一些字符串格式以使内容看起来更简洁,并使用自动布局将视图连接起来。 对于标题,位置和详细信息视图,我使它们紧贴右边缘并具有零行,以用于多行换行文本。 我将视图组放在堆栈视图内地图视图的右侧,只是使布局有些复杂和令人恐惧。 我的目的不是要尽可能以最佳方式显示此数据,而只是使视图向下延伸足够远,以至于实际上需要滚动内容才能看到底部,因此: 哦。 当然,滚动是可取的。 […]

具有圆角和阴影的视图

在过去的几年中,移动和网络应用程序的总体设计模式一直持平。 借助iOS 7和Material Design,谷歌和苹果公司(紧随Windows 8的足迹,让我们在这里成为现实)宣布了崭新的设计模式。 平面UI非常棒。 它删除了看起来确实有点过时2000的时髦3D UI元素。 但是,随着iOS 11的发布,苹果似乎正在从更加突出的纯平UI转移到阴影和其他与深度相关的效果上。 它仍然是非常平坦的外观,只是带有一些用于指示用户如何与UI交互的附加信息。 上图中需要注意的一点是,单元格既有圆角,又有阴影。 为了在CALayer上圆角化,您需要执行以下操作。 扩展名CALayer { func roundCorners(半径:CGFloat){ self.cornerRadius =半径 } } 这会将拐角半径应用于图层— 仅将拐角半径应用于背景颜色和边框。 这很重要,因为如果图层中有任何 contents则需要将masksToBounds设置为true ,以使拐角半径剪切内容。 为了给CALayer添加阴影,只需要多几行代码。 扩展名CALayer { func addShadow(){ self.shadowOffset = .zero self.shadowOpacity = 0.2 self.shadowRadius = 10 self.shadowColor = UIColor.black.cgColor self.masksToBounds =假 } } 在支持视图的图层具有内容之前,在视图上同时具有阴影和圆角不是问题(范围可以从图像到其他非平凡的视图元素)。 如上所述,如果存在图层的contents ,则需要将masksToBounds设置为true才能应用圆角。 剪辑内容和显示阴影是不能同时存在的两种状态。 这是有道理的。 如果要在视图上放置阴影,则在视图上不能使用遮罩将其裁剪到边界,因为阴影会显示在视图边界之外。 要剪辑带有圆角的内容,您需要执行相反的操作。 因此,添加阴影并圆化视图的角点并不像听起来那样琐碎。 […]

如何在Xcode中使用Nibs和Coordinators代替Storyboard

Xcode中的情节提要板起初很方便,但是随着应用程序的增长,需要维护或您与团队一起工作,它们会带来很多伤害。 本文根据我的经验提供了有关如何使用nib文件构建应用程序的指导。 故事板有什么问题 与桌面应用程序相比,移动应用程序的导航功能繁重,在可视化编辑器中帮助开发人员进行设计和导航体验非常有意义。 苹果公司在2010年用Xcode 4引入了它们,并使它们成为在nib文件上创建可视用户界面的默认设置。 不幸的是,Xcode故事板存在很多问题: 添加的屏幕越多,对其进行编辑就越麻烦。 您必须不断滚动和缩放很多才能找到要编辑的屏幕 而且,如果您将情节提要板分开,那么记住每个视图控制器放在哪个情节提要板上并非易事 他们很慢。 每次打开情节提要时,它都会显示一个微调框,而Xcode经常会忘记您的上一个滚动位置 如果您在团队中工作,则不可能避免合并冲突,并且合并情节提要xml并不像合并代码那样容易 如果您的屏幕根据应用程序的状态显示不同的视图,则必须使用遏制序列,这意味着创建许多子视图控制器类,或者在彼此之上堆叠视图,这使得编辑很麻烦,因为它们在Xcode中彼此隐藏 通常情况下,导航是非常繁琐的,无法使用情节提要脚本来创建,最终您只能通过代码来完成。 然后,您将混合使用程序化和情节提要导航,这令人迷惑且令人困惑 创建和使用nib文件 自从放弃故事板以支持笔尖以来,我的开发人员的生活变得如此轻松。 幸运的是,Xcode仍然允许您使用关联的笔尖创建视图控制器子类: 这为您项目中的每个View Controller提供了两个文件,彼此相邻,并且始终易于访问: 然后可以使用默认的初始化程序实例化它(不需要标识符字符串!): 让viewController = ViewController() 应用程序启动后,您需要将根视图控制器分配给一个窗口,并告诉应用程序显示该窗口: 让窗口= UIWindow(框架:UIScreen.main.bounds) window.rootViewController = viewConroller window.makeKeyAndVisible() (如果我们像Xcode的项目模板那样在Info.plist中指定主故事板,这就是Xcode / iOS为我们方便地做的事情) 通常,您希望将根视图控制器包装在导航控制器中,以便可以推送其他视图控制器: 让navigationContoller = UINavigationController(rootViewController:viewController) window.rootViewController = navigationController 输入协调员课程 从结构上讲,笔尖非常适合协调器 (也称为流量控制器 ,请在此处观看Soroush Khanlou的精彩介绍演讲)。 其背后的想法非常简单:创建类,其唯一职责是通过管理视图控制器来控制应用程序的导航流程,从而使情节提要过时。 并且每当您在视图控制器中使用UINavigationController.pushViewController(_:animated 🙂或UIViewController.present(_:animated :)等时 ,都可以调用协调器。 协调器不仅使我们能够减少视图控制器中的代码行,而且这种模式的真正优势在于减少了视图控制器之间的依赖关系:通过segue关联的两个视图控制器不需要彼此了解再也不用了,如果我们使用依赖反转,他们甚至不需要了解协调器(即让他们通过协议与协调器进行对话)。 这对我们的体系结构来说非常好,因为它意味着更低的耦合和更好的可重用性。 补充意见 […]

来自.xib的iOS自定义UIView

在iOS App开发中,创建自定义视图是非常常见的做法。 我们经常创建自定义视图以实现可重用性,以分隔责任或分离依赖关系等。尽管在该主题上有大量的stackoverflow答案,媒体,博客等,但是要找到一个简洁而全面的创建自定义视图的示例非常困难来自.xib。 让我们从以下步骤开始: 步骤1 创建一个单视图应用程序项目 Setp 2 如下图所示添加一个.xib文件,并将其命名为“ CustomView” 第三步 就像上一步一样,添加CustomView类。 这次选择CocoaTouch文件,并在subclassof部分中选择UIView,并将其命名为“ CustomView” 步骤4 选择CustomView.xib文件,然后从Xcode的属性检查器中将CustomView.xib的文件所有者设置为CustomView类,如下所示。 现在,出现了许多问题,例如:什么是文件所有者? 或为什么不设置子类而不是文件所有者? 等等 需要记住的几点: 文件fileowner是加载笔尖的对象,即文件loadNibName:收到消息loadNibName:或initWithNibName: loadNibName: 如果要在装载后访问笔尖中的任何对象,则可以在文件所有者中设置出口。 ViewController充当情节fileowner中View的文件所有者,这就是为什么我们没有在情节fileowner显式设置View的文件所有者。 之所以将其称为文件所有者并给予特殊的位置,是因为与笔尖中的其他对象不同,文件所有者位于笔尖外部,而不是笔尖的一部分。 实际上,只有在装入笔尖时它才可用。 因此,文件所有者是实际对象的替代者或代理,该对象随后将加载笔尖。 因此,您创建了带有许多子视图的精美视图,例如:按钮,标签等。 如果要在加载笔尖之后随时修改这些子视图中的任何一个,我们可以将这些对象的出口设置为fileowner 。 每当我们从xib创建自定义视图时,我们都将其文件所有者设置为自定义子类。 如果现在在Xcode中选择助手编辑器,它将为选定的CustomView显示相应的类CustomView ,如下所示。 第5步 将以下代码添加到CustomView类 我们在两个地方设置文件fileowner 在.xib文件中,如步骤4所示。 我们这样做是为了我们可以得出结果和采取行动。 如果不设置文件fileowner Xcode将无法连接出口和动作 如下所示,在fromNib方法中以编程方式显示为loadNibName方法,将fileowner作为参数。 如果我们发送nil而不是self,它将覆盖先前将fileowner分配给nill 。 将下面的代码添加到您的视图控制器 结论 这就是从.xib创建自定义视图的全部内容。 如果您喜欢本教程,我强烈建议您阅读有关表视图预取的另一篇文章。 够说话了。 现在让代码谈谈: rokonuddin / CustomView 通过在GitHub上创建一个帐户为rokonuddin / CustomView开发做出贡献。 […]

Swift 4中的UIButton动画

动画应用程序在Unterschied机械中的应用程序中的应用程序和应用程序。 您可以在Todo-List-App应用程序中查看Check-Button 以及 Bouncyness的遍历。 Einem Xcode Playground中的Der Prototypist。 文件和代码库的层级。 动画制作专家,所以通常没有时间安排。 动画,动画,动画,动画,动画,动画,动画) -Einen Kreis transformiert werden中的einerer Ausgangsform des abgerundeten Rechtecks。 Zudem wird der Text des Titellabels ausgeblendet,da dieser zum einen zugroßfürdie neue形成者和祖父anderenunschöneÜberlappungenverursacht。 到了新的时候,动画公司就开始了。 Der runde Button wirdschließlichauf 80%围网器Größeskaliert,um ihn imnächstenStepschließlichwieder dynamischvergrößernzukönnen。 线性动画 UIViewPropertyAnimators getriggert的完成处理程序。 Hierbei wird der eigentliche Bounce des Buttons春季动画制作。 Das Konzept提示者dieer Animationsart liegt darin,dass […]

可变的—通过Swift 4中的keyPath跟踪更改

我已经阅读了一些有关单向架构的文章。 有趣的是,您最想在状态更改时更新UI。 基本上,您将只观察状态更改,该更改将发送整个更改的状态,视图将在此状态下相应刷新。 问题在于,在UIKit中,我们没有虚拟DOM,它只能优化状态更改后需要刷新视图的部分中的视图刷新。 解决此问题的一种好方法是发送枚举,该枚举表示除了状态值本身之外状态上发生的更改。 但是我意识到,由于Swift 4中有keyPath,我们可以尝试使用它们来记录更改。 这就是我的意思,因此我编写了一个名为Changeable的小型框架,您可以在github上找到它。 Changeable框架是可容纳对象的任何类型的包装,并为您提供以下功能: 通过keyPath set属性更改 set方法不会立即应用更改 commit方法将应用由set添加的未决更改 reset方法将还原触发set’s所有未完成的更改 观察commit后set所做的更改 可以,但是如何运作,对吗? 我将只关注实现的某些部分。 您可以在github上深入研究细节。 首先,让我们关注Changeable泛型类。 最有趣的部分是set方法,该方法存储keyPath和闭包,这些闭包将在包装的值中应用更改,以后在commit方法中应用更改。 因为没有简单的方法来存储keyPath并将其连接到值,所以需要applier闭包,因为WritableKeyPath是一个通用类,不能轻易以任何顺序存储。 我可以使用AnyKeyPath但是再次必须将它们转换为WritableKeyPath因为只有这种keyPath可以用于更改属性。 幸运的是, AnyKeyPath以及WritableKeyPath都具有hashValue ,该值可以帮助我将特定的keyPath与应用程序的闭包关联起来。 值得一提的是, hashValue仅保证在程序的一次执行中有用。 但是因为我们不需要将其存储在存储中,所以很安全。 另外, Changeable类具有添加观察者的能力。 我将省略许多文章中描述的观察实现。 但是更有趣的部分是,要发出然后消费更改, Changeable使用Change结构来保存更改的值和更改的keyPath。 这是Change结构的整个实现: 没有太多要说的了。 我不向您解释代码,而是向您展示如何使用它: 结论 keyPath在Swift语言中打开了一个新的可能性世界,它为该语言带来了一点活力。 我希望您会发现Changeable是可以用来解决实际问题的工具。 让我知道你的想法。 这就是我为您准备的一切。 您会在操场上找到更多内容,并在github上进行测试。

Neden iOS? Swift’enasılbaşladın? Başlamakistiyorum,nasılbir yol izlemeliyim?

Merhabaarkadaşlar,Bugünsizlereçokald olan “ Neden iOS?,Swift’enasılbaşladın?” sorularınıncevaplarınıvereceğim。 Bunundışındaçokönemliönerilervereceğim。 Öncelikleilk sorumuzdanbaşlayalım, Neden iOS应用商店? 请选择iPhonekullanıcısıyım和iOSsevdalısıyım。 iOS的iOS设备,Steve Jobs,iPhone 3GS,iPhone 4的iPhone,iPad和iPad 4都可以使用。 Demem o ki bente iOS’tenkopamadım,您好吗? 阿斯拉! ☕️ iOS 3到4编码senelik idi,dahaçokWeb ve桌面编程程序。 Sektöründengelerinin mobilekaymasısonucu iOSgeliştirmeyekarar verdim ama o zamanlar Objective-C var idi,(2014’ten bahsediyorum,WWDCöncesi)语法’ınıciddenbeğenmiyordum。 (哈拉beğenmiyorum。) 2014年WWDCyaklaştı。 苹果公司,WWDC’de Swift’i duyurdu。 苹果,Swift’eçokgüveniyorve yeni,güçlübirdilolmasınınyanısıraSwift’eçokciddi anlamda destekvereceğininsinyallerinide veriyordu。 Burasıböyle… Neden Swiftkullanmalısınız? 迅速在德国库尔登(Kolaylıklarından)的巴尔迪尔(BarkDiş)度假。 功能模式 关闭 […]