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
For-In Loops Multiple Conditions
Opening Import File for Module 'Swift': Not a Directory
Swiftui - How to Change Text Alignment of Label in Toggle
Swift: Cast Any Object to Int64 = Nil
Swiftui List View Not Updating After Core Data Entity Updated in Another View
Charts Not Plotting in Tableviewcell
Comparing Two Enum Variables Regardless of Their Associated Values
Using "Codable" to Set Property Values Doesn't Work Through Inheritance
Swift 1.2 Not Working with Same Function Name and Different Parameter
How to Use Uiimage(Contentsoffile:String) Method to Load Images from Images.Xcassets Folder
How to Connect Outlets and Actions in Swift/Macos Programaticly
Swift Unsafemutablepointer: Must I Call Deinitialize Before Deallocate
Swift Seems to Be Slower as Objective-C in Loops
How to Use Bit Field with Swift to Store Values with More Than 1 Bit