是否有可能为UIStackView滚动?

问题描述 投票:158回答:15

比方说,我已经添加在UIStackView多个视图可以显示的,我怎么能做出UIStackView卷轴?

ios uiscrollview uistackview
15个回答
483
投票

如果有人正在寻找无代码的解决方案,我创建了一个例子,在故事板完全做到这一点,使用自动布局。

您可以从github得到它。

基本上,以重新创建例如:

  1. 创建UIScrollView,并设置其限制。
  2. 一个UIStackView添加到UIScrollView
  3. 设定限制:LeadingTrailingTopBottom应该等于从UIScrollView的那些
  4. 建立WidthUIStackView之间的平等UIScrollView约束。
  5. 设置的轴=垂直,对齐=填充,分配=相等的间隔,和间距= 0上UIStackView
  6. 添加了一些UIViewsUIStackView

0
投票

如果你有一个约束垂直居中滚动视图中的堆栈视图中,只是将其删除。


0
投票

例如,对于一个垂直stackview /滚动视图(使用自动布局的@import ScrollableStackView ScrollableStackView *scrollable = [[ScrollableStackView alloc] initWithFrame:self.view.frame]; scrollable.stackView.distribution = UIStackViewDistributionFillProportionally; scrollable.stackView.alignment = UIStackViewAlignmentCenter; scrollable.stackView.axis = UILayoutConstraintAxisVertical; [self.view addSubview:scrollable]; UIView *rectangle = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 55)]; [rectangle setBackgroundColor:[UIColor blueColor]]; // add your views with [scrollable.stackView addArrangedSubview:rectangle]; // ... ):

EasyPeasy

只要确保每个子视图的高度的定义!


0
投票
  1. 首先设计你的看法,最好是在像素描或得到什么你想要的滚动内容做的想法。
  2. 在此之后使视图控制器游离形式,并设置高度和宽度(从属性检查员选择)按您的视图的固有内容大小(从大小检查员进行选择)。
  3. 在此之后的视图控制器把滚动视图,这是一个逻辑,这是我发现的iOS是工作几乎所有的时间(它可能需要经历这种观点类的文档哪一个可以通过命令来获得+点击该类或通过谷歌搜索) 如果您正在使用两个或多个视图的工作,然后先用视图,前面已有介绍或者是比较原始的,然后去已被后来推出或者是更现代的观点开始。所以,在这里,因为滚动视图已率先推出,先开始滚动视图,然后去堆栈视图。这里把滚动视图限制到零在所有方向面对面的人其超视图。将这个滚动视图里面所有的意见,然后把它们放在堆栈视图。

虽然与堆栈视图工作

  • 先用理由了(干杯方式),即启动,如果你有标签,文本字段和图片,在您的视图,然后制定出这些意见第一(滚动视图中),并且把它们放在堆栈视图后。
  • 之后调整堆栈视图的财产。如果仍未达到期望的视图,则使用另一个栈图。
  • 如果仍然没有实现然后用压缩性或内容拥抱优先播放。
  • 在此之后添加约束到堆栈视图。
  • 还想到用一个空的UIView作为填料视图,如果所有上述不给令人满意的结果的。

让您的观点后,把母亲堆栈视图和滚动视图之间的约束,而约束孩子堆栈视图与母亲堆栈视图。希望通过这次它应该可以正常工作,或者你可能会从Xcode的建议给予警告,念出来并实施这些。希望现在你应该有一个工作视图按照您的期望:)。


0
投票

对于嵌套或单个堆栈视图滚动视图必须设置与根视图一个固定的宽度。这是滚动视图的内部主视图堆必须设置相同的宽度。 [我的滚动视图是波纹管观的忽略它]

建立UIStackView和UIScrollView中之间的相等宽度约束。

let scrollView = UIScrollView() self.view.addSubview(scrollView) scrollView <- [ Edges(), Width().like(self.view) ] let stackView = UIStackView(arrangedSubviews: yourSubviews) stackView.axis = .vertical stackView.distribution = .fill stackView.spacing = 10 scrollView.addSubview(stackView) stackView <- [ Edges(), Width().like(self.view) ]


