loop reseting in scrollview (swift3) - ios

My code is a uiscrolview with two pages and a button. The problem is that if I am on the view controller info (middle image). Then hit the button to go back to scrollview it goes back to page 1. So no matter what going from the info slide to the scrollview it always goes back to view controller 1 and the loop resets. If I am on vc 2 hit the info button go to the info slide.If I hit the button on the info slide I want to return to vc 2. My code is below. Essentially the loop always resets I want to fix that if possible.
import UIKit
class ViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet var pageControl: UIPageControl!
#IBOutlet var slideScrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
slideScrollView.delegate = self
let slides:[slide] = createSlides()
setupSlideScrollView(slides: slides)
pageControl.numberOfPages = slides.count
pageControl.currentPage = 0
view.bringSubview(toFront: pageControl)
}
override var prefersStatusBarHidden: Bool {
return true
}
func createSlides() -> [slide]{
let slide1:slide = Bundle.main.loadNibNamed("slide", owner: self, options: nil)?.first as! slide
slide1.label.text = "1"
let slide2:slide = Bundle.main.loadNibNamed("slide", owner: self, options: nil)?.first as! slide
slide2.label.text = "2"
return [slide1,slide2 ]
}
func setupSlideScrollView(slides:[slide]) {
slideScrollView.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height)
slideScrollView.contentSize = CGSize(width: view.frame.width * CGFloat(slides.count), height: view.frame.height)
for i in 0..<slides.count{
slides[i].frame = CGRect(x: view.frame.width * CGFloat(i), y: 0, width: view.frame.width, height: view.frame.height)
slideScrollView.addSubview(slides[i])
slideScrollView.isPagingEnabled = true
}
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let pageIndex = round(scrollView.contentOffset.x/view.frame.width)
pageControl.currentPage = Int(pageIndex)
}}

This sounds like a ViewWillAppear or ViewWillAppear problem , check if you are setting anything in those functions.

Related

Swift: Changing (translate) a UIView position through a pan gesture in its superview window

