Using ScrollView Programmatically in Swift 3

后端 未结 5 572
执念已碎
执念已碎 2020-11-28 11:00

I have searched other questions and seem to still have some trouble creating my scrollView programmatically with autolayout in swift 3. I am able to get my scrollview to sho

相关标签:
5条回答
  • 2020-11-28 11:32

    Two things.

    1. Add the labels to scroll view, not your view

    You want your label to scroll with scroll view, then you should not add it on your view. When running your code, you can scroll but the fixed label there is pinned to your view, not on your scroll view

    2. Make sure you added your constraints correctly

    Try it on your storyboard about what combination of constraint is enough for a view. At least 4 constraints are needed for a label.

    Bottom line

    Here is a modified version of your code. For constraint I added padding left, padding top, width and height and it works. My code is

    let labelOne: UILabel = {
        let label = UILabel()
        label.text = "Scroll Top"
        label.backgroundColor = .red
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    let labelTwo: UILabel = {
        let label = UILabel()
        label.text = "Scroll Bottom"
        label.backgroundColor = .green
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        let screensize: CGRect = UIScreen.main.bounds
        let screenWidth = screensize.width
        let screenHeight = screensize.height
        var scrollView: UIScrollView!
        scrollView = UIScrollView(frame: CGRect(x: 0, y: 120, width: screenWidth, height: screenHeight))
    
        scrollView.addSubview(labelTwo)
    
        NSLayoutConstraint(item: labelTwo, attribute: .leading, relatedBy: .equal, toItem: scrollView, attribute: .leadingMargin, multiplier: 1, constant: 10).isActive = true
        NSLayoutConstraint(item: labelTwo, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 200).isActive = true
        NSLayoutConstraint(item: labelTwo, attribute: .top, relatedBy: .equal, toItem: scrollView, attribute: .topMargin, multiplier: 1, constant: 10).isActive = true
        NSLayoutConstraint(item: labelTwo, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 30).isActive = true
    
        scrollView.contentSize = CGSize(width: screenWidth, height: 2000)
        view.addSubview(scrollView)
    
    }
    

    And the scroll view looks like this

    0 讨论(0)
  • 2020-11-28 11:37

    It is easy to use constraints to define the scroll content size - so you don't have to do any manual calculations.

    Just remember:

    1. The content elements of your scroll view must have left / top / width / height values. In the case of objects such as labels, they have intrinsic sizes, so you only have to define the left & top.
    2. The content elements of your scroll view also define the bounds of the scrollable area - the contentSize - but they do so with the bottom & right constraints.
    3. Combining those two concepts, you see that you need a "continuous chain" with at least one element defining the top / left / bottom / right extents.

    Here is a simple example, that will run directly in a Playground page:

    import UIKit
    import PlaygroundSupport
    
    class TestViewController : UIViewController {
    
        let labelOne: UILabel = {
            let label = UILabel()
            label.text = "Scroll Top"
            label.backgroundColor = .red
            label.translatesAutoresizingMaskIntoConstraints = false
            return label
        }()
    
        let labelTwo: UILabel = {
            let label = UILabel()
            label.text = "Scroll Bottom"
            label.backgroundColor = .green
            label.translatesAutoresizingMaskIntoConstraints = false
            return label
        }()
    
        let scrollView: UIScrollView = {
            let v = UIScrollView()
            v.translatesAutoresizingMaskIntoConstraints = false
            v.backgroundColor = .cyan
            return v
        }()
    
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // add the scroll view to self.view
            self.view.addSubview(scrollView)
    
            // constrain the scroll view to 8-pts on each side
            scrollView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 8.0).isActive = true
            scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 8.0).isActive = true
            scrollView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -8.0).isActive = true
            scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -8.0).isActive = true
    
            // add labelOne to the scroll view
            scrollView.addSubview(labelOne)
    
            // constrain labelOne to left & top with 16-pts padding
            // this also defines the left & top of the scroll content
            labelOne.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 16.0).isActive = true
            labelOne.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 16.0).isActive = true
    
            // add labelTwo to the scroll view
            scrollView.addSubview(labelTwo)
    
            // constrain labelTwo at 400-pts from the left
            labelTwo.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 400.0).isActive = true
    
            // constrain labelTwo at 1000-pts from the top
            labelTwo.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 1000).isActive = true
    
            // constrain labelTwo to right & bottom with 16-pts padding
            labelTwo.rightAnchor.constraint(equalTo: scrollView.rightAnchor, constant: -16.0).isActive = true
            labelTwo.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: -16.0).isActive = true
    
        }
    
    }
    
    
    let vc = TestViewController()
    vc.view.backgroundColor = .yellow
    PlaygroundPage.current.liveView = vc
    
    0 讨论(0)
  • 2020-11-28 11:47

    Set scrollview images to the wallpaper:

    @IBOutlet var scroll_view_img: UIScrollView!
    
    var itemPhotoList = NSMutableArray()
    
    var button = NSMutableArray()    
    
    @IBOutlet var imageview_big: UIImageView!
    
    override func viewDidLoad() {
    
        super.viewDidLoad()
        itemPhotoList = ["grief-and-loss copy.jpg","aaa.jpg","image_4.jpeg"]        
    
        // button = ["btn1","btn2"]
    
        let width:CGFloat = 100
        let height:CGFloat = 100
        var xposition:CGFloat = 10
        var scroll_contont:CGFloat = 0
    
        for i in 0 ..< itemPhotoList.count
        {
            var button_img = UIButton()
            button_img = UIButton(frame: CGRect(x: xposition, y: 50, width: width, height: height))
            let img = UIImage(named:itemPhotoList[i] as! String)
            button_img.setImage(img, for: .normal)
            scroll_view_img.addSubview(button_img)
            button_img.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
            button_img.tag = i
            view.addSubview(scroll_view_img)
            xposition += width+10
            scroll_contont += width
            scroll_view_img.contentSize = CGSize(width: scroll_contont, height: height)
        }
    }
    
    func buttonAction(sender: UIButton!)
    {
        switch sender.tag {
        case 0:
            imageview_big.image = UIImage(named: "grief-and-loss copy.jpg")
        case 1:
            imageview_big.image = UIImage(named: "aaa.jpg")
        case 2:
            imageview_big.image = UIImage(named: "image_4.jpeg")
        default:
            break
        }
    }
    
    0 讨论(0)
  • 2020-11-28 11:47

    Copy and paste this controller in your project

    class BaseScrollViewController: UIViewController {
    
    lazy var contentViewSize = CGSize(width: self.view.frame.width, height: self.view.frame.height + 100)
    lazy var scrollView: UIScrollView = {
        let view = UIScrollView(frame: .zero)
        view.backgroundColor = .white
        view.frame = self.view.bounds
        view.contentSize = contentViewSize
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()
    lazy var containerView: UIView = {
        let v = UIView()
        v.backgroundColor = .white
        v.frame.size = contentViewSize
        return v
    }()
    
    override func viewDidLoad() {
        view.backgroundColor = .white
        view.addSubview(scrollView)
        scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
    
        scrollView.addSubview(containerView)
        setupContainer(containerView)
        super.viewDidLoad()
        
    }
    
    public func setupContainer(_ container: UIView) {
        
    }
    

    }

    Usage for above code:

    class ClientViewController: BaseScrollViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // do your stuff here
    }
    
    override func setupContainer(_ container: UIView) {
        // add views here
    }
    

    }

    0 讨论(0)
  • 2020-11-28 11:48

    These answers do not work with large titles in the navigation bar. Make sure you have the code below in your viewDidLoad() method of your view controller:

    self.navigationController?.navigationBar.prefersLargeTitles = false
    
    0 讨论(0)
提交回复
热议问题