How Marquee Text of Label on Swift

how Marquee text of label on swift?

Using a label which can Marquee up its content is really simple.
Just add MarqueeLabel pod in your project.

Swift:

pod 'MarqueeLabel/Swift'

And then select the label you wish to perform Marquee on and add the Custom Class MarqueeLabel to it in the Identity Inspector.

That's it.

This is the Simplest way to add marquee in your Label. After adding Custom Class MarqueeLabel if you want some spacing in between the last character and the first character of the content of your label then:

Step 1: Select the label.

Step 2: Go to Attributes Inspector and then increase the fadeLength attribute value the much you want to have. Applying value 10 to it is fair enough.

If you wish to customize more then Add custom class MarqueeLabel to the Label and then take the outlet of that Label in you Code and customize it the way you want to.

The outlet of that Label in your code should look like this:

@IBOutlet var YOURLABELNAME: MarqueeLabel!

If not so then start over by first adding the custom class to the label and then taking its outlet in the code file.

how to implement marquee label in IOS using swift

For creating marquee in swift Add Below Class in your Project https://github.com/cbpowell/MarqueeLabel

To do this first add the pod: pod 'MarqueeLabel'.

And perform a pod update in your project.

Then import pod in your working file:
import MarqueeLabel

Create one label and set the custom class as MarqueeLabel in the storyboard.
Then:

@IBOutlet weak var marqueeLabel:MarqueeLabel!

In ViewDidLoad add this:

marqueeLabel.type = .Continuous
marqueeLabel.scrollDuration = 5.0
marqueeLabel.animationCurve = .EaseInOut
marqueeLabel.fadeLength = 10.0
marqueeLabel.leadingBuffer = 30.0
marqueeLabel.trailingBuffer = 20.0

How to use MarqueeLabel in Swift?

I used this little piece of code for my label to scroll like marquee:

@IBOutlet weak var firstLabel: UILabel! 
override func viewDidLoad() {
super.viewDidLoad()

UIView.animateWithDuration(12.0, delay: 1, options: ([.CurveLinear, .Repeat]), animations: {() -> Void in
self.firstLabel.center = CGPointMake(0 - self.firstLabel.bounds.size.width / 2, self.firstLabel.center.y)
}, completion: { _ in })
}

Yes, it worked.

Swift 3 Marquee Label Notification Before Repeats or At Home Position

You can create new inherited class from MarqueeLabel and override labelReturnedToHome function:

class CustomMarqueLabel : MarqueeLabel {
open var returned : ((Bool)->Void)?
override func labelReturnedToHome(_ finished: Bool) {
super.labelReturnedToHome(finished)
if returned != nil {
returned!(finished)
}
}
}

Then use like this:

let lengthyLabel = CustomMarqueLabel(frame: CGRect(x: 20, y: 40, width: 200, height: 20), duration: 0.5, fadeLength: 10.0)
lengthyLabel.returned = {completed in
//label returned to begining
}

How to make a simple UILabel subclass for marquee/scrolling text effect in swift?

First of, I would keep the variables private if you don't need them to be accessed externally, especially labelText (since you're using the computed property text to be set).

Second, since you're adding labels as subviews, I'd rather use a UIView as container instead of UILabel. The only difference in the storyboard would be to add a View instead of a Label.

Third, if you use this approach, you should not set the frame (of the view) to zero.

Something like that would do:

import UIKit

class LoopLabelView: UIView {

private var labelText : String?
private var rect0: CGRect!
private var rect1: CGRect!
private var labelArray = [UILabel]()
private var isStop = false
private var timeInterval: TimeInterval!
private let leadingBuffer = CGFloat(25.0)
private let loopStartDelay = 2.0

required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}

var text: String? {
didSet {
labelText = text
setup()
}
}

func setup() {
self.backgroundColor = UIColor.yellow
let label = UILabel()
label.text = labelText
label.frame = CGRect.zero

timeInterval = TimeInterval((labelText?.characters.count)! / 5)
let sizeOfText = label.sizeThatFits(CGSize.zero)
let textIsTooLong = sizeOfText.width > frame.size.width ? true : false

rect0 = CGRect(x: leadingBuffer, y: 0, width: sizeOfText.width, height: self.bounds.size.height)
rect1 = CGRect(x: rect0.origin.x + rect0.size.width, y: 0, width: sizeOfText.width, height: self.bounds.size.height)
label.frame = rect0

super.clipsToBounds = true
labelArray.append(label)
self.addSubview(label)

//self.frame = CGRect(origin: self.frame.origin, size: CGSize(width: 0, height: 0))

if textIsTooLong {
let additionalLabel = UILabel(frame: rect1)
additionalLabel.text = labelText
self.addSubview(additionalLabel)

labelArray.append(additionalLabel)

animateLabelText()
}
}

func animateLabelText() {
if(!isStop) {
let labelAtIndex0 = labelArray[0]
let labelAtIndex1 = labelArray[1]

UIView.animate(withDuration: timeInterval, delay: loopStartDelay, options: [.curveLinear], animations: {
labelAtIndex0.frame = CGRect(x: -self.rect0.size.width,y: 0,width: self.rect0.size.width,height: self.rect0.size.height)
labelAtIndex1.frame = CGRect(x: labelAtIndex0.frame.origin.x + labelAtIndex0.frame.size.width,y: 0,width: labelAtIndex1.frame.size.width,height: labelAtIndex1.frame.size.height)
}, completion: { finishied in
labelAtIndex0.frame = self.rect1
labelAtIndex1.frame = self.rect0

self.labelArray[0] = labelAtIndex1
self.labelArray[1] = labelAtIndex0
self.animateLabelText()
})
} else {
self.layer.removeAllAnimations()
}
}
}

