Tag: uikit

使用UICollectionView构建自适应的自适应iOS应用

UICollectionView是一个UIKit视图,用于管理已订购商品的集合,并使用可自定义的布局显示商品。 它是由Apple在WWDC 2012中随iOS 6 SDK发行而引入的。 UICollectionView接口与旧的UITableView非常相似,因为它提供DataSource作为显示数据的源,并提供Delegate处理每个项目的交互。 与UITableView在UITableViewCell内部使用固定列表布局显示每一行不同, UICollectionView通过子类化UICollectionViewLayout为开发人员提供了灵活性和可自定义性以提供自己的布局,它还支持自定义装饰视图,每个单独的横断面图和单元格的可自定义大小。 Apple本身提供了一种UICollectionViewFlowLayout布局,称为UICollectionViewFlowLayout 。 UICollectionViewFlowLayout是使用网格系统显示项目的布局,并支持页眉和页脚。 它还提供了2个垂直和水平滚动方向。 在垂直方向上,项目的宽度受集合视图的宽度限制,因此在每一行中,它会尝试在下降到下一行之前在集合视图宽度的范围内填充尽可能多的项目,因此用户可以垂直滚动内容。 在水平方向上,内容的高度受集合视图的高度限制,因此在每一列中,在向右移动到下一列之前,将尽可能多地添加项目,以便用户可以水平滚动。 如果要使用集合视图构建圆盘传送带,则水平滚动方向非常适合。 我们将建立什么 在本文中,我们将使用UICollectionViewFlowLayout构建一个自适应的电影列表应用程序,以适应从小型iPhone 5到最大iPad Pro的各种UICollectionViewFlowLayout 。 用户将具有使用列表,小网格和大网格布局显示电影的选项。 以下是我们将要执行的任务: 启动项目。 建立模型。 构建MainListViewController 。 构建列表布局。 构建网格布局。 开始项目 要开始项目,您可以在下面的GitHub存储库中下载入门项目。 alfianlosari /响应式iOS收集视图启动器 带有Collection View的自适应和自适应iOS App的入门项目… github.com 入门项目包含多个资产,用于列表的集合视图单元格以及我们将用于集合视图的网格项目布局。 建立模型 让我们创建代表电影的模型。 创建一个新文件,并将其命名为Movie.swift 。 复制下面的声明以创建具有所有属性的Movie结构。 我们还需要确保更新MovieLayoutListCollectionViewCell ,在这里我们创建一个方法setup(movie:)以便在通过电影时可以设置标签和图像视图。 建立网格布局 让我们构建网格布局,在此布局中,每个单元格将仅在每个单元格内显示电影的海报图像。 窥视入门项目提供的MovieLayoutGridCollectionViewCell ,以查看布局。 确保更新MovieLayoutGridCollectionViewCell ,在这里我们创建一个方法setup(movie:)以便在通过电影时可以设置图像视图。 结论 最后,恭喜!我们已经成功使用Collection View构建了自适应的自适应iOS应用程序! 借助Cocoa Touch […]

在iOS App中构建可重用的通用UITableViewController

