Tag: uistackview

使用Storyboard在水平UIStackView中滚动

自从UIStackView发布UIStackView ,它已成为iOS开发人员中广泛使用的UI元素。 它减少了我们手动设置大量约束的繁重工作。 尽管它在大多数情况下提供了灵活性,但并没有提供我们大多数人希望具有的滚动行为。 上一次,我有一个要求,我需要在其中使用水平滚动的堆栈视图。 我在Google上搜索了很多,发现了很多资源。 但是大多数都是从代码方面完成的。 我还发现一些在情节提要中完成的工作。 您可以在此SO Post中找到一些建议。 是的,我可以考虑以编程方式进行操作。 但是我不会。 因为我不是一个好的程序员。 我喜欢在情节提要中进行设计。 但是在尝试使用情节提要的游戏之后,我只是失败了。 有时,约束没有得到满足。 即使满足约束条件,滚动也不起作用。 所以我最终得到了解决方案。 如果您需要了解我的操作方法,请花一些时间阅读全文。 我把前导和尾随匹配到超级视图的边缘。 将其放在垂直居中的位置并给出高度限制。 这样做可以满足所有必需的约束。 您显然可以根据需要定位此滚动视图。 现在,将水平堆栈视图从库拖动到滚动视图。 将属性用于堆栈视图,如下所示: 将其边缘固定到其超级视图(滚动视图)。 我喜欢在领先者和落后者之间保持一定的差距。 因此,我将其设置为10分。 但是等等,什么? 🙄🙄 刚刚发生了什么? 😕我添加了前导和尾随约束,并将滚动视图与超级视图的中心Y对齐。 首先也给出了高度限制。 但是为什么这总是抱怨呢? 罪魁祸首是UIScrollView contentView 。 从苹果文档: 滚动视图必须知道内容视图的大小,以便知道何时停止滚动 那么,如何预先指定内容视图的大小? 是的你可以。 因为这里的内容视图是您的堆栈视图 。 您只需在文档大纲中从堆栈视图控制+单击+拖动到滚动视图,然后按Shift键即可选择等宽和等高: 这样做将消除情节提要板错误。 看到: (我使用-20作为等宽的常数,因为我之前将前边缘和后边缘设置为距超级视图边缘10 pt,以便总宽度匹配) 但是……我们做错了什么。 让我们先看看输出中可能是错误的: 一旦指定了内容视图的宽度和高度 ,我们就失去了滚动视图的滚动行为。 另外,整个内容视图现在仅包含在滚动视图的可见区域中。 它不会扩展到屏幕边缘以外。 您可以在这里阅读。 […]

如何制作智能的UIStackView垫片