Introduction
Context:
In my main ViewController I have a scrollView with a few objects inside (which are UIViews). When one of the UIViews are tapped/selected I animate forward a UITextView in a UIView to go with the selected object. (only one UIView can appear at a time)
This UIView that appears on object selection is separated into a separate class called AdjunctiveTextView.
Issue/goal:
(the example code provided below will clear make this clear, I've also commented where the issue lies in the code)
When an object has been tapped and has an adjacent UIView with a text I want to have that adjacent UIView to follow with the scrollView.
I'm using a UIPanGestureRecognizer to attempt to do this. But I can't figure out how to make it work when the user drags in the scrollview. It only work if the user drags on the actual adjunctiveTextView.
Everything works as expected except that the adjunctiveTextView does not change its position during the panGesture.
I would like (if possible) to have the AdjunctiveTextView as a separate class. My ViewController file is getting rather big.
Question:
Why doesn't the UIPanGestureRecognizer work as expected? What is needed in order for it to translate the backView correctly?
Code
My attempt: (as shown below)
My attempt simply makes the backView itself "dragable" around through the panGesture. Nothing happens to it when I scroll the scrollView.
(I have only included relevant portions of my code)
class ViewController: UIViewController {
let adjunctiveTextView = AdjunctiveTextView()
// this is a delegate method which gets called when an object is tapped in the scrollView
func scrollViewObjectIsTapped(_ objectScrollView: ObjectScrollView, object: AvailableObject) {
** adjunctiveTextView.scrollView = scrollView // **Edited! (scrollView is the name of the scrollView in this class too)
adjunctiveTextView.showView(passInObject: AvailableObject)
}
}
class AdjunctiveTextView: NSObject {
lazy var backView: UIView = {
//backView setup
}
lazy var textView: UITextView = {
//textView setup
}
//additional init and setup
** weak var scrollView : UIScrollView! // **Edited!
func showView(passInObject: AvailableObject) {
if let window = UIApplication.shared.keyWindow {
// the issue must either be here in the PanGesture setup
let panG = UIPanGestureRecognizer(target: self, action: #selector(translateView(sender:)))
panG.cancelsTouchesInView = false
// window.addGestureRecognizer(panG)
** scrollView.addGestureRecognizer(panG) // **Edited!
window.addSubview(backView)
textView.text = passInObject.information
backView.frame = CGRect(x: passInObject.frame.minX, y: passInObject.minY, width: window.frame.width - passInObject.maxX - 6, height: textView.bounds.height + 5)
backView.alpha = 0
//it animates a change of the backViews x position and alpha.
UIView.animate(withDuration: 0.42, delay: 0, options: .curveEaseInOut, animations: {
self.backView.alpha = 1
self.backView.frame = CGRect(x: passInObject.frame.minX + passInObject.frame.width, y: passInObject.minY, width: window.frame.width - passInObject.maxX - 6, height: textView.bounds.height + 5)
}, completion: nil)
}
}
// or the issue is here in the handle function for the PanGesture.
#objc private func translateView(sender: UIPanGestureRecognizer) {
if let window = UIApplication.shared.keyWindow {
let translation = sender.translation(in: window) //Have tried setting this to scrollView also
switch sender.state {
case .began, .changed:
backView.center = CGPoint(x: backView.center.x, y: backView.center.y + translation.y)
sender.setTranslation(CGPoint.zero, in: window) //Have tried setting this to sccrollView also
break
case .ended:
break
default:
break
}
}
}
}
Thanks for reading my question.
I just add a weak reference to your scrollView and then add the pan gesture to scrollView. It works as you want. You may consider add another pan gesture to the back view if you want your original behavior.
class AdjunctiveTextView: NSObject {
lazy var backView: UIView = {
//backView setup
return UIView.init()
}()
lazy var textView: UITextView = {
//textView setup
return UITextView.init(frame: CGRect.init(x: 0, y: 0, width: 300, height: 100))
}()
weak var scrollView: UIScrollView!
//additional init and setup
func showView(passInObject: AvailableObject) {
if let window = UIApplication.shared.keyWindow {
// the issue must either be here in the PanGesture setup
let panG = UIPanGestureRecognizer(target: self, action: #selector(translateView(sender:)))
panG.cancelsTouchesInView = false
// passInObject.addGestureRecognizer(panG)
scrollView.addGestureRecognizer(panG)
window.addSubview(backView)
textView.text = passInObject.information
textView.backgroundColor = UIColor.blue
backView.addSubview(textView)
backView.frame = CGRect(x: passInObject.frame.minX, y: passInObject.frame.minY, width: window.frame.width - passInObject.frame.maxX - 6, height: textView.bounds.height + 5)
backView.alpha = 0
//it animates a change of the backViews x position and alpha.
UIView.animate(withDuration: 0.42, delay: 0, options: .curveEaseInOut, animations: {
self.backView.alpha = 1
self.backView.frame = CGRect(x: passInObject.frame.minX + passInObject.frame.width , y: passInObject.frame.minY , width: window.frame.width - passInObject.frame.maxX - 6, height: self.textView.bounds.height + 5)
self.backView.backgroundColor = UIColor.red
}, completion: nil)
}
}
// or the issue is here in the handle function for the PanGesture.
#objc private func translateView(sender: UIPanGestureRecognizer) {
if let window = UIApplication.shared.keyWindow {
let translation = sender.translation(in: window)
switch sender.state {
case .began, .changed:
backView.center = CGPoint(x: backView.center.x, y: backView.center.y + translation.y)
sender.setTranslation(CGPoint.zero, in: window)
break
case .ended:
break
default:
break
}
}
}
}
class ObjectScrollView: UIScrollView{
}
class AvailableObject: UIView{
var information: String!
}
class MySCNViewController: UIViewController {
#IBOutlet weak var oScrollView: ObjectScrollView!
// this is a delegate method which gets called when an object is tapped in the scrollView
func scrollViewObjectIsTapped(_ objectScrollView: ObjectScrollView, object: AvailableObject) {
adjunctiveTextView.showView(passInObject: object)
}
let adjunctiveTextView = AdjunctiveTextView()
let ao = AvailableObject.init(frame: CGRect.init(x: 0, y: 0, width: 200, height: 200))
override func viewDidLoad() {
super.viewDidLoad()
ao.information = "test"
adjunctiveTextView.scrollView = oScrollView
ao.backgroundColor = UIColor.yellow
}
#IBAction func tap(_ sender: Any?){
scrollViewObjectIsTapped(oScrollView, object: ao)}
}

