CocoaPods trunk is moving to be read-only. Read more on the blog, there are 19 months to go.

NLSegmentControl 1.4.0

NLSegmentControl 1.4.0

TestsTested
LangLanguage SwiftSwift
License MIT
ReleasedLast Release Aug 2017
SwiftSwift Version 3.0
SPMSupports SPM

Maintained by hailiang.song.



  • By
  • hailiang.song

NLSegmentControl

A drop-in replacement for UISegmentControl. Written in swift 3.0. It’s heavily inspired by HMSegmentedControl

Features

  • Support both text, images and text + image (easy to set image position: left, right, top, bottom)
  • Support attributed title
  • Based on protocol, support custom data model as the data source
  • Support horizontal scrolling
  • Support advanced title styling with text attributes for font, color, kerning, shadow, etc.
  • Support selection indicator both on top and bottom, and box indicator
  • Support blocks
  • Works with ARC and iOS >= 8

Usage

Just like the code below

let segment = NLSegmentControl(frame: CGRect(x: 0, y: 80, width: UIScreen.main.bounds.width, height: 40))
segment.segments = ["One Day", "Two", "Three", "Four dogs", "Five fingers", "Six trees", "Seven", "Eight", "Nine", "Ten"]
segment.indexChangedHandler = {
            (index) in
            print("index changed: \(index)")
        }
self.view.addSubview(segment)
segment.reloadSegments()

See more in the demo project.

Example

  • text only:
segment.segments = ["Trending", "News", "Library"]
  • image only:
segment.segments = [UIImage(named: "baby")!,UIImage(named: "bag")!,UIImage(named: "diamond")!]

if you want to set the selected image for the selected segment, try this:

let item1 = NLSegmentItem(image: UIImage(named: "baby"), selectedImage: UIImage(named: "baby_s"))
let item2 = NLSegmentItem(image: UIImage(named: "bag"), selectedImage: UIImage(named: "bag_s"))
let item3 = NLSegmentItem(image: UIImage(named: "diamond"), selectedImage:UIImage(named: "diamond_s"))
segment.segments = [item1, item2, item3]
  • text and image:

1.use NLSegmentItem struct

Note: title, image, selectedImage are all optional

let item1 = NLUISegmentItem(title: "Baby", image: UIImage(named: "baby"), selectedImage: UIImage(named: "baby_s"))
let item2 = NLUISegmentItem(title: "Bag", image: UIImage(named: "bag"), selectedImage: UIImage(named: "bag_s"))
let item3 = NLUISegmentItem(title: "Diamond", image: UIImage(named: "diamond"), selectedImage: UIImage(named: "diamond_s"))
segment.segments = [item1, item2, item3]

2.use your own data model, just make it implements NLSegment protocol.

struct Category {
    var categoryTitle: String?
    var categoryImage: String?
    var categorySelectedImage: String?
    
    init(title: String? = nil, image: String? = nil, selectedImage: String? = nil) {
        self.categoryTitle = title
        self.categoryImage = image
        self.categorySelectedImage = selectedImage
    }
}

extension Category: NLSegment {
    var segmentTitle: String? {
        return categoryTitle
    }
    var segmentImage: UIImage? {
        if let img = categoryImage {
            return UIImage(named: img)
        }
        return nil
    }
    var segmentSelectedImage: UIImage? {
        if let img = categorySelectedImage {
            return UIImage(named: img)
        }
        return nil
    }
}
let item1 = Category(title: "Baby", image: "baby", selectedImage: "baby_s")
let item2 = Category(title: "Bag", image: "bag", selectedImage: "bag_s")
let item3 = Category(title: "Diamond", image: "diamond", selectedImage: "diamond_s")
segment.segments = [item1, item2, item3]
  • attributed title:

Set the segmentTitleFormatter property, you can set any attribute to the segment as you want. If return nil, the segment will use the common titleTextAttributes property.

attrSegment.segmentTitleFormatter = {
            (segment, selected) -> NSAttributedString? in
            if let cate = segment as? Category {
                let title = cate.categoryTitle ?? ""
                let desc = cate.categoryDesc != nil ? "\n" + cate.categoryDesc! : ""
                let titleRange = NSRange(location: 0, length: title.count)
                let descRange = NSRange(location: title.count, length: desc.count)
                let attr = NSMutableAttributedString(string: title + desc)
                attr.addAttribute(NSFontAttributeName, value: UIFont.systemFont(ofSize: 18), range: titleRange)
                attr.addAttribute(NSFontAttributeName, value: UIFont.systemFont(ofSize: 10), range: descRange)
                if selected {
                    attr.addAttribute(NSForegroundColorAttributeName, value: UIColor.red, range: descRange)
                } else {
                    attr.addAttribute(NSForegroundColorAttributeName, value: UIColor.blue, range: descRange)
                }
                return attr
            }
            return nil
        }

Custom properties

  • segment width style

    • fixed: Each segment has equal width, equal to the widest segment.
    • dynamic: Each segment has different width, depends on it’s content.
    • equal(width): Each segment has equal width, equal to the width param.

  • selection indicator

    • selectionIndicatorStyle: style of the selection indicator, support textWidthStripe, fullWidthStripe, box
    • selectionIndicatorHeight: Height of the selection indicator
    • selectionIndicatorEdgeInset: Edge insets of the selection indicator
    • selectionIndicatorColor: Color of the selection indicator
    • selectionIndicatorPosition: Position of the selection indicator, support top, bottom, none
    • selectionBoxColor: Color of selection box

  • font & color

    • titleTextAttributes: Text attributes to apply to labels of the unselected segments
    • selectedTitleTextAttributes: Text attributes to apply to labels of the selected segments

  • vertical divider

    • enableVerticalDivider: enable vertical divider between the segments
    • verticalDividerColor: Color of vertical divider
    • verticalDividerWidth: Width of vertical divider
    • verticalDividerInset: Inset top and bottom of vertical divider

  • image and text

    • imagePosition: image position relative to text
    • imageTitleSpace: space between image and title

Change Log

version 1.3.0

  • support attributed title

version 1.2.0

  • refactor segment data source, use NLSegment protocol as data source
  • remove titles, images, selectedImages properties
  • support custom data model

version 1.1.0

  • update selectedSegmentIndex property to public