在Swift UIscrollview

时间:2017-07-09 07:04:45

标签: ios swift uiviewcontroller uiscrollview uikit

我正在尝试创建一个菜单,使用滚动视图在5个视图控制器之间滑动,形状像 T ,我的问题是目前我的viewcontrollers形状像 + sign < / strong>即可。我想知道基于下面的代码我如何设置左右视图控制器对齐以形成T形而不是+形状。为了澄清,代码的工作原理如下:snapcontainerviewcontroller设置一个垂直的scrollvew视图,其中包含三个视图控制器,顶部底部和中间,然后将此scrollview视图夹在包含左右视图控制器的水平滚动视图中。

的AppDelegate:

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool {
    // Override point for customization after application launch.

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let left = storyboard.instantiateViewController(withIdentifier: "left")
    let middle = storyboard.instantiateViewController(withIdentifier: "middle")
    let right = storyboard.instantiateViewController(withIdentifier: "right")
    let top = storyboard.instantiateViewController(withIdentifier: "top")
    let bottom = storyboard.instantiateViewController(withIdentifier: "bottom")

    let snapContainer = SnapContainerViewController.containerViewWith(left,
                                                                      middleVC: middle,
                                                                      rightVC: right,
                                                                      topVC: top,
                                                                        bottomVC: bottom)

    self.window?.rootViewController = snapContainer
    self.window?.makeKeyAndVisible()
    return true
}`

SnapContainerViewController:

class SnapContainerViewController: UIViewController, UIScrollViewDelegate,UIGestureRecognizerDelegate {

var topVc: UIViewController?
var leftVc: UIViewController!
var middleVc: UIViewController!
var rightVc: UIViewController!
var bottomVc: UIViewController?

var directionLockDisabled: Bool!

var horizontalViews = [UIViewController]()
var veritcalViews = [UIViewController]()

var initialContentOffset = CGPoint() // scrollView initial offset
var middleVertScrollVc: VerticalScrollViewController!
var scrollView: UIScrollView!
var delegate: SnapContainerViewControllerDelegate?


let player = MPMusicPlayerController.applicationMusicPlayer()


class func containerViewWith(_ leftVC: UIViewController,
                             middleVC: UIViewController,
                             rightVC: UIViewController,
                             topVC: UIViewController?=nil,
                             bottomVC: UIViewController?=nil,
                             directionLockDisabled: Bool?=false) -> SnapContainerViewController {
    let container = SnapContainerViewController()

    container.directionLockDisabled = directionLockDisabled

    container.topVc = topVC
    container.leftVc = leftVC
    container.middleVc = middleVC
    container.rightVc = rightVC
    container.bottomVc = bottomVC
    return container
}

override func viewDidLoad() {
    super.viewDidLoad()
    setupVerticalScrollView()
    setupHorizontalScrollView()
    scrollView.delaysContentTouches = false
    scrollView.bounces = false
    //scrollView.canCancelContentTouches = false
    scrollView.isPagingEnabled = true



}



func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}

func setupVerticalScrollView() {
    middleVertScrollVc = VerticalScrollViewController.verticalScrollVcWith(topVc: topVc,
                                                                           middleVc: middleVc,
                                                                           bottomVc: bottomVc)
    delegate = middleVertScrollVc
}

func setupHorizontalScrollView() {
    scrollView = UIScrollView()
    scrollView.isPagingEnabled = true
    scrollView.showsHorizontalScrollIndicator = false
    scrollView.bounces = false


    //self.view.bounds.origin.x
    let view = (
        x: CGFloat(0) ,
        y: CGFloat(0),
        width: self.view.bounds.width,
        height: self.view.bounds.height
    )

    scrollView.frame = CGRect(x: view.x,
                              y: view.y,
                              width: view.width,
                              height: view.height
    )

    self.view.addSubview(scrollView)

    let scrollWidth  = 3 * view.width
    let scrollHeight  = view.height
    scrollView.contentSize = CGSize(width: scrollWidth, height: scrollHeight)

    leftVc.view.frame = CGRect(x: 0,
                               y: 0,
                               width: view.width,
                               height: view.height
    )

    middleVertScrollVc.view.frame = CGRect(x: view.width,
                                           y: 0,
                                           width: view.width,
                                           height: view.height
    )

    rightVc.view.frame = CGRect(x: 2 * view.width,
                                y: 0,
                                width: view.width,
                                height: view.height
    )

    addChildViewController(leftVc)
    addChildViewController(middleVertScrollVc)
    addChildViewController(rightVc)

    scrollView.addSubview(leftVc.view)
    scrollView.addSubview(middleVertScrollVc.view)
    scrollView.addSubview(rightVc.view)

    leftVc.didMove(toParentViewController: self)
    middleVertScrollVc.didMove(toParentViewController: self)
    rightVc.didMove(toParentViewController: self)

    scrollView.contentOffset.x = middleVertScrollVc.view.frame.origin.x
    //scrollView.contentOffset.y = (topVc?.view.frame.origin.y)!
    scrollView.delegate = self
}

func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
    self.initialContentOffset = scrollView.contentOffset


}

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    if delegate != nil && !delegate!.outerScrollViewShouldScroll() && !directionLockDisabled {
        let newOffset = CGPoint(x: self.initialContentOffset.x, y: self.initialContentOffset.y)

        // Setting the new offset to the scrollView makes it behave like a proper
        // directional lock, that allows you to scroll in only one direction at any given time
        self.scrollView!.setContentOffset(newOffset, animated:  false)
    }
}

}

VerticalScrollViewController:

class VerticalScrollViewController: UIViewController, SnapContainerViewControllerDelegate {
var topVc: UIViewController!
var middleVc: UIViewController!
var bottomVc: UIViewController!
var scrollView: UIScrollView!

class func verticalScrollVcWith(topVc: UIViewController?=nil, middleVc: UIViewController,bottomVc: UIViewController?=nil) -> VerticalScrollViewController {
    let middleScrollVc = VerticalScrollViewController()

    middleScrollVc.topVc = topVc
    middleScrollVc.middleVc = middleVc
    middleScrollVc.bottomVc = bottomVc

    return middleScrollVc
}

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view:
    setupScrollView()
    scrollView.isPagingEnabled = true
}

func setupScrollView() {
    scrollView = UIScrollView()
    scrollView.isPagingEnabled = true
    scrollView.showsVerticalScrollIndicator = false
    scrollView.bounces = false
    //scrollView.isScrollEnabled = false


    let view = (
        x: CGFloat(0),
        y: CGFloat(0),
        width: self.view.bounds.width,
        height: self.view.bounds.height
    )

    scrollView.frame = CGRect(x: view.x, y: view.y, width: view.width, height: view.height)
    self.view.addSubview(scrollView)

    let scrollWidth: CGFloat  = view.width
    var scrollHeight: CGFloat


        scrollHeight  = 3 * view.height

        topVc.view.frame = CGRect(x: 0, y: 0, width: view.width, height: view.height)
        middleVc.view.frame = CGRect(x: 0, y: view.height, width: view.width, height: view.height)
        bottomVc.view.frame = CGRect(x: 0, y: 2 * view.height, width: view.width, height: view.height)




        addChildViewController(topVc)
        addChildViewController(middleVc)
        addChildViewController(bottomVc)

        scrollView.addSubview(topVc.view)
        scrollView.addSubview(middleVc.view)
        scrollView.addSubview(bottomVc.view)

        topVc.didMove(toParentViewController: self)
        middleVc.didMove(toParentViewController: self)
        bottomVc.didMove(toParentViewController: self)
        print("1st case!")

        //scrollView.contentOffset.y = middleVc.view.frame.origin.y
        scrollView.contentOffset.y = topVc.view.frame.origin.y




    scrollView.contentSize = CGSize(width: scrollWidth, height: scrollHeight)
    scrollView.delaysContentTouches = false
    //scrollView.canCancelContentTouches = false
}

// MARK: - SnapContainerViewControllerDelegate Methods
/**

 */
func outerScrollViewShouldScroll() -> Bool {

    if scrollView.contentOffset.y < middleVc.view.frame.origin.y || scrollView.contentOffset.y > middleVc.view.frame.origin.y {
        return false
    } else {
        return true
    }

}

}

1 个答案:

答案 0 :(得分:0)

您的outerScrollViewShouldScroll方法不正确。当contentOffset等于middleVc时,您只能让它滚动。只有在contentOffset.y等于topVc的origin.y

时才应更改为允许滚动

替换

if scrollView.contentOffset.y < middleVc.view.frame.origin.y || scrollView.contentOffset.y > middleVc.view.frame.origin.y {
    return false
} else {
    return true
}

有了这个:

return scrollView.contentOffset.y == topVc.view.frame.origin.y