您是否曾经需要创建一个在每个已排列的子视图之间具有不同间距的StackView? 好吧,如果您有并且您的项目需要支持比iOS 11更旧的操作系统(您可以在iOS 11+中本地运行),则可能只是创建了一个空的子视图,并定义了宽度/高度并将其添加到其他子视图之间。 但是,嘿,有一个陷阱。 如果要隐藏原始排列的子视图之一(假设是中间的子视图),该怎么办? 隐藏它之后,很可能会有不希望有的间距,因为它的两侧都存在空的隔离子视图。 因此,您也必须隐藏一个空的隔离子视图,这可能是您要避免保持代码清洁的一种方法。 在本博文中,我将向您展示如何以更聪明的方式实现此方法,以便您的spacer视图自动随内容视图一起隐藏。 这个想法是添加一个连接到内容视图并与其隐藏的间隔器。 我们将通过在UIView(这将是我们的内容视图)上创建扩展来实现此目的,该扩展具有创建间隔视图并返回它的功能。 在函数内部,间隔视图将观察内容视图的“隐藏”属性,并对该属性的任何更改做出反应。 该功能将使用参数来区分垫片的尺寸,轴和优先级。 这是我们将要实现的功能的概要: 扩展UIView { func createSpacer(_ size:CGFloat,axis:UILayoutConstraintAxis,priority:Int)-> UIView { //这将是一个创建并返回间隔符的代码,该间隔符将观察self的“隐藏”属性(这是我们的内容视图) } } 然后,您将在ViewController中创建类似于以下内容的间隔符: 让aLabel = UILabel() yourStackView.addArrangedSubview(aLabel) yourStackView.addArrangedSubiew(aLabel.createSpacer(10,轴:.vertical,优先级:1000)) UIStackView间隔符:实现 我将向您展示依赖于ReactiveSwift的有效实现。 然后,我将描述我尝试过的其他方法以及为什么它们不起作用。 该实现还取决于SnapKit(这是自动布局框架),当然也取决于UIKit。 因此,请不要忘记将其导入文件顶部。 导入UIKit 导入SnapKit 导入ReactiveSwift 我认为实现非常简单。 在“ createSpacer”函数内,您将创建一个隔离器,即UIView。 然后,将其“ isHidden”属性设置为最初与内容视图的(isself)“ isHidden”属性匹配。 然后,您可以将内容视图的“ isHidden”属性的反应绑定到spacer的“ isHidden”属性,因此每次隐藏或取消隐藏内容视图时,都可以。 垫片也会自动隐藏或取消隐藏。 请注意,由于Objective-C的旧名称,signal:forKeyPath函数必须使用“隐藏”字符串作为参数。 之后,仅使用SnapKit框架创建所需的间隔物高度或宽度(取决于轴)大小约束,然后返回间隔物。 扩展UIView { 私有函数createSpacer(_大小:CGFloat,轴:UILayoutConstraintAxis,优先级:Int)-> UIView { […]

使用UIStackView动态调整大小的按钮

问题 :我们曾遇到过这样一种情况,我们想通过在屏幕截图(如下图)中具有相等的宽度来显示两个水平放置的按钮。 在某些情况下,我们可能需要隐藏其中一个按钮,并将按钮的中心显示在视图的下方,如屏幕截图所示。 我们知道这是安静的常见情况,可以通过使用约束来实现。 但是,通过使用约束,我们最终需要添加许多约束来查看并在需要隐藏一个按钮时对其进行更改。 通过使用堆栈视图,我们可以轻松地做到这一点而无需处理约束。 当我们使用堆栈视图时,当我们需要隐藏一个按钮时,我们最终会拉伸按钮(在具有填充对齐的水平堆栈视图中)。 为了避免这种情况,我们需要像下面的代码片段一样适当地更改StackView的轴,对齐方式和分布。 在这里,我们将堆栈视图轴修改为垂直,以对齐为中心 , 分布为fillProportionally,当我们隐藏按钮之一时。 注意: Modify(forAxis:.vertical……是UIStackView扩展中的辅助方法。 Github链接以获取完整代码。 LeelaRamala / ButtonsInStackView 这是一个示例代码,用于通过使用堆栈视图在视图中显示动态调整大小的按钮。 通过使用堆栈视图,我们可以… github.com 希望这可以帮助!。 欢迎建议🙂

以编程方式在UIStackView中添加视图

堆栈视图使用内部内容大小,因此使用布局约束来定义视图的尺寸。 有一种简单的方法可以快速添加约束(示例): [view1.heightAnchor constraintEqualToConstant:100] .active = true; 完整代码: -(void)setup {//查看1 UIView * view1 = [[UIView alloc] init]; view1.backgroundColor = [UIColor blueColor]; [view1.heightAnchor constraintEqualToConstant:100] .active = true; [view1.widthAnchor constraintEqualToConstant:120] .active = true; //查看2 UIView * view2 = [[UIView alloc] init]; view2.backgroundColor = [UIColor greenColor]; [view2.heightAnchor constraintEqualToConstant:100] .active = true; [view2.widthAnchor constraintEqualToConstant:70] .active = true; //查看3 UIView […]

在Swift中高效滚动UIStackView

如何构建滚动堆栈容器并保持内存的正常使用。 如今,移动用户界面已成为一项复杂的工作。 列表(表,或更常见的是集合)可能包含不同种类的项目,从而在单个滚动交互中显示了大量数据。 以IMDB应用程序为例; 主页包含: 带有突出显示的电影的水平列表 重点新闻 带有照片库的水平列表 与附近电影的水平列表 即将推出的电影的另一个水平列表 新闻垂直列表 …是的,还有更多东西 单个垂直滚动视图中的所有内容! 通常,如果您在编写此类代码时仍然缺乏注意力,则视图控制器可能会成为大量的意大利面条式代码,将多个职责组合在一起,并使您的应用程序更脆弱且更不可测试。 那就是Massive View Controllers的世界,以及诸如Viper,MMVM和其他几种替代体系结构背后的主要原因。 关注点分离(以及“单一责任原则”)是一种将计算机程序分为不同部分的设计原理,这样每个部分都可以解决一个单独的关注点。 天真的方法 将这类布局带回家的最简单方法是使用表或集合,然后将对象放入内部(即,内部布局复杂的富单元格); 尽管它实际上只适用于很少的对象,但具有相当数量的异构对象,但最终的体系结构却是您可以避免的疯狂庇护。 JustEat UK的ScrollingStackViewController类使用UIScrollView内的UIStackView的方法来模拟Android的垂直布局。 正如自述文件所述,它是在构建数量有限或动态且内容丰富的滚动控制器的情况下的一种更合适的方法。 但是,当您的布局变得复杂时,可能导致相关的内存占用或不可持续。 在一个或多个子视图控制器包含垂直表或集合的情况下。 实际上,为了使它们正常工作,您需要扩展这些视图以显示整个内部表/集合的内容,并以内部单元格的巨大分配作为结尾(即使当前不可见):您到表的缓存。 请参阅以下示例: 高效方法 以下工作的灵感来自Ole Begamnn的一篇旧文章“ Scroll Views Inside Scroll Views”,我几年前在CreoLabs上为CreoKIT制作UITableView克隆时曾大量使用它。 主要区别在于它可以与UIViewControllers并可以正确管理,然后这些容器是UIScrollView子类的容器(如UITableView或UICollectionView ); 是的,它适用于Swift 3+。 基本上,这是一个UIViewController ,它期望在其中包含UIScrollView (您可以通过情节提要进行设计并链接插座,因此可以自由保留自己的自定义布局)。 它允许实现以下目的: 将多个UIViewControllers (视图)彼此放在下面,以使它们的滚动行为仍然感觉完全正常。 如果视图是表集合或垂直集合,则内置单元重用功能不会受到影响,并且可以按您期望的方式直接使用。 将一个复杂的UITableViewDataSource/UICollectionViewDataSource转换为几个不同的UIViewControllers ,这些UIViewControllers独立管理其同类(?)数据。 这是第一个版本; 我的主要目标是拥有一个高效的堆栈容器; 没有小饰品或特殊功能(但是,即使有您的帮助,迭代后它也会变得更好)。 例如,它目前仅支持垂直堆叠。 UITableView和UICollectionView都是UIScrollView子类; 它们的行为基本上类似于标准滚动视图,但主要区别在于内部单元进行的回收操作。 […]

如何以编程方式重新排列IOS中的UIStackView内的项目?

如何以编程方式重新排列IOS中的UIStackView中的项目? (即我看不到在https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIStackView_Class_Reference/#//apple_ref/doc/uid/TP40015256-CH1-SW30覆盖这个function)? ??

如何以编程方式为ios 9中的UIStackView的alignment属性设置animation效果

我想知道如何在水平UIStackView的alignment属性中将UIStackViewAlignmentCenter中的alignment属性更改为UIStackViewAlignmentTop,反之亦然,并且我想在视觉上同时反映此更改。 编辑: 我拥有的: 这是我的观点层次: 两个button名为b1和b2; b1有一个名为“changeAlignmentToTop”的动作,而b2有一个名为“changeAlignmentToCenter”的动作。 一个名为Pview的UIView框架(0,100,414,100)。 一个名为S1的水平UIStackView,其alignment属性设置为“center”。 这个堆栈视图已被固定到pView的边界。 一个名为S2的水平UIStackView,其alignment属性设置为“Fill”,里面有两个标签。 我想做的事: 当我触摸buttonb1时,我想将S1的alignment从“中心”更改为“顶部”,并且我想为该更改设置animation。 我试过了 – (void) changeAlignmentToTop { [UIView animationWithduration 0.3 animations : ^{ S1.alignment = UIStackViewAlignmentTop; // here I'd prove several options // option – 1 [S1 setNeedsDisplay]; [S1 layoutIfNeeded]; // option – 2 //[S1 setNeedsLayout]; //[S1 layoutIfNeeded]; // option – 3 //[S1 setNeedsDisplay]; //[pView […]

CGRectContainsPoint不适用于不同的视图

我正在做一个简单的拖放项目。 当我使用CGRectContainsPoint拖动一个视图,并放在不同的视图,它的作品。 但是这两种观点都应该是一个观点。 现在让我们说我有一个名为“A”的视图,它包含两个视图。 一个UIView和一个UIStackView 。 如果我将视图拖到堆视图到UIView它不会丢弃。 只是CGRectContainsPoint不适用于从不同的视图拖放。 有什么办法可以解决吗?

使用自动布局检索子视图的正确位置

我想以编程方式将一个视图放在故事板中创build的所有子视图的中心。 在故事板中,我有一个视图,并在一个垂直堆栈视图中,它具有约束来填充整个屏幕,分布“等距”。 在垂直堆栈视图的内部,我有3个水平堆栈视图,约束高度= 100,尾随和领先的空间:从超级视angular0。 分布也是“等距”。 在每个水平堆栈视图中,我有两个视图,约束宽度和高度= 100,视图是红色的。 到目前为止,这么好,我有我想要的接口, 现在我想检索每个红色视图的中心,在这个位置放置另一个视图(实际上,它将成为棋盘上的棋子…) 所以我写到: import UIKit class ViewController: UIViewController { @IBOutlet weak var verticalStackView:UIStackView? override func viewDidLoad() { super.viewDidLoad() print ("viewDidLoad") printPos() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) print ("viewWillAppear") printPos() } override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() print ("viewWillLayoutSubviews") printPos() } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() print […]

在栈视图内创buildUilabels之间的垂直线

我想在代码中创build一个自定义标题的UICollectionView。 因此,我创build了UICollectionViewCell的子类来描述我的自定义标题。 我想在水平线的头部显示五个标签。 所以我创build了五个标签并将它们添加到一个stackView中。 stackview显示我的标签平等填充。 到目前为止一切都完美 标签1标签2标签3标签4标签5 //Label 1 let votesLabel: UILabel = { let label = UILabel() let attributedText = NSMutableAttributedString(string: "Votes", attributes: [NSFontAttributeName: UIFont.boldSystemFont(ofSize: 12) ]) attributedText.append(NSAttributedString(string: "\n 0", attributes: [NSForegroundColorAttributeName: UIColor.lightGray, NSFontAttributeName: UIFont.systemFont(ofSize: 14)])) label.attributedText = attributedText // label.text = "11\nvotes" label.textAlignment = .center label.numberOfLines = 0 return label }() // label […]