0
投票

如果任何一个寻找水平滚动视图

enter image description here

0
投票

放置在场景滚动视图,所以它填充场景大小了。然后,将滚动视图内的堆栈视图,并将其放置在堆栈视图内的添加项目按钮。只要一切都在的地方,设置以下限制:

func createHorizontalStackViewsWithScroll() {

 self.view.addSubview(stackScrollView)
 stackScrollView.translatesAutoresizingMaskIntoConstraints = false
 stackScrollView.heightAnchor.constraint(equalToConstant: 85).isActive = true
 stackScrollView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
 stackScrollView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
 stackScrollView.bottomAnchor.constraint(equalTo: visualEffectViews.topAnchor).isActive = true
 stackScrollView.addSubview(stackView)

 stackView.translatesAutoresizingMaskIntoConstraints = false
 stackView.topAnchor.constraint(equalTo: stackScrollView.topAnchor).isActive = true
 stackView.leadingAnchor.constraint(equalTo: stackScrollView.leadingAnchor).isActive = true
 stackView.trailingAnchor.constraint(equalTo: stackScrollView.trailingAnchor).isActive = true
 stackView.bottomAnchor.constraint(equalTo: stackScrollView.bottomAnchor).isActive = true
 stackView.heightAnchor.constraint(equalTo: stackScrollView.heightAnchor).isActive = true

 stackView.distribution = .equalSpacing
 stackView.spacing = 5
 stackView.axis = .horizontal
 stackView.alignment = .fill


 for i in 0 ..< images.count {
 let photoView = UIButton.init(frame: CGRect(x: 0, y: 0, width: 85, height: 85))
 // set button image
 photoView.translatesAutoresizingMaskIntoConstraints = false
 photoView.heightAnchor.constraint(equalToConstant: photoView.frame.height).isActive = true
 photoView.widthAnchor.constraint(equalToConstant: photoView.frame.width).isActive = true

 stackView.addArrangedSubview(photoView)
 }
 stackView.setNeedsLayout()

 }

Scroll View.Leading = Superview.LeadingMargin Scroll View.Trailing = Superview.TrailingMargin Scroll View.Top = Superview.TopMargin Bottom Layout Guide.Top = Scroll View.Bottom + 20.0 Stack View.Leading = Scroll View.Leading Stack View.Trailing = Scroll View.Trailing Stack View.Top = Scroll View.Top Stack View.Bottom = Scroll View.Bottom Stack View.Width = Scroll View.Width

代码:enter image description here是关键。


-12
投票

把它变成一个Stack View.Width = Scroll View.Width ...


40
投票

苹果公司的自动布局指南包括对Working with Scroll Views一整节。一些相关的片段:

  1. 针内容视图的顶部,底部,导致,和后缘滚动视图的相应的边缘。内容视图现在定义滚动视图的内容区域。
  2. (可选的)要禁用水平滚动,设定为等于滚动视图的宽度的内容视图的宽度。内容视图现在水平充满滚动视图。
  3. (可选的)要禁用垂直滚动,设置内容视图的高度等于滚动视图的高度。内容视图现在水平充满滚动视图。

此外:

您的布局必须完全定义的内容视图的大小(除非在步骤5和6所定义的)。 ...当含量视图比滚动视图高,滚动视图使垂直滚动。当该含量视图比滚动视图更宽,滚动视图使水平滚动。

总之,滚动视图的内容视图(在这种情况下,堆叠视图)必须被固定到它的边缘和具有其宽度和/或高度另有限制。这意味着,堆栈视图的内容必须可以在其滚动期望的方向(S),这可能意味着增加了高度约束到每个视图中的垂直滚动堆栈视图内部,例如(直接或间接)的限制。以下是如何允许用于容纳堆叠视图滚动视图的垂直滚动的例子:

