Swift UIScrollView 在没有 pagingEnabled 的情况下捕捉到子视图宽度

Posted

技术标签:

【中文标题】Swift UIScrollView 在没有 pagingEnabled 的情况下捕捉到子视图宽度【英文标题】:Swift UIScrollView snap to subview width without pagingEnabled 【发布时间】:2015-12-14 12:39:13 【问题描述】:

当滑动对齐到其子视图宽度时,我如何实现UIScrollView。我需要它表现得像pagingEnabled,但我不能启用分页,因为我需要我的整个视图可以滑动来滚动。如果我这样做pagingEnable 这是不可能的,因为滚动视图边界将更改为子视图宽度。

有没有办法做到这一点。 please check the image for more details

import UIKit

class ViewController: UIViewController

  var navigationScroller: UIScrollView!
  var contentScroller: UIScrollView!
  var navContainer: UIView!
  var contentContainer: UIView!
  var selfWidth:CGFloat?
  var navigationLabels = ["EVENTS", "MEMBERS", "SECTORS", "ORGANIZATIONS", "SEARCH", "EVENTS", "MEMBERS"]
 private var buttonsTextFontAndSize: UIFont = UIFont(name:     "HelveticaNeue-Light", size: 14)!
override func viewDidLoad() 

    super.viewDidLoad()
    selfWidth = self.view.frame.width
    let frameWidth = self.view.frame.width
    let frameHeight = self.view.frame.height
    //let navscrollPosition = CGFloat( (frameWidth/2) - (75.0/2) )


    navContainer = UIView(frame: CGRectMake(0.0, 75.0, frameWidth, 40.0))
    navContainer.backgroundColor = UIColor(red:0,  green:0.302,  blue:0.522, alpha:1)



    navigationScroller = UIScrollView(frame: CGRectMake(0.0, 0.0, frameWidth, 40.0))
    navigationScroller.backgroundColor = UIColor.clearColor()
    navigationScroller.pagingEnabled = false
    navigationScroller.showsHorizontalScrollIndicator = false
    navigationScroller.showsVerticalScrollIndicator = false
    navigationScroller.clipsToBounds = false
    navigationScroller.contentInset = UIEdgeInsetsZero
    //navigationScroller.userInteractionEnabled = false
    //navigationScroller.

    addNavigationLabels(navigationScroller)
    self.view.addSubview(navContainer)
    navContainer.addSubview(navigationScroller)
    navigationScroller.contentSize = CGSize(width: 150.0 * CGFloat(navigationLabels.count),height: 40.0)
    navigationScroller.contentOffset = CGPoint(x: 170.0, y:0.0)


    contentContainer = UIView(frame: CGRectMake(0.0, 115.0, frameWidth, frameHeight-115.0))
    contentContainer.backgroundColor = UIColor.clearColor()

    contentScroller = UIScrollView(frame: CGRectMake(0.0, 0.0, frameWidth, frameHeight-115.0))
    contentScroller.backgroundColor = UIColor.clearColor()
    contentScroller.pagingEnabled = true
    contentScroller.showsHorizontalScrollIndicator = false
    contentScroller.showsVerticalScrollIndicator = false
    contentScroller.clipsToBounds = true
    contentScroller.contentInset = UIEdgeInsetsZero
    //contentScroller.addSubview(navContainer)
    addContents(contentScroller)
    self.view.addSubview(contentContainer)
    contentContainer.addSubview(contentScroller)
    contentScroller.contentSize = CGSize(width: frameWidth * CGFloat(navigationLabels.count),
        height: frameHeight-115.0)
    //contentScroller.delegate = self
    navigationScroller.delegate = self





//MARK: -View Appeared function
override func viewDidAppear(animated: Bool) 
    super.viewDidAppear(true)


override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()


// MARK: -Adding navigation labels fron navigation labels array
private func addNavigationLabels(navScrollView:UIScrollView)
    var buttonsXPosition: CGFloat = 0
    var buttonNumber = 0

    for navLabel in navigationLabels 
        var navButton: UIButton!
        let red = CGFloat(buttonNumber) - 0.9
        let frameWidth = self.view.frame.width
        navButton = UIButton(frame: CGRectMake(buttonsXPosition, 0, frameWidth/3, 40.0))
        navButton.titleLabel!.font = buttonsTextFontAndSize
        navButton.contentHorizontalAlignment = .Center

        navButton.backgroundColor = UIColor(red:red  ,  green:0.114,  blue:0.286, alpha:1)
        navButton.setTitle(navLabel, forState: UIControlState.Normal)
        navButton.addTarget(self, action: "buttonAction:", forControlEvents: UIControlEvents.TouchUpInside)
        navScrollView.addSubview(navButton)

        buttonsXPosition = frameWidth/3 + buttonsXPosition
        buttonNumber++
    


func buttonAction(sender:UIButton!)
    print("pressed")


// MARK: -Adding navigation labels fron navigation labels array
private func addContents(contentScroller:UIScrollView)
    var buttonsXPosition: CGFloat = 0
    var buttonNumber = 0
    let frameWidth = self.view.frame.width
    let frameHeight = self.view.frame.height
    for navLabel in navigationLabels 
        var navButton: UIButton!
        navButton = UIButton(frame: CGRectMake(buttonsXPosition, 40.0, frameWidth, frameHeight-155))
        navButton.titleLabel!.font = buttonsTextFontAndSize
        navButton.contentHorizontalAlignment = .Center
        navButton.backgroundColor = UIColor.darkGrayColor()
        navButton.setTitle(navLabel, forState: UIControlState.Normal)
        contentScroller.addSubview(navButton)
        buttonsXPosition = frameWidth + buttonsXPosition
        buttonNumber++

    
     

app view

【问题讨论】:

【参考方案1】:

您可以实现UIScrollViewDelegate的方法scrollViewWillEndDragging:withVelocity:targetContentOffset:并修改偏移量,它将完成减速以匹配您希望的宽度。

类似这样的:

class ScrollSample: NSObject, UIScrollViewDelegate 
    func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) 

        let targetOffset = targetContentOffset.memory.x
        // Round the offset to be a multiple of scrollview width
        let roundedOffset = round(targetOffset / scrollView.frame.width) * scrollView.frame.width
        targetContentOffset.memory = CGPoint(x: roundedOffset, y: 0)
    

【讨论】:

谢谢,如果您能发布代码示例,那就太好了。

以上是关于Swift UIScrollView 在没有 pagingEnabled 的情况下捕捉到子视图宽度的主要内容,如果未能解决你的问题,请参考以下文章

swift-无法使用 AutoLayout 在 UIScrollView 中居中 UIImageView

我的带有自动布局约束的 Swift 4 UIScrollView 没有滚动

在 Swift 中以编程方式创建垂直 UIScrollView

Swift如何获得UIScrollView动态高度

Swift AutoLayout:UIScrollView 内的 UITextViews 让人头疼

Twitter个人资料页面iOS Swift剖析(UIScrollView中的多个UITableViews)