简体   繁体   中英

How to add UIStackView inside an UIScrollView

I have a UIScrollView that has UIStackView with three objects inside it (label, image and label)

How do I let the scrollview work with the stackview?

As you see in code I added the Label11,image1 and label12 to the stack but I want the stack items to change when scrolling to label21, image2 and label22 and I don't know how!

How can I do that? Here is what I have tried:

布局

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.
}
}

I ended up doing it like this. Attached is a code sample

在此处输入图片说明

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.
}


}

For people who needs cocoapods solution try ScrollableStackView library. Here is the github page :

https://github.com/gurhub/ScrollableStackView

Here is some sample codes :

Swift

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]; 
// ...

Hope it helps someone.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM