BLACK FRIDAY SALE: Save 50% on all my Swift books and bundles! >>

NSImage Animation as Tickertape

Forums > macOS

I am setting up an ad ticker to run ad images across a window that is displayed on a second display for an app I have written.

I was able to finally get the NSAnimationContext.runAnimationGroup to do what I need it to do. However, now I am having a couple of issues. First, there are latent lines being left as the image scrolls (transitions) to the new origin. Secondly, the image appears to speed up as it is transitioning, and then slows. The speed appears to be directly related to the duration, which is understandable, but it starts out slow and then speeds up in the middle, then slows down a lot when the image gets to the right side of the window.

My storyboard view is set to 2200x1100.

//  ViewController.swift
//  Image Ticker
//  Created by Thomas Carroll on 5/11/21.

import Cocoa

class ViewController: NSViewController {

    var adFilesArray:Array<String> = []
    var adImageView:Array<NSImageView> = []
    var imageView:NSImageView!
    var currentAd:Int = -1
    var adFinished = false {
        didSet {
            if adFinished {
                // Increment which ad to display
                currentAd += 1
                // If the current ad is the last ad in the array
                if currentAd == adFilesArray.count {
                    // Reset to the first ad in the array
                    currentAd = 0
                // Reset the observed property to true
                adFinished = true
                // Retrigger the showNextAd method

    override func viewDidLoad() {

        // Do any additional setup after loading the view.
        // Load ad file names array and the image views
        do {
            adFilesArray = try FileManager.default.contentsOfDirectory(atPath: "/Users/Shared/Ad Images")
            for i in 0...adFilesArray.count-1 {
                imageView = NSImageView(image: NSImage(byReferencingFile: "/Users/Shared/Ad Images/"+adFilesArray[i])!)
        } catch {
            print("Unable to retrieve images for ads.")
        // Set the adFinished observed property to true to trigger the ads to begin
        adFinished = true

    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.

    func showNextAd() {
        // Load the imageView
        imageView = adImageView[currentAd]
        // Do not set auto resize constraints
        imageView.translatesAutoresizingMaskIntoConstraints = false
        // Set the initial location just off the left side of the screen
        imageView.frame = CGRect(x: -imageView.image!.size.width, y: 200, width: 1100, height: 700)
        // Add the image view as a subview
        // Begin the animation
        NSAnimationContext.runAnimationGroup({ context in
            //What is being animated? I want an imageView to scroll from the left (off screen) to the right (off screen)
            //Indicate the duration of the animation
            context.duration = 15.0
            // Set the x coordinate of the origin (destination) to the screen width)
            let origin = CGPoint(x: 2201, y: 200)
            // Set the origin to where the image will animate (scroll) to
            self.view.subviews[0].animator().frame.origin = origin
        }, completionHandler: {
            // Remove the subview
            self.view.subviews.remove(at: 0)
            // Set the observed property to true to trigger the next ad
            self.adFinished = true
            print("Ad number [\(self.currentAd)] completed")


How can I get the transition to be the same speed throughout, and how do I get rid of the latent lines it is leaving behind?


Save 50% in my Black Friday sale.

SAVE 50% To celebrate Black Friday, all our books and bundles are half price, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.

Save 50% on all our books and bundles!

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

Unknown user

You are not logged in

Log in or create account

Link copied to your pasteboard.