以编程方式将UIScrollView滚动到Swift中的子UIView(子视图)的顶部

时间:2016-08-18 12:16:56

标签: ios swift uiscrollview

我的UIScrollView中有几个屏幕内容,只能垂直滚动。

我想以编程方式滚动到包含在其层次结构中的某个视图。

UIScrollView移动,以便子视图位于UIScrollView的顶部(动画与否)

11 个答案:

答案 0 :(得分:72)

这是我最后写的扩展名。

用法:

从我的viewController调用,self.scrollView是UIScrollView的出口,self.commentsHeader是其中的一个视图,靠近底部:

self.scrollView.scrollToView(self.commentsHeader, animated: true)

<强>代码:

您只需要 scrollToView 方法,但也可以使用 scrollToBottom / scrollToTop 方法,因为您可能也需要这些方法,但感觉可以自由删除它们。

extension UIScrollView {

    // Scroll to a specific view so that it's top is at the top our scrollview
    func scrollToView(view:UIView, animated: Bool) {
        if let origin = view.superview {
            // Get the Y position of your child view
            let childStartPoint = origin.convertPoint(view.frame.origin, toView: self)
            // Scroll to a rectangle starting at the Y of your subview, with a height of the scrollview
            self.scrollRectToVisible(CGRect(x:0, y:childStartPoint.y,width: 1,height: self.frame.height), animated: animated)
        }
    }

    // Bonus: Scroll to top
    func scrollToTop(animated: Bool) {
        let topOffset = CGPoint(x: 0, y: -contentInset.top)
        setContentOffset(topOffset, animated: animated)
    }

    // Bonus: Scroll to bottom
    func scrollToBottom() {
        let bottomOffset = CGPoint(x: 0, y: contentSize.height - bounds.size.height + contentInset.bottom)
        if(bottomOffset.y > 0) {
            setContentOffset(bottomOffset, animated: true)
        }
    }

}

答案 1 :(得分:5)

 scrollView.scrollRectToVisible(CGRect(x: x, y: y, width: 1, height:
1), animated: true)

scrollView.setContentOffset(CGPoint(x: x, y: y), animated: true)

另一种方式是

scrollView.contentOffset = CGPointMake(x,y);

我用动画这样做

[UIView animateWithDuration:2.0f delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
scrollView.contentOffset = CGPointMake(x, y); }
completion:NULL];

答案 2 :(得分:4)

scrollView.setContentOffset(CGPoint, animated: Bool)

点y坐标是视图框架的y坐标,您希望相对于scrollView的内容视图显示

答案 3 :(得分:2)

对我来说,事情是导航栏,它与scrollView内容的一小部分重叠。所以我做了两件事:

  • 大小检查器-滚动视图-内容插入->从“自动”更改为“从不”。
  • 尺寸检查器-约束-“顶部对齐至”(顶部对齐约束)-第二项-> 从Superview.Top更改为安全区域。Top值(常数字段) )设置为0

Content insets - Never Align ScrolView.Top to Safe Area.Top

答案 4 :(得分:2)

dyson's answer更新为与for each word in fileLocation Dim noExp As New Regex("([0-9]{8,11})") Dim m As Match = noExp.Match(word) If Not m.Success Then Throw New Exception("No sequence number found") Dim c = m.Groups(1).Captures(0) Msgbox(c.value) next 的{​​{1}}相似,因为这是我的用例:

UITableView

答案 5 :(得分:1)

这是我的答案,这很快。这将无限滚动滚动视图中的页面。

private func startBannerSlideShow()
{
UIView.animate(withDuration: 6, delay: 0.1, options: .allowUserInteraction, animations: {
    scrollviewOutlt.contentOffset.x = (scrollviewOutlt.contentOffset.x == scrollviewOutlt.bounds.width*2) ? 0 : scrollviewOutlt.contentOffset.x+scrollviewOutlt.bounds.width
}, completion: { (status) in
    self.startBannerSlideShow()
})
}

答案 6 :(得分:0)

完成动画时滚动到顶部或底部

// MARK: - UIScrollView extensions

