【问题标题】:Xcode XIB: how to implement a ScrollView or PageControl to swipe sub-views?Xcode XIB:如何实现 ScrollView 或 PageControl 来滑动子视图?
【发布时间】:2015-04-16 01:50:55
【问题描述】:

我正在构建一个典型的 Xcode 6 iOS 应用程序。

我的目标是:

  • 具有可滑动以更改内容的子区域的屏幕。

  • 例如,主屏幕有一个标志图像、一个我想要滑动的中间区域和一个底部按钮。

  • 当用户滑动(或点击)中间区域时,该区域会显示下一个(或上一个)信息,这是典型的 UIImage 和 UILabel 标题。

  • 屏幕的其余部分保持不变,即没有导航变化。

代码是here。它使用来自 StackOverflow 帖子 here 的建议。

我的问题:我怎样才能更好地实现下面的代码,同时仍然使用 XIB?

我当前的实现确实有效,并且使用了这种方法...

一个典型的 Swift Demo.swift 文件,它是一个 UIViewController,它具有:

  • 页面索引、最小值和最大值
  • PageControl、UIImageView 和 UILabel 的插座
  • 页面控件更改以及图像滑动或点击的操作

一个典型的Demo.xib 文件具有:

  • 整个屏幕的典型 UIViewController
  • 用于可变图像和标题文本的 UIImageView 和 UILabel
  • PageControl 指示用户正在查看的教程页面

我正在寻找更好的方法来实现这一点;我已经阅读了很多 Xcode 教程,但到目前为止,似乎没有一个针对 Xcode 6、XIB 和 Swift 的权威。

以下是我研究过的一些看起来很有希望的实现...

有没有办法在XIB中实现子视图区域?

  • 例如,Xocde 是否可以显示带有矩形区域的 XIB 以用于可变内容?

是否有一种惯用的方式来编写可变内容的代码?

  • 例如,通过使用 ScrollView,可能包含 UIPageViewController?

有没有办法让 PageControl XIB 对象大到足以覆盖整个 UIImageView 和 UILabel,所以我可以跳过让 UIImageView 响应手势。

  • 在我的 Xcode 中,PageControl 似乎有一个不可编辑的高度,始终为 37。

赏金将用于征求专家意见。

【问题讨论】:

    标签: xcode swift uiviewcontroller uiimageview uipageviewcontroller


    【解决方案1】:

    要使 UIPageViewController 可滑动,您应该实现 UIPageViewControllerDataSource 协议并为 pageViewController(pageViewController:viewControllerBeforeViewController) -> UIViewController?...viewControllerAfterViewController) 方法提供视图控制器。

    为显示图像和标签并将它们作为属性的每个页面提供自定义视图控制器,以便您可以从 PageViewController 提供它们。

    我的技巧是创建一个在这些方法中实例化新视图控制器的方法:

    // MARK:- UIPageViewControllerDataSource
    
    extension MyPageViewController: UIPageViewControllerDataSource {
    
      func viewControllerWithIndex(var index: Int) -> UIViewController! {
        let viewController = storyboard?.instantiateViewControllerWithIdentifier("MyViewController") as! MyViewController // This VC has to be in the storyboard, otherwise just use MyVC()
    
        // Adjust the index to be cyclical, not required
        if let count = data?.endIndex {
          if count == 1 && index != 0 { return nil }
          if index < 0 { index += count }
          index %= count
        }
    
        viewController.view.tag = index
        viewController.record = data?[index]
    
        return viewController
      }
    
      func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
        let index = viewController.view?.tag ?? 0
        return viewControllerWithIndex(index + 1)
      }
    
      func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
        let index = viewController.view?.tag ?? 0
        return viewControllerWithIndex(index - 1)
      }
    
      func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
        return countAndSetupPageControl()
      }
    
      func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
        return viewController?.view.tag ?? 0
      }
    }
    

    现在对于“子区域”,您需要实现 ChildViewController。如果您使用情节提要,您只需拖动 Container View 并将 PageViewController 放入嵌入式视图控制器中,否则您需要将 PageViewController.view 添加为子视图并将 frame 设置为中间。

    您可以在apple documentation 中找到更多信息,但基本上您必须调用这些方法:

    addChildViewController(pageViewController)
    view.addSubView(pageViewController.view)
    pageViewController.view.frame = ... // This is your "sub-area"
    pageViewController.didMoveToParentViewController(self)
    

    【讨论】:

    • 谢谢!我特别喜欢根据需要实例化视图控制器的方式。
    【解决方案2】:

    如果您向 PageControl 添加高度约束,您可以将其高度设置为您想要的任何值。

    我认为您当前的实施没有问题。将其更改为使用 PageViewController 将需要更多的工作。

    如果我是你,我会在 pageUpdate 函数中添加一个动画,这样图像就会淡入或滑入...

    只有当您希望能够滚动到下一页时才使用 PageViewController 才有意义(例如在您的手指在屏幕上移动的同时内容移动)。您可以使用启用分页的 PageViewController 或 CollectionView。

    【讨论】:

      猜你喜欢
      • 2015-04-26
      • 1970-01-01
      • 1970-01-01
      • 2013-05-03
      • 2012-05-11
      • 1970-01-01
      • 2012-03-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多