// Pin the edges of the stack view to the edges of the scroll view that contains it
stackView.topAnchor.constraintEqualToAnchor(scrollView.topAnchor).active = true
stackView.leadingAnchor.constraintEqualToAnchor(scrollView.leadingAnchor).active = true
stackView.trailingAnchor.constraintEqualToAnchor(scrollView.trailingAnchor).active = true
stackView.bottomAnchor.constraintEqualToAnchor(scrollView.bottomAnchor).active = true

// Set the width of the stack view to the width of the scroll view for vertical scrolling
stackView.widthAnchor.constraintEqualToAnchor(scrollView.widthAnchor).active = true

13
投票

作为EIK说,UIStackViewUIScrollView很好地一起玩,看到here

关键是,UIStackView处理可变高度/宽度不同的内容,然后UIScrollView做滚动/弹跳该内容的分内的工作:

override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        scrollView.contentSize = CGSize(width: stackView.frame.width, height: stackView.frame.height)       
}

12
投票

在得票最多的答案约束在这里工作对我来说,我已经粘贴了以下限制的图像,在我的故事板创建。

我也打不过别人应该注意的两个问题:

  1. 在接受的答案添加类似的约束后,我得到了红色自动布局错误Need constraints for: X position or width。这通过将一个UILabel作为堆栈视图的子视图解决。 我编程添加子视图,所以我本来就没有故事板子视图。为了摆脱自动版式错误的,一个子视图添加到故事板,然后将其删除在负荷增加你的真实的子视图和约束之前。
  2. 我本来试图UIButtons添加到UIStackView。按钮和意见将加载,但滚动视图不会滚动。这通过将UILabels到堆栈视图,而不是按钮解决。使用相同的限制,这种观点与UILabels滚动,但UIButtons层次没有。 我很困惑这个问题,因为UIButtons似乎有一个IntrinsicContentSize(由堆栈视图中使用)。如果有人知道为什么按钮不起作用,我很想知道为什么。

这是我的看法层次和约束,以供参考:


9
投票

我一直在寻找做同样的事情,偶然发现了这excellent post.如果你想这样做编程方式使用锚API,这是要走的路。

总之,嵌入您的UIStackViewUIScrollView,并设置UIStackView的锚约束以匹配UIScrollView的:

stackView.leadingAnchor.constraintEqualToAnchor(scrollView.leadingAnchor).active = true
stackView.trailingAnchor.constraintEqualToAnchor(scrollView.trailingAnchor).active = true
stackView.bottomAnchor.constraintEqualToAnchor(scrollView.bottomAnchor).active = true
stackView.topAnchor.constraintEqualToAnchor(scrollView.topAnchor).active = true
stackView.widthAnchor.constraintEqualToAnchor(scrollView.widthAnchor).active = true

6
投票

只需添加这viewdidload

let insets = UIEdgeInsetsMake(20.0, 0.0, 0.0, 0.0)
scrollVIew.contentInset = insets
scrollVIew.scrollIndicatorInsets = insets

来源:https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/LayoutUsingStackViews.html


5
投票

水平滚动(内的UIScrollView UIStackView)

对于水平滚动。首先,创建一个UIStackViewUIScrollView并将它们添加到下面的方式您的看法:

let scrollView = UIScrollView()
let stackView = UIStackView()

scrollView.addSubview(stackView)
view.addSubview(scrollView)

记住设置translatesAutoresizingMaskIntoConstraintsfalseUIStackViewUIScrollView

stackView.translatesAutoresizingMaskIntoConstraints = false
scrollView.translatesAutoresizingMaskIntoConstraints = false

为了让一切工作的尾部,导致的UIStackView的顶部和底部锚应该等于UIScrollView锚:

stackView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
stackView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
stackView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
stackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true

UIStackView必须比UIScrollView锚的宽度等于或大于宽度锚:

stackView.widthAnchor.constraint(greaterThanOrEqualTo: scrollView.widthAnchor).isActive = true

现在,你的锚UIScrollView,例如:

scrollView.heightAnchor.constraint(equalToConstant: 80).isActive = true
scrollView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true

