Last active
August 29, 2015 14:27
-
-
Save juliengdt/43205e21df1234042608 to your computer and use it in GitHub Desktop.
Auto-Scroll in Swift, wherever you want, everywhere - not perfect but works like a charm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension UIView { | |
//MARK: - AutoScroll Stuff - | |
private func autoScroll(view: UIView, kbFrame: CGRect, animated: Bool) { | |
let offset = kbFrame.height + 20 | |
let deltaOffset = CGRectGetMinY(view.convertRect(view.bounds, toView: self.view)) - offset | |
autoScrollOffset = deltaOffset < 0 ? 0 : deltaOffset | |
totalAutoScrollOffset = autoScrollOffset | |
if autoScrollOffset > 0 { | |
UIView.animateWithDuration(animated ? 0.3 : 0, animations: { | |
self.view.transform(y: -self.autoScrollOffset) | |
}, completion: { (finished) -> Void in | |
self.autoScrollAnimating = false | |
}) | |
}else { | |
autoScrollAnimating = false | |
} | |
} | |
private func resetAutoScroll(animated: Bool) { | |
if totalAutoScrollOffset > 0 { | |
UIView.animateWithDuration(animated ? 0.3 : 0, animations: { | |
self.view.transform(y: self.autoScrollOffset) | |
}, completion: { (finished) -> Void in | |
self.autoScrollAnimating = false | |
}) | |
}else { | |
autoScrollAnimating = false | |
} | |
totalAutoScrollOffset = 0 | |
} | |
func willautoScrollOffset(notification: NSNotification){ | |
if !inhibitAutoScroll { | |
guard let kbInfo = notification.userInfo else { return } | |
guard let kbFrame = kbInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue else { return } | |
guard let firstRespView = self.view.findFirstResponder() else { return } | |
keyboardFrame = kbFrame.CGRectValue() | |
if !autoScrollAnimating { | |
autoScrollAnimating = true | |
autoScroll(firstRespView, kbFrame: keyboardFrame, animated: true) | |
} | |
} | |
} | |
func willautoScrollReset(notification: NSNotification){ | |
if !inhibitAutoScroll { | |
autoScrollAnimating = true | |
resetAutoScroll(true) | |
} | |
} | |
func findFirstResponder() -> UIView? { | |
if self.isFirstResponder() { | |
return self | |
} | |
for subview in subviews { | |
if let respView = subview.findFirstResponder() { | |
return respView | |
} | |
} | |
return self | |
} | |
func transform(x: CGFloat? = 0, y: CGFloat? = 0, width: CGFloat? = 0, height: CGFloat? = 0){ | |
self.frame = CGRectMake(self.frame.origin.x + x!, self.frame.origin.y + y!, self.frame.width + width!, self.frame.height + height!) | |
} | |
} | |
// Place this into your viewWillAppear() motherBaseViewController: | |
override func viewWillAppear(animated: Bool) { | |
super.viewWillAppear(animated) | |
NSNotificationCenter.defaultCenter().addObserver(self, selector: "willautoScrollOffset:", name: UIKeyboardWillShowNotification, object: nil) | |
NSNotificationCenter.defaultCenter().addObserver(self, selector: "willautoScrollReset:", name: UIKeyboardWillHideNotification, object: nil) | |
} | |
//Place this into your viewWillDisappear motherBaseViewController | |
override func viewWillDisappear(animated: Bool) { | |
super.viewWillDisappear(animated) | |
NSNotificationCenter.defaultCenter().removeObserver(self) | |
} | |
//Why viewWillAppear/Disappear instead of viewDidLoad/deinit ? | |
//because with this method, you avoid glitch-scrolling when you push another view containing a scrollView |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment