如何在 UIScrollView 中添加 UIStackView
Posted
技术标签:
【中文标题】如何在 UIScrollView 中添加 UIStackView【英文标题】:How to add UIStackView inside an UIScrollView 【发布时间】:2016-04-11 21:38:09 【问题描述】:我有一个UIScrollView
,它有一个UIStackView
,里面有三个对象(标签、图像和标签)
如何让滚动视图与堆栈视图一起使用?
正如您在代码中看到的,我将 Label11、image1 和 label12 添加到堆栈中 但我希望在滚动到 label21、image2 和 label22 时更改堆栈项,但我不知道怎么做!
我该怎么做?这是我尝试过的:
import UIKit
class ViewController: UIViewController
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// parent scroll
let ScrollView = UIScrollView()
ScrollView.frame = CGRectMake(0, 0, self.view.frame.size.width, 667)
ScrollView.contentSize = CGSizeMake(self.view.frame.size.width * 2, 667)
ScrollView.backgroundColor = UIColor.init(colorLiteralRed: 219, green: 237, blue: 254, alpha: 1)
ScrollView.pagingEnabled = true
//label1
let label11 = UILabel()
label11.text = "label1"
// image1
let image1 = UIImageView()
image1.frame = CGRectMake(self.view.frame.size.width * 1, 0, self.view.frame.size.width, 200)
image1.image = UIImage(named: "mother1")
//label2
let label12 = UILabel()
label12.text = "label2"
//label21
let label21 = UILabel()
label21.text = "label1"
// image2
let image = UIImageView()
image.frame = CGRectMake(self.view.frame.size.width * 1, 0, self.view.frame.size.width, 200)
image.image = UIImage(named: "mother1")
//label22
let label22 = UILabel()
label22.text = "label2"
//Stackview
let stackView = UIStackView(arrangedSubviews: [label11, image1, label12])
stackView.distribution = .FillEqually
stackView.axis = .Vertical
stackView.alignment = .Fill
stackView.spacing = 0
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.backgroundColor = UIColor.blueColor()
ScrollView.addSubview(stackView)
let margins = ScrollView.layoutMarginsGuide
stackView.leadingAnchor.constraintEqualToAnchor(margins.leadingAnchor, constant: 0).active = true
stackView.trailingAnchor.constraintEqualToAnchor(margins.trailingAnchor, constant: 0).active = true
stackView.topAnchor.constraintEqualToAnchor(margins.topAnchor, constant: 0).active = true
stackView.bottomAnchor.constraintEqualToAnchor(margins.bottomAnchor, constant: 0).active = true
stackView.widthAnchor.constraintEqualToAnchor(ScrollView.widthAnchor, constant: 0).active = true
stackView.heightAnchor.constraintEqualToAnchor(ScrollView.heightAnchor, constant: 0).active = true
self.view.addSubview(ScrollView)
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
【问题讨论】:
您需要解释更多您想要发生的事情以及这与您现在的情况有何不同。 “滚动到 label21、image2 和 label22 时堆栈项应该改变”不清楚。 你是对的。我通过添加我不知道的部分来澄清。谢谢! 我遇到了同样的问题。我对动态地做这件事感到沮丧,我也喜欢这种方式。希望有人解释这个 uistackview 业务。 Is it possible for UIStackView to scroll?的可能重复 【参考方案1】:我最终这样做了。附上代码示例
import UIKit
class ViewController: UIViewController
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let parentView = UIView()
parentView.backgroundColor = UIColor.blackColor()
parentView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)
// parent scroll
let parentScrollView = UIScrollView()
parentScrollView.frame = CGRectMake(0, 50, self.view.frame.size.width, self.view.frame.size.height - 100)
parentScrollView.contentSize = CGSizeMake(self.view.frame.size.width * 2, self.view.frame.size.height - 100)
parentScrollView.backgroundColor = UIColor.init(colorLiteralRed: 219, green: 237, blue: 254, alpha: 1)
parentScrollView.pagingEnabled = true
// add 1st mother
let imageView1 = UIImageView()
imageView1.frame = CGRectMake(self.view.frame.size.width * 0, 0, self.view.frame.size.width, 467)
imageView1.image = UIImage(named: "mother1")
// add 2nd mother
let imageView2 = UIImageView()
imageView2.frame = CGRectMake(self.view.frame.size.width * 1, 0, self.view.frame.size.width, 467)
imageView2.image = UIImage(named: "mother2")
//-----------------------------------------------------
// child scroll
let childScrollView = UIScrollView()
childScrollView.frame = CGRectMake(0, 467, self.view.frame.size.width, 0)
childScrollView.contentSize = CGSizeMake(self.view.frame.size.width * 2, 0)
childScrollView.layer.borderColor = UIColor.blackColor().CGColor
childScrollView.pagingEnabled = true
// child 1
let imageViewChild1 = UIImageView()
imageViewChild1.frame = CGRectMake(self.view.frame.size.width * 0, 0, self.view.frame.size.width, 200)
imageViewChild1.image = UIImage(named: "child1-1")
childScrollView.addSubview(imageViewChild1)
print("the frame of imageViewChild1 is: \(imageViewChild1.frame)")
// child2
let imageViewChild2 = UIImageView()
imageViewChild2.frame = CGRectMake(self.view.frame.size.width * 1, 0, self.view.frame.size.width, 200)
imageViewChild2.image = UIImage(named: "child2-1")
childScrollView.addSubview(imageViewChild2)
print("the frame of imageViewChild2 is: \(imageViewChild2.frame)")
//-----------------------------------------------------
// child scroll
let childScrollView2 = UIScrollView()
childScrollView2.frame = CGRectMake(468, 467, self.view.frame.size.width, 0)
childScrollView2.contentSize = CGSizeMake(self.view.frame.size.width * 2, 0)
childScrollView2.layer.borderColor = UIColor.blackColor().CGColor
childScrollView2.pagingEnabled = true
let imageViewChild3 = UIImageView()
imageViewChild3.frame = CGRectMake(self.view.frame.size.width * 0, 0, self.view.frame.size.width, 200)
imageViewChild3.image = UIImage(named: "user-1")
childScrollView2.addSubview(imageViewChild3)
print("the frame of imageViewChild1 is: \(imageViewChild3.frame)")
let imageViewChild4 = UIImageView()
imageViewChild4.frame = CGRectMake(self.view.frame.size.width * 1, 0, self.view.frame.size.width, 200)
imageViewChild4.image = UIImage(named: "user")
childScrollView2.addSubview(imageViewChild4)
print("the frame of imageViewChild4 is: \(imageViewChild4.frame)")
//-----------------------------------------------------
// add label for the button space
let buttons = UIView()
buttons.backgroundColor = UIColor.redColor()
let motherstackView = UIStackView(arrangedSubviews: [imageView2, imageView1])
motherstackView.distribution = .FillEqually
motherstackView.axis = .Horizontal
motherstackView.alignment = .Fill
motherstackView.spacing = 0
motherstackView.translatesAutoresizingMaskIntoConstraints = false
let ChildstackView = UIStackView(arrangedSubviews: [childScrollView, childScrollView2])
ChildstackView.distribution = .FillEqually
ChildstackView.axis = .Horizontal
ChildstackView.alignment = .Fill
ChildstackView.spacing = 0
ChildstackView.translatesAutoresizingMaskIntoConstraints = false
//Stackview
let stackView = UIStackView(arrangedSubviews: [motherstackView, ChildstackView, buttons])
stackView.distribution = .Fill
stackView.axis = .Vertical
stackView.alignment = .Fill
stackView.spacing = 0
stackView.translatesAutoresizingMaskIntoConstraints = false
parentScrollView.addSubview(stackView)
parentView.addSubview(parentScrollView)
stackView.leadingAnchor.constraintEqualToAnchor(parentScrollView.leadingAnchor, constant: 0).active = true
stackView.trailingAnchor.constraintEqualToAnchor(parentScrollView.trailingAnchor, constant: 0).active = true
stackView.topAnchor.constraintEqualToAnchor(parentScrollView.topAnchor, constant: 0).active = true
stackView.bottomAnchor.constraintEqualToAnchor(parentScrollView.bottomAnchor, constant: 0).active = true
stackView.widthAnchor.constraintEqualToAnchor(parentScrollView.widthAnchor,multiplier: 2, constant: 0).active = true
stackView.heightAnchor.constraintEqualToAnchor(parentScrollView.heightAnchor, constant: 0).active = true
motherstackView.heightAnchor.constraintEqualToAnchor(ChildstackView.heightAnchor, multiplier: 1).active = true
ChildstackView.heightAnchor.constraintEqualToAnchor(buttons.heightAnchor, multiplier: 2).active = true
self.view.addSubview(parentView)
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
【讨论】:
【参考方案2】:对于需要 cocoapods 解决方案的人,请尝试 ScrollableStackView 库。这是github页面:
https://github.com/gurhub/ScrollableStackView
这里是一些示例代码:
斯威夫特
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)
// ...
Objective-C
@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];
// ...
希望对某人有所帮助。
【讨论】:
以上是关于如何在 UIScrollView 中添加 UIStackView的主要内容,如果未能解决你的问题,请参考以下文章
如何在像 BBC 新闻应用一样的 UIScrollView 中添加“广告”?