scrollView.bottomAnchor.constraint(equalTo:view.safeAreaLayoutGuide.bottomAnchor).isActive = true
scrollView.leadingAnchor.constraint(equalTo:view.leadingAnchor).isActive = true
scrollView.trailingAnchor.constraint(equalTo:view.trailingAnchor).isActive = true 

接下来,我会建议试图为UIStackView对齐和分布如下设置:

topicStackView.axis = .horizontal
topicStackView.distribution = .equalCentering
topicStackView.alignment = .center

topicStackView.spacing = 10

最后,你需要使用addArrangedSubview:方法子视图添加到您的UIStackView。

文字插图

有一个附加功能,你可能会发现有用的是,由于UIStackViewUIScrollView内举行,你现在可以使用文字的插图使事情看起来有点漂亮。

let inset:CGFloat = 20
scrollView.contentInset.left = inset
scrollView.contentInset.right = inset

// remember if you're using insets then reduce the width of your stack view to match
stackView.widthAnchor.constraint(greaterThanOrEqualTo: topicScrollView.widthAnchor, constant: -inset*2).isActive = true

5
投票

Up to date for 2019.

100% storyboard OR 100% code.


Here's the simplest possible explanation:

  1. 有一个空白全屏场景
  2. 添加滚动视图。从滚动视图的基本视图控制拖动,添加左 - 右 - 顶部 - 底部,所有零。
  3. 添加在滚动视图中的堆栈视图。从堆栈视图滚动视图控制拖动,添加左 - 右 - 顶部 - 底部,所有零。
  4. 把一个的UILabel堆栈视图中。

为了清楚起见,使背景颜色为红色;高度设置为100,并在堆叠视图中的间距设定为20。

  1. 现在设置的UILabel的宽度: 令人惊讶地,控制拖动从UILabel滚动视图,不堆栈视图,并选择相等的宽度。

重复:

Don't control drag from the UILabel to the UILabel's parent - go to the grandparent. (In other words, go all the way to the scroll view, do not go to the stack view.)

就这么简单。这是秘密。

  1. 接下来,你必须点击一个的UILabel,你必须从字面上命中复制粘贴了几次。它不会与只有一个项目工作。 (不要点击“复制”,然后单击“复制然后粘贴”。)

你完成了。就这么简单。

提示:尝试添加一个新的项目,以堆栈视图,比方说,一个UIView(似乎可以作为的空间)。请注意,事事不顺心。事实上,你必须高度添加到每个新的项目(比如,“100”)。每次添加一个新项目的时候,你必须以某种方式给它的高度。


另一种方式来看待它:

在上述结构中,这样说:令人惊讶地,设置UILabels的宽度滚动视图(未堆栈视图)的宽度。完美的作品。

交替...

需要注意的是堆栈观点左右固定到其父,滚动视图。尝试这个:

Drag from the stack view to the scroll view, and add a "width equal" constraint. This seems strange because you already pinned left-right, but that is how you do it. No matter how strange it seems that's the secret.

所以,你有两个选择:

  1. 令人惊讶地,UILabels的宽度设定为滚动视图祖父母(不是stackview亲本)的宽度。

要么

  1. 出人意料的是,设置“宽度相等”的stackview的滚动型的 - 即使你有固定的滚动型反正stackview的左右边缘。

需要明确的是,做这些方法之一,不要一举两得。


2
投票

您可以尝试滚动StackView:qazxsw POI

这是Objective-C和斯威夫特兼容库。这可通过https://github.com/gurhub/ScrollableStackView

示例代码(SWIFT)

CocoaPods

示例代码(Objective-C的)

import ScrollableStackView

var scrollable = ScrollableStackView(frame: view.frame)
view.addSubview(scrollable)

// add your views with 
let rectangle = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 55))
rectangle.backgroundColor = UIColor.blue
scrollable.stackView.addArrangedSubview(rectangle)
// ...
© www.soinside.com 2019 - 2024. All rights reserved.