user3626615 user3626615 - 1 month ago 7x
iOS Question

View does not stick on top (does not change position)

I am trying to stick the UIView on top while scrolling. Tried using max(x:T, y:T) method as suggested here on stackOverflow but it does not work. I manage to detect when the scrollView should be re-positioned but updating frame does not have any affect.

import UIKit

class ViewController: UIViewController, UIScrollViewDelegate{

@IBOutlet var objectView: UIView!
@IBOutlet var scrollView: UIScrollView!

//var originalOffsetY : CGFloat!
//var originalOffestX : CGFloat!

override func viewDidLoad() {
// Do any additional setup after loading the view, typically from a nib.

let size = CGSize.init(width: self.view.frame.width, height: self.view.frame.height*2)
scrollView.contentSize = size
scrollView.backgroundColor = UIColor.blueColor()
objectView.backgroundColor = UIColor.whiteColor()
scrollView.delegate = self


// override func viewWillAppear(animated: Bool) {
// originalOffsetY = objectView.frame.origin.y
// originalOffestX = objectView.frame.origin.x

// }

func scrollViewDidScroll(scrollView: UIScrollView) {

print("ScrollView \(scrollView.contentOffset.y)")
print("ObjectView \(objectView.frame.origin.y)")

let location = CGPointMake(0, scrollView.contentOffset.y)
let size = objectView.frame.size

if scrollView.contentOffset.y >= objectView.frame.origin.y {
objectView.frame = CGRect.init(origin: location, size: size)
print("Detected \(objectView.frame)")


// var newRect = objectView.frame
// newRect.origin.y = max(originalOffsetY!, scrollView.contentOffset.y)
// objectView.frame = newRect



The condition is matched successfully as can be seen here in Logs . But the view remains unchanged. I require the objectView to scroll a bit.. from around y=270 to 0 .. but not beyond it.


You need to keep track of the original position of the view within the scroll view, and calculate using that value, here's a very simplified example:

class StickyScrollViewController: UIViewController {

    var stickyView = UIView(frame: CGRect(x: 0, y: 100, width: 300, height: 100))
    var originalStickyOrigin: CGPoint = CGPoint(x: 0, y: 100)

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        var nextYOffset = max(originalStickyOrigin.y, scrollView.contentOffset.y)
        stickyView.frame = CGRect(x: 0, y: nextYOffset, width: 300, height: 100)