I want to put Marquee Label with different label text color

in your cellforrowatindexpath create uilabel and assign your marque label than uilabel's text set to attributed string and than convert uilabel to marque label and than add sub view to your cell.

Hope this will be helpful for you.
Thanks.

SWIFTUI Marquee when text not fit

Try below code....

In MarqueeText.swift

import SwiftUI

struct MarqueeText: View {

@State private var leftMost = false

@State private var w: CGFloat = 0

@State private var previousText: String = ""

@State private var contentViewWidth: CGFloat = 0

@State private var animationDuration: Double = 5

@Binding var text : String

var body: some View {
let baseAnimation = Animation.linear(duration: self.animationDuration)//Animation duration
let repeated = baseAnimation.repeatForever(autoreverses: false)
return VStack(alignment:.center, spacing: 0) {
GeometryReader { geometry in//geometry.size.width will provide container/superView width
Text(self.text).font(.system(size: 24)).lineLimit(1).foregroundColor(.clear).fixedSize(horizontal: true, vertical: false).background(TextGeometry()).onPreferenceChange(WidthPreferenceKey.self, perform: {
self.w = $0
print("textWidth:\(self.w)")
print("geometry:\(geometry.size.width)")
self.contentViewWidth = geometry.size.width
if self.text.count != self.previousText.count && self.contentViewWidth < self.w {
let duration = self.w/50
print("duration:\(duration)")
self.animationDuration = Double(duration)
self.leftMost = true
} else {
self.animationDuration = 0.0
}
self.previousText = self.text
}).fixedSize(horizontal: false, vertical: true)// This Text is temp, will not be displayed in UI. Used to identify the width of the text.
if self.animationDuration > 0.0 {
Text(self.text).font(.system(size: 24)).lineLimit(nil).foregroundColor(.green).fixedSize(horizontal: true, vertical: false).background(TextGeometry()).onPreferenceChange(WidthPreferenceKey.self, perform: { _ in
if self.text.count != self.previousText.count && self.contentViewWidth < self.w {

} else {
self.leftMost = false
}
self.previousText = self.text
}).modifier(self.makeSlidingEffect().ignoredByLayout()).animation(repeated, value: self.leftMost).clipped(antialiased: true).offset(y: -8)//Text with animation
}
else {
Text(self.text).font(.system(size: 24)).lineLimit(1).foregroundColor(.blue).fixedSize(horizontal: true, vertical: false).background(TextGeometry()).fixedSize(horizontal: false, vertical: true).frame(maxWidth: .infinity, alignment: .center).offset(y: -8)//Text without animation
}
}
}.fixedSize(horizontal: false, vertical: true).layoutPriority(1).frame(maxHeight: 50, alignment: .center).clipped()

}

func makeSlidingEffect() -> some GeometryEffect {
return SlidingEffect(
xPosition: self.leftMost ? -self.w : self.w,
yPosition: 0).ignoredByLayout()
}
}

struct MarqueeText_Previews: PreviewProvider {
@State static var myCoolText = "myCoolText"
static var previews: some View {
MarqueeText(text: $myCoolText)
}
}

struct SlidingEffect: GeometryEffect {
var xPosition: CGFloat = 0
var yPosition: CGFloat = 0

var animatableData: CGFloat {
get { return xPosition }
set { xPosition = newValue }
}

func effectValue(size: CGSize) -> ProjectionTransform {
let pt = CGPoint(
x: xPosition,
y: yPosition)
return ProjectionTransform(CGAffineTransform(translationX: pt.x, y: pt.y)).inverted()
}
}

struct TextGeometry: View {
var body: some View {
GeometryReader { geometry in
return Rectangle().fill(Color.clear).preference(key: WidthPreferenceKey.self, value: geometry.size.width)
}
}
}

struct WidthPreferenceKey: PreferenceKey {
static var defaultValue = CGFloat(0)

static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
value = nextValue()
}

typealias Value = CGFloat
}

struct MagicStuff: ViewModifier {
func body(content: Content) -> some View {
Group {
content.alignmentGuide(.underlineLeading) { d in
return d[.leading]
}
}
}
}

extension HorizontalAlignment {
private enum UnderlineLeading: AlignmentID {
static func defaultValue(in d: ViewDimensions) -> CGFloat {
return d[.leading]
}
}
static let underlineLeading = HorizontalAlignment(UnderlineLeading.self)
}

In your existing SwiftUI struct.
(The below sample code will check 3 cases 1.Empty string, 2.Short string that doesn't need to marquee, 3.Lengthy marquee string)

@State var value = ""
@State var counter = 0

var body: some View {
VStack {
Spacer(minLength: 0)
Text("Monday").background(Color.yellow)
HStack {
Spacer()
VStack {
Text("One").background(Color.blue)
}
VStack {
MarqueeText(text: $value).background(Color.red).padding(.horizontal, 8).clipped()
}
VStack {
Text("Two").background(Color.green)
}
Spacer()

}
Text("Tuesday").background(Color.gray)
Spacer(minLength: 0)
Button(action: {
self.counter = self.counter + 1
if (self.counter % 2 == 0) {
self.value = "1Hello World! Hello World! Hello World! Hello World! Hello World!"
} else {
self.value = "1Hello World! Hello"
}
}) {
Text("Button")
}
Spacer()
}
}


Related Topics



Leave a reply



Submit