1

I have a simple UIViewRepresentable of a MarqueeLabel, but it does not work. My guess is that the frame is not correctly set, but I don't know what to pass to the MarqueeLabel initialiser as a frame. Using geometry Reader or some other way to get the Marquee effect is not an option.

struct UILabelView : UIViewRepresentable {
    
    var text: String

    typealias UIViewType = MarqueeLabel

    func makeUIView(context: UIViewRepresentableContext<UILabelView>) -> MarqueeLabel {
        
        let label = MarqueeLabel()
        print(label.frame.size)
        label.text = text
        return label
        
    }
    
    func updateUIView(_ uiView: MarqueeLabel, context: UIViewRepresentableContext<UILabelView>) { }
    
}

I have tried using this to no avail. Also, I have looked at this Question but there is no answer.

The View is used like this:

UILabelView(text: "a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20")

setting .frame(width: 40) on this view does not help.

D. Kee
  • 169
  • 14

1 Answers1

1

It is by-default expanded by intrinsic content to full width, so MarqueeLabel just does not have what to scroll - everything is in frame.

In such cases we need to give ability to parent to shrink internal view to externally available space (by width in this case to screen)

so here is a fix - decrease resistance priority:

func makeUIView(context: UIViewRepresentableContext<UILabelView>) -> MarqueeLabel {

    let label = MarqueeLabel()
    label.text = text
    label.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
    //                                            ^^^^^ << this one !!
    return label

}

demo

Tested with Xcode 13.4 / iOS 15.5

Asperi
  • 228,894
  • 20
  • 464
  • 690