【问题标题】:UIScrollView with glitch content on iPhone 11 Pro MaxiPhone 11 Pro Max 上带有故障内容的 UIScrollView
【发布时间】:2020-10-03 22:02:57
【问题描述】:

我是 Swift 新手,我尝试制作显示视图控制器的 UIScrollView

iPhone 11 Pro Max 上的每一件事都很完美,下一个屏幕在侧面显示了一点:

the orange strip is the next screen

我的代码:

//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)
}

感谢您的帮助...

【问题讨论】:

  • 这种方法会有几个问题...但首先,您是否考虑过使用UIPageViewController?它内置了所有这些功能。

标签: ios swift swift3


【解决方案1】:

几个观察:

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

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

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

  4. 当您将视图控制器的 view 添加为子视图时,请确保调用 addChild(_:)didMove(toParent:) 调用视图控制器包含。请参阅view controller documentation 的“实现容器视图控制器”部分。

  5. 如果要添加分页行为,只需设置滚动视图的isPagingEnabled即可。

综合起来:

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

override func viewDidLoad() {
    super.viewDidLoad()

    var anchor = scrollView.contentLayoutGuide.leadingAnchor

    for identifier in viewControllers {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let child = storyboard.instantiateViewController(withIdentifier: identifier)
        addChild(child)                   // containment call
        child.view.translatesAutoresizingMaskIntoConstraints = false
        scrollView.addSubview(child.view)
        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: anchor),
            child.view.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor),
            child.view.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor),
        ])

        anchor = child.view.trailingAnchor
    }
    anchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor).isActive = true
    scrollView.isPagingEnabled = true
}

我已经删除了属性frame,因为它不再需要了(这只是与视图控制器的视图的同名属性混淆的原因)。我还删除了容器视图,因为它并没有为整体解决方案添加太多内容(并且只添加了一层要添加的约束)。

但关键是使用约束来规定滚动视图中子视图的大小和位置,并使用视图控制器包含 API。

【讨论】:

  • 首先非常感谢您的帮助,它解决了问题,但现在有新问题:他缩小了我的视野高度。之前:imgur.com/xJGV1bh 之后:imgur.com/Ia1jyu8 谢谢
  • @LiorD - 看起来你还没有定义滚动视图和它的超级视图之间的垂直约束(例如,滚动视图的底部和它下面的任何东西)。但这与上面的代码无关,它假设您已经定义了滚动视图的高度,并且只担心在滚动视图中配置子视图/页面。
猜你喜欢
  • 2020-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-04
  • 1970-01-01
  • 2018-01-21
相关资源
最近更新 更多