TableView Controller是一个必不可少的UIKit组件,几乎每个iOS应用程序都使用TableView Controller组件来显示列表中的数据。 当我们要在UITableViewController显示不同类型的数据时,大多数时候我们会创建一个新的子类来显示相关的数据类型。 这种方法有效,但是如果我们的应用程序中有许多不同类型的数据,则可能导致重复和维护困难。 我们如何解决这个问题? 一种方法是,我们可以使用Swift通用抽象数据类型使用简单抽象来创建通用UITableViewController子类,该子类可用于使用Swift通用约束配置和显示不同种类的数据。 您可以在GitHub存储库中找到并构建源项目: alfianlosari / GenericTableViewController 通用UITableViewController实现的示例– alfianlosari / GenericTableViewController github.com 我们创建一个名为GenericTableViewController的UITableViewController子类,并添加2种类型的Generic T和Cell 。 我们添加了约束,即Cell必须是UITableViewCell子类。 T将用作数据的抽象,而Cell将被注册到UITableView并出队以将每行的数据显示为UITableViewCell 。 类 GenericTableViewController :UITableViewController { 变量 :[T] var configure:(Cell,T)-> Void var selectHandler:(T)-> Void init (items:[T],​​配置: @转义 (Cell,T)-> Void,selectHandler: @转义 (T)-> Void){ 自我 .items =项目 自我 .configure =配置 自我 .selectHandler = selectHandler 超级 .init(样式:.plain) self […]

测试序列的两种方法

未经请求的代码审查。 最近,我正在阅读使用Swift 3进行测试驱动的iOS开发,并且有一章他们测试从一个UIViewController迁移到另一个。 这让我思考了执行segue / present UIViewController的各种方法以及每种方法的简便性。 我想谈两种方式。 @IBAction将UIControl与@IBAction一起用于UIViewController并在代码中显示UIViewController -这是本书所建议的 将UIControl与UIStoryboard segue一起使用 当然,我认为#2(我的方式)更好,但我希望您能读懂并选择适合您和您的项目的方式。 该书建议将UIViewController嵌入UINavigationController ,其中UIBarButtonItem具有IBAction ,该IBAction呈现从UIStoryboard实例化的不同UIViewController 。 TLDR; 这是一张照片: 测试如下所示: 在我的设置中,我有一个UIStoryboard segue,它带有一个链接两个UIViewController的当前模态选项。 测试如下所示: 确实,没有代码。 这是情节@IBAction文件中的一次单击(基本上),而不是@IBAction ,您可以忘记将其链接到可能错误实现的代码。 好: 更少的代码 清洁代码 更清晰的测试命名 UIViewController和UIStoryboard之间的耦合UIStoryboard 测试标识符。 序列不需要标识符即可工作。 也就是说,如果有一个,稍后将更容易测试两个UIViewController之间的关系,而无需涉及UIBarButtonItem 我对此不满意: 我不喜欢在测试中使用value(forKey:) 。 在这里似乎很有必要,但仍然有种黑涩的代码味道 我认为测试目标是否具有标识符可能更清洁,并且当传递该标识符时, performSegue(withIdentifier:sender:)呈现正确的UIViewController 。 整个performSelector rigamarole似乎有点稠密 我希望这能给您一些启发,帮助您实现对UIStoryboardSegue进行单元测试的方式, UIStoryboardSegue您更多地考虑UIControl 。 我还希望您注意到这两个解决方案最令我困扰的是,没有人测试过以模态形式呈现UIViewController情况。 现在,您可以将UIStoryboardSegue从“ Show (eg Push)更改为“ UIStoryboardSegue Present Modally而无需中断测试。 作为设置的一部分,可以通过将UIViewController添加到UINavigationController来纠正这种疏忽,但是我认为添加此范围不在本文的讨论范围之内。 […]

为什么viewWillAppear没有被调用?

您为什么期望如此? 最有可能的是-您想知道您的用户将要看到一个屏幕。 有各种各样有用的理由想要这个。 也许您想跟踪分析屏幕视图,或触发数据获取以保持屏幕新鲜。 无论您的目标是什么,有人都可能告诉您检查viewWillAppear -好消息。 它会实现这些目标,但有时会起作用。 * 简单答案 调用viewWillAppear的技术原因很简单。 通知视图控制器其视图将被添加到视图层次结构中。 它不能是任何视图层次结构-它必须是在根目录下具有UIWindow视图层次结构(不一定是可见窗口)。 如果您从一个选项卡跳到另一个选项卡,或者从UINavigationController推送并弹出,那很好。 iOS正在从视图层次结构中删除视图,并每次都将其重新插入。 在所有这些过程中,视图仍保留在内存中,因此不会重复调用viewDidLoad 。 但是,当您开始在当前屏幕上显示视图时会遇到麻烦,因为有时*它将删除基础视图,但有时*不会。 展示您的View Controller 这完全取决于您如何呈现模态视图。 如果可能的话,iOS倾向于删除基础视图(内存很宝贵)。 但是,如果您的设计师坚持要保留该基本视图,则可以要求iOS通过设置正确的.modalPresentationStyle来保留它。 您可以选择以下选项,以及关闭后是否在其父视图上触发viewWillAppear : UIModalPresentationStyle选择 .none的文档说…… “不要使用这种样式来呈现视图控制器。” 他们通过崩溃强制执行此操作。 感谢Apple让我们保持警惕! 备用计划 当下面的视图保留时,关闭叠加视图时将不会调用viewWillAppear 。 要开展业务,您必须在dismiss呼叫中加入完成处理程序。 将引用传递给呈现的视图控制器的最佳方法是什么? 这确实取决于您如何设置应用程序,这超出了本文的范围。 缺失的环节 当我们将视图添加到窗口的视图层次结构时,iOS如何知道要通知哪个UIViewController ? 从UIViewController文档中,我们可以看到它具有对其拥有的view的引用,但是UIView文档中没有任何内容表明它知道哪个UIViewController拥有它。 这些present方法也没有什么特别的事情发生-即使直接添加视图, viewWillAppear调用也会发生。 仅仅因为苹果不告诉我们发生了什么,并不意味着我们就无法做出有根据的猜测。 让我们偷偷摸摸,检查专用API… 查看所有这些额外的属性! 而且只有一种具有我们要寻找的类型…… UIViewController* _viewDelegate; 让我们通过创建2个视图控制器进行测试。 我们将一个注入到另一个view的_viewDelegate中,并将该view添加到窗口的视图层次结构中时,应调用注入的视图控制器的viewWillAppear 。 自己尝试一下! 警告 —请勿使用私有API交付应用程序。 这是一种危险的编码方式。 这些属性是私有的,Apple保留在不通知您的情况下随时更改其基础实现的权利。 […]

Swift 4:填充UITextField和UITextView

扩展检查角半径,边框颜色和阴影 这是与填充无关的其他部分。 如果您不需要了解此主题,只需跳至步骤2。 1. UITextField填充 第5行:更改为您喜欢的任何填充。 第12、16、21行:将textRect,placeholderRect,editingRect覆盖为已实现的填充。 2. UITextView填充 第4行:将textContainerInset设置为所需的UIEdgeInsets。 快来玩Swift! 随时问任何问题🙂

双向滚动UITableViews

我已经知道您在想什么……这没有道理。 UITableView是通过垂直滚动来显示其内容的,为什么您要一个双向滚动呢? 当前,在Shine Labs,我们正在构建一个iPad应用程序,该应用程序使用具有非常宽内容的单元格来实现全屏UITableView。 随着开发的进行,客户希望该应用程序同时支持iPad多任务处理和iPhone。 为了做到这一点,我们需要采取一种对时间敏感且微创的方法来适应各种屏幕尺寸。 我们想出的解决方案非常简单,并允许我们重用整个现有的UI,并有一些小的警告。 通过在运行时将UITableView嵌入UIScrollView中,我们可以确定UITableView是否足够宽以容纳其所有内容。 如果没有,我们将其宽度增加一定程度,并使UIScrollView能够水平滚动。 让我们来看一个实际的例子。 在UIViewController的viewDidLoad方法中,我们配置UITableView和UIScrollView的布局。 为了配置布局,我们使用了自动布局抽象库SnapKit来使约束代码更加简洁。 私人 让 scrollView = UIScrollView() 私人 让 tableView = UITableView() 覆盖 func viewDidLoad(){ 超级 .viewDidLoad() configureConstraints() } 私人 功能 configureConstraints(){ view.addSubview(scrollView) scrollView.snp.makeConstraints { $ 0.edges.equalToSuperview() } scrollView.addSubview(tableView) 让 tableViewWidth = view.frame.width tableView.snp.makeConstraints { $ 0.edges.equalToSuperview() $ 0.height.equalTo(视图) $ 0.width.equalTo(tableViewWidth) } } 我们首先将scrollView边缘固定到视图。 然后,将tableView边缘固定到scrollView […]

快速提示:向UIView添加圆角和阴影

为什么看似简单的事情很难 背景故事 我已经在一个应用程序上工作了几年,并且收到了一个简单的设计请求:在视图上四处拐角并添加阴影。 容易吧? //设置拐角半径 layer.cornerRadius = 6.0 layer.masksToBounds = true //设置阴影属性 layer.shadowColor = UIColor.black.cgColor layer.shadowOffset = CGSize(宽度:0,高度:1.0) layer.shadowOpacity = 0.2 layer.shadowRadius = 4.0 错误! 如果您以前尝试过此方法,那么您将确切知道会发生什么。 角将变圆,但阴影将消失。 如果将masksToBounds设置为false,则将显示阴影,但不会对角进行圆化。 CALayerWhyAreYouDoingThisToMe 事后看来, layer.masksToBounds = true的原因实际上是显而易见的,它会layer.masksToBounds = true该图层之外的所有内容。 阴影将在图层外部绘制,因此也会被剪切。 因此,我们不能对这两种效果使用同一层。 解决方案 我将分享我发现阻力最小的路径。 我选择创建一个固定在父view边缘的内部containerView 。 阴影将应用于父view的图层,而圆角将应用于containerView 。 然后,只需将所有内容添加到containerView 。 我敢肯定,也可以使用子图层和蒙版来完成此操作,但是使用AutoLayout时会遇到一些麻烦,因为我们不知道布局时视图的大小。 这将需要覆盖视图控制器中的layoutSubviews或视图控制器中的viewDidLayoutSubviews以便更新图层路径,但是坦率地说,这比看起来如此琐碎的事情要花更多的精力。 检查以下要点。 评论很好,所以应该很容易理解。 更新! 我偶然发现了StackOverflow帖子(当然),找到了可以用来避免添加子视图的替代解决方案。 魔术发生在: shadowLayer.path = UIBezierPath(roundedRect: […]

如何在iOS 5中添加多个UITextfield?

如何创build和添加多个UITextField到我的控制器? 我可以创build一个,就像这样: UITextField *tf = [[UITextField alloc] initWithFrame:CGRectMake(5,5,100,25)]; tf.borderStyle = UITextBorderStyleRoundedRect; [tf setReturnKeyType:UIReturnKeyDefault]; [tf setEnablesReturnKeyAutomatically:YES]; [tf setDelegate:self]; [self.view addSubview:tf] 但是,我需要为每个UITextField做这个吗? 什么是模板UI控件的最佳方法?

在UIScrollView中实现UIWebView

我试图在UIScrollView中使用UIWebView,我想显示一个图像下的webview,使他们可以滚动。 所以我走了那些步骤: 取消激活UIWebView的滚动属性 设置UIScrollView和UIWebView高度等于内容大小。 而这个我的代码: – (void)viewDidLoad { [super viewDidLoad]; self.contentReader.scrollView.scrollEnabled = NO; NSString *myDescriptionHTML = [NSString stringWithFormat:@"<html> \n" "<head> \n" "<style type=\"text/css\"> \n" "body {font-family: \"%@\"; font-size: %d;}\n" "</style> \n" "</head> \n" "<body>%@</body> \n" "</html>", @"JF Flat", 18, self.thePost.content]; [self.contentReader loadHTMLString:[NSString stringWithFormat:@"<div style='text-align:right; text-align:justify; direction:rtl'><style type='text/css'>img { max-width: 100%%; width: auto; height: auto; }</style><style […]

找不到支持键盘types的键盘

我有用于input电子邮件的UITextField。 所有的工作 – 但我在debugging器terminal有这个问题: Can't find keyplane that supports type 7 for keyboard iPhone-Portrait-Emoji-Email; using 1582125428_Portrait_iPhone-Emoji-Keyboard_Letters 我怎样才能解决它?