extension UIScrollView {
    /// Animate scroll to bottom with completion
    ///
    /// - Parameters:
    ///   - duration:   TimeInterval
    ///   - completion: Completion block
    func animateScrollToBottom(withDuration duration:  TimeInterval,
                            completion:             (()->())? = nil) {

        UIView.animate(withDuration: duration, animations: { [weak self] in
            self?.setContentOffset(CGPoint.zero, animated: false)
            }, completion: { finish in
                if finish { completion?() }
        })
    }

    /// Animate scroll to top with completion
    ///
    /// - Parameters:
    ///   - duration:   TimeInterval
    ///   - completion: Completion block
    func animateScrollToBottomTop(withDuration duration:  TimeInterval,
                                  completion:             (()->())? = nil) {
        UIView.animate(withDuration: duration, animations: { [weak self] in
            guard let `self` = self else {
                return
            }
            let desiredOffset = CGPoint(x: 0, y: -self.contentInset.top)
            self.setContentOffset(desiredOffset, animated: false)

            }, completion: { finish in
                if finish { completion?() }
        })
    }
}

答案 7 :(得分:0)

对我来说scrollRectToVisible()不起作用(请参阅here),因此我使用了setContentOffset()并根据AMAN77的答案自己进行了计算:

extension UIScrollView {

    func scrollToView(view:UIView, animated: Bool) {
        if let superview = view.superview {
            let child = superview.convert(view.frame, to: self)
            let visible = CGRect(origin: contentOffset, size: visibleSize)
            let newOffsetY = child.minY < visible.minY ? child.minY : child.maxY > visible.maxY ? child.maxY - visible.height : nil
            if let y = newOffsetY {
                setContentOffset(CGPoint(x:0, y: y), animated: animated)
            }
        }
    }

}

它是用于水平滚动视图的,但是同样的想法也可以垂直应用。

答案 8 :(得分:0)

重要的是要为在那里的任何初学者指出,您需要将故事板上的UIScrollView链接到您的代码中,然后使用扩展名“ .nameoffunction”

例如:

您将UIScrollView导入代码并将其命名为bob。

您有一个扩展脚本,上面写着“ dyson returns”

您现在在代码中编写代码:

“ bob.scrollToTop”

这将扩展功能“ scrollToTop”附加到情节提要中的UIScrollView。

祝你好运,振作起来!

答案 9 :(得分:0)

您可以使用以下方法,对我来说效果很好

func scrollViewToTop( _ someView:UIView)
{

    let targetViewTop = someView.frame.origin.y
    //If you have a complicated hierarchy it is better to 
    // use someView superview (someView.superview?.frame.origin.y) and figure out your view origin
    let viewToTop = targetViewTop - scrollView.contentInset.top
    scrollView.setContentOffset(CGPoint(x: 0, y: viewToTop), animated: true)

}

或者您可以将其作为扩展

 extension UIScrollView
{
       func scrollViewToTop( _ someView:UIView){
    let targetViewTop = someView.frame.origin.y
    let viewToTop = targetViewTop - self.contentInset.top
    self.setContentOffset(CGPoint(x: 0, y: viewToTop), animated: true)

   }
}

这是滚动视图的约束 constraints for the scroll view

一些屏幕截图

屏幕截图2

答案 10 :(得分:0)

swift 5.0 代码

extension UIScrollView {

    // Scroll to a specific view so that it's top is at the top our scrollview
    func scrollToView(view:UIView, animated: Bool) {
        if let origin = view.superview {
            // Get the Y position of your child view
            let childStartPoint = origin.convert(view.frame.origin, to: self)
            // Scroll to a rectangle starting at the Y of your subview, with a height of the scrollview
            self.scrollRectToVisible(CGRect(x:0, y:childStartPoint.y,width: 1,height: self.frame.height), animated: animated)
        }
    }

    // Bonus: Scroll to top
    func scrollToTop(animated: Bool) {
        let topOffset = CGPoint(x: 0, y: -contentInset.top)
        setContentOffset(topOffset, animated: animated)
    }

    // Bonus: Scroll to bottom
    func scrollToBottom() {
        let bottomOffset = CGPoint(x: 0, y: contentSize.height - bounds.size.height + contentInset.bottom)
        if(bottomOffset.y > 0) {
            setContentOffset(bottomOffset, animated: true)
        }
    }

}