Swift 4 - The background function isn't working

I made this simple game with Swift 4 but it's not working.
Code :
class ViewController: UIViewController {
#IBOutlet weak var TheCharacter: UIImageView!
#IBOutlet weak var rocket1: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
self.rocket1.isHidden = true
if 1 % 1 == 0 {
if 0 == 0{
self.rocket1.isHidden = false
let xPosR = rocket1.frame.origin.x + 500
let yPosR = rocket1.frame.origin.y
let heightCharacterR = rocket1.frame.size.height
let widthCharacterR = rocket1.frame.size.width
UIView.animate(withDuration: 1.75, animations: {
self.rocket1.frame = CGRect(x: xPosR, y: yPosR
, width: widthCharacterR, height: heightCharacterR)
}) { (finished) in
}
self.rocket1.isHidden = true
self.rocket1.frame = CGRect(x: xPosR - 500, y: yPosR, width: widthCharacterR, height: heightCharacterR)
}
}
}
}
I know it's being written badly but the problem is one of the rockets has to move in my screen (from one side to the other) because the condition is always true since 0==0 and 1 % 1 == 0. But it's not moving.
Why?
You are animating the views in viewDidLoad(), that is, before they are visible in the window. Move that code to viewDidAppear(). Then your views are visible and can be animated.
And be sure your views are not using autolayout that constraint the frame. Animating the frame is not a good idea OTOH.

Setting Shape of View Controllers In Swift UIscrollview

I am trying to create a menu that uses scrollviews to swipe between 5 view controllers that are shaped like a T, my problem is that currently my viewcontrollers are shaped like a + sign. I was wondering based on the code below how I could set the left and right view controllers to be aligned to form a T shape instead of a + shape. Just to clarify, the code works as such: The snapcontainerviewcontroller sets up a vertical scrollvew view with three view controllers, top bottom and middle, and then this scrollview view is sandwiched in a horizontal scroll view that contains a left and a right viewcontroller.
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
}
}
}
You're outerScrollViewShouldScroll method is not correct. You're only letting it scroll when the contentOffset is equal to the middleVc. You should change to allow scrolling only when contentOffset.y is equal to topVc's origin.y
Replace
if scrollView.contentOffset.y < middleVc.view.frame.origin.y || scrollView.contentOffset.y > middleVc.view.frame.origin.y {
return false
} else {
return true
}
With this:
return scrollView.contentOffset.y == topVc.view.frame.origin.y

ScrollView and little horizontal bar under menu items?

