带有约束的UIScrollView切断了内容

问题描述 投票:0回答:1

是我的新手,我尝试制作显示viewController的UIScrollView。

在我对情节提要中的UIScrollView进行约束之前,一切都是完美的。

无限制:without constraints 1

without constraints 2

with constraints

我的代码:

//MARK: - outlets

@IBOutlet weak var pageControl: UIPageControl!
@IBOutlet weak var scrollView: UIScrollView!

//MARK: - properties

var viewControllers: [String] = ["ComputerViewController", "AttactViewController", "DefenceViewController", "OfflineViewController"]
var frame = CGRect(x: 0, y: 0, width: 0, height: 0)

//MARK: - life cyrcles
override func viewDidLoad() {
    super.viewDidLoad()


    for index in 0..<viewControllers.count {
        frame.origin.x = scrollView.frame.size.width * CGFloat(index)

        frame.size = scrollView.frame.size


        let view = UIView(frame: frame)

        let storyboard = UIStoryboard(name: "Menu", bundle: nil)
        var controller: UIViewController = storyboard.instantiateViewController(withIdentifier: viewControllers[index]) as UIViewController

        view.addSubview(controller.view)


        self.scrollView.addSubview(view)

    }

    scrollView.contentSize = CGSize(width: scrollView.frame.size.width * CGFloat(viewControllers.count), height: scrollView.frame.size.height)

    scrollView.delegate = self

}

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    var pageNumber = scrollView.contentOffset.x / scrollView.frame.size.width

    pageControl.currentPage = Int(pageNumber)
}

}

感谢您的帮助...

ios swift swift3
1个回答
0
投票

一些观察:

  1. 您应避免引用frame中的viewDidLoad。此时,frame未知。

  2. 您应该完全避免对子视图的大小和位置进行硬编码。以后可能会有多种事件改变视图的大小(例如,旋转,拆分视图多任务处理等)。使用约束。

  3. 具有滚动视图,有两个布局指南,一个用于frame,另一个用于contentSize。因此,请使用frameLayoutGuide设置子视图的大小以及这些子视图相对于contentLayoutGuide的位置。

  4. 当将视图控制器的view添加为子视图时,请确保调用addChild(_:),并且需要didMove(toParent:)调用视图控制器约束

将它们全部拉在一起:

override func viewDidLoad() {
    super.viewDidLoad()
    addChildViews()
}

func addChildViews() {
    // first view’s leading anchor is the scroll view’s leading content anchor
    var leadingAnchor = scrollView.contentLayoutGuide.leadingAnchor

    var child: UIViewController!
    for identifier in viewControllers {
        let container = UIView()
        container.translatesAutoresizingMaskIntoConstraints = false

        let storyboard = UIStoryboard(name: "Menu", bundle: nil)
        child = storyboard.instantiateViewController(withIdentifier: identifier)
        addChild(child)                   // containment call
        child.view.translatesAutoresizingMaskIntoConstraints = false
        container.addSubview(child.view)
        scrollView.addSubview(container)
        child.didMove(toParent: self)     // containment call

        NSLayoutConstraint.activate([
            // define size of child view (relative to `frameLayoutGuide`)

            child.view.widthAnchor.constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor),
            child.view.heightAnchor.constraint(equalTo: scrollView.frameLayoutGuide.heightAnchor),

            // define placement of child view (relative to `contentLayoutGuide`)

            child.view.leadingAnchor.constraint(equalTo: leadingAnchor),
            child.view.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor),
            child.view.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor),
        ])

        // next view’s leading anchor should use this view’s trailing anchor

        leadingAnchor = child.view.trailingAnchor
    }

    // last view’s trailing anchor is scroll view’s trailing content anchor

    child?.view.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor).isActive = true

    scrollView.isPagingEnabled = true
    scrollView.delegate = self
}

[希望您不要介意,但我还重命名了一些变量以使意图更清晰(例如,子视图控制器视图的容器称为container;子视图控制器称为child) 。我还删除了frame属性,因为不再需要该属性(这只是与视图控制器的同名视图属性相混淆的原因。)>

但是关键是不定义

© www.soinside.com 2019 - 2024. All rights reserved.