Detect when a UITextView has finished scrolling - iphone

Is there a way to detect when a UITextView has finished scrolling? As a note, I allow the user to enable or disable paging.
Thanks.

UITextView is a subclass of UIScrollView, which has a UIScrollViewDelegate class for controlling behaviour related to scrolling. One of its methods is scrollViewDidEndDecelerating. You can make your view controller implement this protocol, set your UITextView's delegate property to the view controller, and then implement the scrollViewDidEndDecelerating method. When the method is called, the UITextView will have finished scrolling. e.g.:
in .h:
#interface MyViewController : UIViewController <UIScrollViewDelegate>
in .m:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
NSLog(#"Finished scrolling");
}

In Swift:
class MyViewController: UIViewController, UITextViewDelegate {
weak var textView: UITextView!
override func viewDidLoad() {
self.textView.delegate = self
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
...
}
}
UITextViewDelegate inherits UIScrollViewDelegate

Related

Best way to handle textViewChanged in Swift 5.5

I'm trying to add attributed strings to some text in a UITextView on text change in Swift 5.5
What's the best approach, a UIView or a UIViewController?
Sample code would really help me out as I can't seem to get either approach to work atm.
Thanks
class ViewController: UIViewController, UITextViewDelegate { //If your class is not conforms to the UITextViewDelegate protocol you will not be able to set it as delegate to UITextView
#IBOutlet weak var bodyText: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
bodyText.delegate = self //Without setting the delegate you won't be able to track UITextView events
}
func textViewDidChange(_ textView: UITextView) { //Handle the text changes here
print(textView.text); //the textView parameter is the textView where text was changed
}
}
#Rob Hope this boilerplate works for you :)

scrollViewDidScroll not called in a CollectionView with custom layout

I want to load more data when the user reaches the end of my CollectionView. Unfortunately, scrollViewDidScroll is never called.
For my CollectionView, I use a custom layout and I think the problem could be at this:
if let layout = exploreCollectionView.collectionViewLayout as? CustomLayout {
layout.delegate = self
}
My class:
class MainViewController: UIViewController, UIScrollViewDelegate { .....
I want to check if the function scrollViewDidScroll works:
// Check if a user wants to load more data at the bottom
func scrollViewDidScroll(_ scrollView: UIScrollView) {
print("scrolled")
}
How do I implement the scrollViewDidScroll in my CustomLayout?
scrollViewDidScroll is a UIScrollViewDelegate method. So you need to make self (MyViewController) a delegate of the collectionview:
exploreCollectionView.delegate = self
And then for instance in an extension:
extension MyViewController: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
print("scrolled")
}
}

iCarousel error in xcode 9

I tried to implement iCarousel as per this tutorial: https://medium.com/#arb1nsnmgl/icarousel-walkthrough-swift-3-0-887554155242
but when trying to implement the #protocol it gives me 4 error messages:
Expected '{' in protocol type
Expected an attribute name
Protocol 'iCarouselDataSource' cannot be nested inside another declaration
Protocols do not allow generic parameters; use associated types instead
Currently the code looks like this:
import UIKit
class ViewController: UIViewController {
#IBOutlet var carouselView: iCarousel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//Testing
#protocol iCarouselDataSource <NSObject>
-(NSInteger)numberOfItemsInCarousel:(iCarousel *)carousel;
-(UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSInteger)index reusingView:(nullable UIView *)view;
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
You are adding it at wrong place so remove
#protocol iCarouselDataSource <NSObject>
-(NSInteger)numberOfItemsInCarousel:(iCarousel *)carousel;
-(UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSInteger)index reusingView:(nullable UIView *)view;
From viewDidLoad method.
Above methods are delegate methods. And you need to add it as shown in tutorial.
Check point 11 for that.
Also confirm the delegates as shown in point number 8.

My scrollViewDidScroll function is not receiving calls

I'm trying to check if a user is scrolling up and down on my app but it's not calling my scrollViewDidScroll method
Any ideas why it's not printing received scroll when I scroll up and down on the app?
import UIKit
class CreateAccount: UIViewController, UITextFieldDelegate, UIScrollViewDelegate {
#IBOutlet weak var scrollViewer: UIScrollView!
#IBOutlet weak var usernameTextField: UITextField!
#IBOutlet weak var emailTextField: UITextField!
#IBOutlet weak var passwordTextField: UITextField!
#IBOutlet weak var reenterPasswordTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func scrollViewDidScroll(scrollView: UIScrollView) {
print("received scroll")
}
}
Add the scrollview delegate. Whenever you implement a delegate method you need tell it what controller to use, usually it will be self. It's caught me out a few times.
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
scrollViewer.delegate = self
}
You need to set delegate of scrollview also don't use tag to differentiate 2 scrollview instead of that create 2 outlets of scrollview and use that in UIScrollViewDelegate methods like this.
func scrollViewDidScroll(scrollView: UIScrollView) {
if scrollView == scrollView1 {
print("received scrollview 1")
}
else if scrollView == scrollView2 {
print("received scrollview 2")
}
}
Delegate are given properly even if your scrollview delegate method not calling then please check you delegate method which you have added for scrollview, this may give warning due to using old swift version scrollview delegate with swift 4.0
Please correct it with below if this is the case:
Old Method:
func scrollViewDidScroll(scrollView: UIScrollView) {
}
New Method:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
}
You can set the .delegate = self as Sarcoma suggests, or:
CTRL drag from scrollView in storyboard onto the File Owner (it is located in the view hierarchy list, actually it is right by the yellow circle icon by the name of your controller: [O] Create Account and choose
delegate

TransitioningDelegate doesn't work for UIPresentationController when separated to a custom class inherited from NSObject

I use custom UIPresentationController to perform sequel with my own animation. In prepareForSegue:
myDestinationController.transitioningDelegate = DBViewControllerTransitioningDelegate()
myDestinationController.modalPresentationStyle = .Custom
This is mine DBViewControllerTransitioningDelegate:
class DBViewControllerTransitioningDelegate: NSObject, UIViewControllerTransitioningDelegate {
func presentationControllerForPresentedViewController(presented: UIViewController, presentingViewController presenting: UIViewController, sourceViewController source: UIViewController) -> UIPresentationController? {
return DBOverlayPresentationController(presentedViewController: presented, presentingViewController: presenting)
}
func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return DBTransitioningAnimator()
}
}
It is not working, because the methods are not called. But when I set:
myDestinationController.transitioningDelegate = self
and within my self controller add 2 methods from my DBViewControllerTransitioningDelegate everything is fine. These two methods are called. Why? What is the difference?
Declaration for transitioningDelegate in UIViewController:
weak var transitioningDelegate: UIViewControllerTransitioningDelegate?
As you can see transitioningDelegate holding a weak reference. The custom TransitioningDelegate instance got released right after you created it since no one have the ownership here. When you adopt the delegate in the "controller" and assign it to transitioningDelegate 'someone' is keeping this delegate instance for you.