I have a horizontal bar view under my menu items and whenever I tap one of the menu items it appears under that item. I have named it movingView inside my code. Here is a screenshot:
And under that menu I have a UIScrollView. I have placed 5 views inside that UIScrollView and I am able to swipe between them. Now whenever I swipe, I want that horizontal bar view under my menu item follow my selection. For example when I tap pistol, it moves from rifle to pistol. I want that to happen when I swipe from first page to second inside the UIScrollView.
Please someone help me. It's been 3 days and I couldn't figure out how to do this.
MY CODE:
class TabViewController: UIViewController
{
#IBOutlet var scrollView: UIScrollView!
#IBOutlet var buttons: [UIButton]!
#IBOutlet var backgroundView: UIImageView!
var movingView = UIView()
let screenWidth = UIScreen.main.bounds.width
var rifleViewController: UIViewController!
var pistolViewController: UIViewController!
var shotgunViewController: UIViewController!
var smgsViewController: UIViewController!
var sniperViewController: UIViewController!
override func viewDidLoad()
{
super.viewDidLoad()
let main = UIStoryboard(name: "Main", bundle: nil)
rifleViewController = main.instantiateViewController(withIdentifier: "rifles")
sniperViewController = main.instantiateViewController(withIdentifier: "snipers")
smgsViewController = main.instantiateViewController(withIdentifier: "smgss")
shotgunViewController = main.instantiateViewController(withIdentifier: "shotguns")
pistolViewController = main.instantiateViewController(withIdentifier: "pistols")
self.scrollView.contentSize = CGSize(width: self.view.frame.width * 5, height: self.view.frame.height)
rifleViewController.view.frame = scrollView.bounds
scrollView.addSubview(rifleViewController.view)
pistolViewController.view.frame = scrollView.bounds
pistolViewController.view.frame.origin.x = scrollView.frame.size.width
scrollView.addSubview(pistolViewController.view)
shotgunViewController.view.frame = scrollView.bounds
shotgunViewController.view.frame.origin.x = scrollView.frame.size.width * 2
scrollView.addSubview(shotgunViewController.view)
smgsViewController.view.frame = scrollView.bounds
smgsViewController.view.frame.origin.x = scrollView.frame.size.width * 3
scrollView.addSubview(smgsViewController.view)
sniperViewController.view.frame = scrollView.bounds
sniperViewController.view.frame.origin.x = scrollView.frame.size.width * 4
scrollView.addSubview(sniperViewController.view)
movingView = UIView(frame: CGRect(x: 0, y: backgroundView.frame.maxY - 5, width: screenWidth / 5, height: 10))
movingView.backgroundColor = UIColor.white
backgroundView.addSubview(movingView)
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
}
#IBAction func riflePressTab(_ sender: Any)
{
scrollView.setContentOffset(CGPoint(x: 0, y: 0) , animated: true)
}
#IBAction func pistolPressTab(_ sender: Any)
{
scrollView.setContentOffset(CGPoint(x: scrollView.frame.size.width, y: 0) , animated: true)
}
#IBAction func shotgunPressTab(_ sender: Any)
{
scrollView.setContentOffset(CGPoint(x: scrollView.frame.size.width * 2, y: 0) , animated: true)
}
#IBAction func smgsPressTab(_ sender: Any)
{
scrollView.setContentOffset(CGPoint(x: scrollView.frame.size.width * 3, y: 0) , animated: true)
}
#IBAction func sniperPressTab(_ sender: Any)
{
scrollView.setContentOffset(CGPoint(x: scrollView.frame.size.width * 4, y: 0) , animated: true)
}
#IBAction func didPressTab(_ sender: UIButton)
{
let newx = sender.frame.origin.x
UIView.animate(withDuration: 0.2)
{
self.movingView.frame.origin.x = newx
}
}
}
I have tried this but when i run my app, nothing happens when i scroll
func scrollViewDidScroll(_ scrollView: UIScrollView) {
//Assuming your views are of full screen width or just change the SCREEN_WIDTH to whatever width your views occupy
//This will give you which index you are on, i.e you are showing the first view or second or third
let newIndex = scrollView.contentOffset.x/UIScreen.main.bounds.size.width;
animateUnderBar(forIndex index:Int(newIndex))
}
func animateUnderBar(forIndex index:Int){
let newx = self.movingView.frame.origin.x + CGFloat(index) * self.movingView.bounds.size.width
UIView.animate(withDuration: 0.2)
{
self.movingView.frame.origin.x = newx
}
}
Make your class conform to the UIScrollViewDelegate and implement the following method-
func scrollViewDidScroll(_ scrollView: UIScrollView) {
//Assuming your views are of full screen width or just change the SCREEN_WIDTH to whatever width your views occupy
//This will give you which index you are on, i.e you are showing the first view or second or third
let newIndex = scrollView.contentOffset.x/UIScreen.main.bounds.size.width;
animateUnderBar(forIndex :Int(newIndex))
}
func animateUnderBar(forIndex index:Int){
let newx = view.frame.origin.x + CGFloat(index) * view.bounds.size.width
UIView.animate(withDuration: 0.2)
{
self.movingView.frame.origin.x = newx
}
}
}
Alternatively
You should use a UICollectionView instead of a UIScrollView as it will automatically handle displaying of views inside of cells without you having to manually set contentOffSet. Moving under bar will also be easier as it will simply be a matter of using the indexPath.item property to move the under bar.

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() {
super.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
scrollView.addSubview(objectView)
}
// 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)
}
}

Resources