2

i am trying to make an app to view txt files in uitextview. So far i got no problems about fetching the data and stuff.

In my app i have 2 uisliders. one to control font size and the other one to control the speed of textviews autoscroll.

My problem is with the second one (slider to control the speed of textviews autoscroll.)

in example if the uislider value is 0 the text is not autoscrolling and if the slider value is bigger than 0 it starts to scroll as fast as it is set. something like:

slider value:0 - 0 autoscroll, slider value:0.25 - 15 px autoscroll and so on...

Is there a way to do this, I have searching and googling but I have no luck.

Ashley Mills
  • 50,474
  • 16
  • 129
  • 160

2 Answers2

2

The auto-scroll speed of a text could simply be achieved using Apple's CADisplayLink API. From your question, I'm assuming you've already created your textView and UISlider UIControls in StoryBoard and correctly connected them as IBOutlets in code already. Not forgetting an IBAction for the same UISlider to respond to user events. You should then head over to the corresponding ViewController and do the following:

class ViewController: UIViewController {

    //MARK: Vars
    private var speed: CGFloat = 0.0
    private var displayLink: CADisplayLink?

    var timer:Timer?

    //IBOutlets
    @IBOutlet weak var scrollSpeedSlider: UISlider!
    @IBOutlet weak var textView: UITextView!

    //MARK: LifeCycle
    override func viewDidLoad() {
        super.viewDidLoad() 

       // Load up initial scrollSpeedSlider value
        speed = CGFloat(scrollSpeedSlider.value)

    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        //Initialize a new display link inside a displayLink variable, providing 'self' 
        //as target object and a selector to be called when the screen is updated. 
        displayLink = CADisplayLink(target: self, selector: #selector(step(displaylink:)))

        // And add the displayLink variable to the current run loop with default mode.
        displayLink?.add(to: .current, forMode: .defaultRunLoopMode)
    }

 //The selector to be called when the screen is updated each time
    @objc func step(displaylink: CADisplayLink) {

        //Variable to capture and store the ever so changing deltatime/time lapsed of  
        //every second after the textview loads onto the screen
        let seconds = displaylink.targetTimestamp - displaylink.timestamp

        //Set the content offset on the textview to start at x position 0, 
        //and to its y position-parameter, pass the slider speed value multiplied by the changing time delta. 
       //This will ensure that the textview automatically scrolls, 
       //and also accounts for value changes as users slider back and forth.
        textView.setContentOffset(CGPoint(x: 0, y: textView.contentOffset.y + speed * CGFloat(seconds) * 100), animated: false)
    }

    // MARK: - IBActions

    @IBAction func scrollSpeedValueChanged(_ sender: UISlider) {

        //Here's where we capture the slider speed value as user slide's back and forth
        speed = CGFloat(sender.value)
    }
}

Hope this helps.

Happy Coding!

Vick Swift
  • 2,945
  • 1
  • 15
  • 17
0

The scroll speed for a UITextView is fixed - there's no parameter to control the rate. However, you can work around this:

  • Get the height of the textView's contentSize (say 500 pt)
  • Divide by the time you want to take to scroll (say 10 seconds, so 50pt/sec, or 1pt every 50th second)
  • Create an NSTimer that fires every 1/50th second and adjusts the contentOffset by 1pt each time

You can adjust the numbers to suit your requirements, of course

Ashley Mills
  • 50,474
  • 16
  • 129
  • 160