UISegmentedControl text with multiple lines

2019-04-10 08:49发布

问题:

Is there any possibility to make UISegmentedControl with multiple lines of text in iOs 9+?

So far i've tryed:

  1. Variants from SO topics: This, this and this one
  2. Make an extension:

    extension UISegmentedControl
    {
        func makeMultiline(numberOfLines: Int)
        {
            for segment in self.subviews
            {
                let labels = segment.subviews.filter { $0 is UILabel }  // [AnyObject]
                labels.map { ($0 as UILabel).numberOfLines = numberOfLines }    
            }
        }
    }
    
  3. Inherit from UISegmentedControl and set new class to SegmentedControl in Identity Inspector

    class MultilineSegmentedControl: UISegmentedControl
    {
        override func didMoveToSuperview()
        {
            for segment in subviews
            {
                for subview in segment.subviews
                {
                    if let segmentLabel = subview as? UILabel
                    {
                        segmentLabel.numberOfLines = 2
                    }
                }
            }
        }
    }
    
  4. Set image with text instead of title and change frame of UISegmentedControl in

    viewDidLayoutSubviews()
    

    method. It makes UISegmentedControl height larger, but image keeps it's height as if UISegmentedControl didn't enlarge and on first interaction UISegmentedControl shrinks to it's default height.

回答1:

Maybe it's a bit late but here is my subclass to resolve this problem in swift 3 :

@IBDesignable class MySegmentedControl: UISegmentedControl {

    @IBInspectable var height: CGFloat = 29 {
        didSet {
            let centerSave = center
            frame = CGRect(x: frame.minX, y: frame.minY, width: frame.width, height: height)
            center = centerSave
        }
    }

    @IBInspectable var multilinesMode: Bool = false

    override func layoutSubviews() {
        super.layoutSubviews()
        for segment in self.subviews {
            for subview in segment.subviews {
                if let segmentLabel = subview as? UILabel {
                    segmentLabel.frame = CGRect(x: 0, y: 0, width: segmentLabel.frame.size.width, height: segmentLabel.frame.size.height * 1.6)
                    if (multilinesMode == true)
                    {
                        segmentLabel.numberOfLines = 0
                    }
                    else
                    {
                        segmentLabel.numberOfLines = 1
                    }
                }
            }
        }
    }

}


回答2:

Try out below code, find out all segmentedControl sub UILabel and set numberOfLines.

for segmentViews in segmentedControl.subviews {
    for segmentLabel in segmentViews.subviews {
        if segmentLabel is UILabel {
            (segmentLabel as! UILabel).numberOfLines = 0
        }
    }
}