我正在尝试创建一个菜单,使用滚动视图在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
}
}
}
答案 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