Scroll dynamic UISegmentedControl in Swift 3
Asked Answered
N

3

6

Hi i want to create a dynamic UISegmented View with more than 20 Items. I tried it, but the output is like this.

enter image description here

the text is sliced not visible fully. I want it to scroll to the left and right and also display the full text. can some one help me to fix this. tnx

View Controller

override func viewDidLoad() {
    super.viewDidLoad()

    let items = ["All Fruits", "Orange", "Grapes", "Banana",  "Mango", "papaya", "coconut", "django"]
    let filtersSegment = UISegmentedControl(items: items)
    filtersSegment.frame = CGRect.init(x: 10, y: 60, width: 300, height: 50)
    filtersSegment.selectedSegmentIndex = 0
    filtersSegment.tintColor = UIColor.black
    filtersSegment.addTarget(self, action: #selector(self.filterApply), for: UIControlEvents.valueChanged)
    self.view.addSubview(filtersSegment)
}

@objc private func filterApply(segment:UISegmentedControl) -> Void {
    print("Selected Index : \(segment.selectedSegmentIndex)")
}
Nanci answered 2/10, 2017 at 4:36 Comment(4)
Use scrollview. Add your segment controller into scrollview.Heelandtoe
Use something other than a segmented control. Perhaps a picker view.Degroot
Embed your segment control in a scrollView. Also limit the segment control to show 3,4 visible text by setting its frame.Recha
Probably, it is not a good user experience to let a segmented control to contains 20 items, you might need to choose another appropriate view for it, such as a picker view or a table view...Kava
T
2

It's better to use another controller rather then segment controller to achieve your goal.

But If you are going with segment controller only then you must add segment controller to scroll view, because titles are dynamic so we can't recognise hows it's wide that's why.

First add segment controller to scroll view. and segment controller has method name setWidth(_ width: CGFloat, forSegmentAt segment: Int) to set width of each segment at index.

so here I'm writing my logic .

    var scrollViewWidth:Float = 0.0
    let items  = ["All Fruits", "Orange", "Grapes", "Banana",  "Mango", "papaya", "coconut", "django"]
    for (index, element) in items.enumerated() {
        let size = element.size(attributes: [NSFontAttributeName: UIFont.systemFont(ofSize: 20.0)]) //you can change font as you want
        segmentCon.setWidth(size.width, forSegmentAt: index)
        scrollViewWidth = scrollViewWidth + Float(size.width)
    }

    // Here you can set content width of UIScollView by use of "scrollViewWidth"
    // scrollView.contentSize = CGSize(width: scrollViewWidth, height: 40)// height should whatever you want.
Tram answered 2/10, 2017 at 5:47 Comment(1)
tried your solution, it's fine for the big number of segments (~ >8), but how to manage the width, if I have only 2-3 segments, in this case, it shrinks the width and shifts all segments to the extreme left of the segmentView.Bombast
L
4

You can try like

[[UILabel appearanceWhenContainedIn:[UISegmentedControl class], nil] setNumberOfLines:0];

segment.apportionsSegmentWidthsByContent = YES;

Swift :

Something like,

   UILabel.appearance(whenContainedInInstancesOf: [UISegmentedControl.self]).numberOfLines = 0
   segment.apportionsSegmentWidthsByContent = true

and you can take your segmented control in scrollview. But with UISegmentedControl you should not use more than four or five segment. It's main purpose is to show three or four options! You should try different mechanism to achieve your goal!

You should refer this post also if it can help!

Lucid answered 2/10, 2017 at 5:49 Comment(0)
T
2

It's better to use another controller rather then segment controller to achieve your goal.

But If you are going with segment controller only then you must add segment controller to scroll view, because titles are dynamic so we can't recognise hows it's wide that's why.

First add segment controller to scroll view. and segment controller has method name setWidth(_ width: CGFloat, forSegmentAt segment: Int) to set width of each segment at index.

so here I'm writing my logic .

    var scrollViewWidth:Float = 0.0
    let items  = ["All Fruits", "Orange", "Grapes", "Banana",  "Mango", "papaya", "coconut", "django"]
    for (index, element) in items.enumerated() {
        let size = element.size(attributes: [NSFontAttributeName: UIFont.systemFont(ofSize: 20.0)]) //you can change font as you want
        segmentCon.setWidth(size.width, forSegmentAt: index)
        scrollViewWidth = scrollViewWidth + Float(size.width)
    }

    // Here you can set content width of UIScollView by use of "scrollViewWidth"
    // scrollView.contentSize = CGSize(width: scrollViewWidth, height: 40)// height should whatever you want.
Tram answered 2/10, 2017 at 5:47 Comment(1)
tried your solution, it's fine for the big number of segments (~ >8), but how to manage the width, if I have only 2-3 segments, in this case, it shrinks the width and shifts all segments to the extreme left of the segmentView.Bombast
D
1

Try this https://github.com/lestadNew/SASScrolletSegment, I don't find solution and write own cocoa pods

Hope this help you

enter image description here

Denote answered 16/5, 2018 at 15:24 Comment(1)
if you wants to update this CocoaPods write me and I fixeDenote

© 2022 - 2024 — McMap. All rights reserved.