Merge branch 'master' into fix/label-layout
This commit is contained in:
commit
c37e26eadf
|
|
@ -0,0 +1,58 @@
|
|||
## How to contribute to Segmentio
|
||||
|
||||
#### **Did you find a bug?**
|
||||
|
||||
* **Ensure the bug was not already reported** by searching under [Issues](https://github.com/Yalantis/Segmentio/issues).
|
||||
|
||||
* If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/Yalantis/Segmentio/issues/new). Be sure to include a **title and clear description**, as much relevant information as possible, and a **code sample** or an **example project** demonstrating the expected behavior that is not occurring.
|
||||
|
||||
* Fill appropriate section in issue template and remove the section you aren't interested in.
|
||||
|
||||
#### **Did you write a patch that fixes a bug?**
|
||||
|
||||
* Open a new GitHub pull request with the patch.
|
||||
|
||||
* Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable.
|
||||
|
||||
* Ensure the PR doesn't extend the number of existing issues.
|
||||
|
||||
#### **Did you fix whitespace, format code, or make a purely cosmetic patch?**
|
||||
|
||||
* Changes that are **cosmetic** in nature and **do not add anything substantial** to the stability or functionality of Segmentio will generally **not be accepted**.
|
||||
|
||||
#### **Did you write patch that extends functionality?**
|
||||
|
||||
* Ensure the functionality you trying to add needed not only for your case.
|
||||
|
||||
#### Each issue will be labeled by it's `type`, `priority` and `status`.
|
||||
|
||||
**Issue types:**
|
||||
* Bug
|
||||
* Enhancement
|
||||
|
||||
**These are the available priority labels:**
|
||||
* Critical
|
||||
* High
|
||||
* Medium
|
||||
* Low
|
||||
|
||||
**Status label will be assigned to your issue to keep the issue tracker easy to follow:**
|
||||
* Queued (will be reviewed soon)
|
||||
* Reviewed (assignee has read it)
|
||||
* Pending (will work on it soon)
|
||||
* Work in progress (is working on it now)
|
||||
* On hold
|
||||
* Invalid (if bug it's not reproducible)
|
||||
* Need feedback (signal to get people to read and comment or provide help)
|
||||
|
||||
#### **Coding Style**
|
||||
|
||||
* Most importantly, match the existing code style as much as possible.
|
||||
|
||||
#### **Do you have a question?**
|
||||
|
||||
For any usage questions that are not specific to the project itself, please ask on [Stack Overflow](https://stackoverflow.com/). By doing so, you'll be more likely to quickly solve your problem, and you'll allow anyone else with the same question to find the answer. This also allows maintainers to focus on improving the project for others.
|
||||
|
||||
## Thank you!
|
||||
|
||||
#### [](https://Yalantis.com/?utm_source=github)
|
||||
2
LICENSE
2
LICENSE
|
|
@ -1,6 +1,6 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright © 2016 Yalantis
|
||||
Copyright © 2017 Yalantis
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
|||
108
README.md
108
README.md
|
|
@ -1,4 +1,4 @@
|
|||
##Segmentio
|
||||
## Segmentio
|
||||
[](https://cocoapods.org/?q=segmentio) [](https://github.com/Yalantis/Segmentio/blob/master/LICENSE)  [](https://github.com/Carthage/Carthage)
|
||||
|
||||
Animated top/bottom segmented control written in Swift.
|
||||
|
|
@ -7,15 +7,15 @@ Animated top/bottom segmented control written in Swift.
|
|||
|
||||
Check this <a href="https://dribbble.com/shots/2820372-Segmentio-Component">project on dribbble</a>.
|
||||
|
||||
##Requirements
|
||||
## Requirements
|
||||
|
||||
- Xcode 8
|
||||
- iOS 8.x+
|
||||
- Swift 3
|
||||
|
||||
##Installation
|
||||
## Installation
|
||||
|
||||
####[CocoaPods](http://cocoapods.org)
|
||||
#### [CocoaPods](http://cocoapods.org)
|
||||
```ruby
|
||||
use_frameworks!
|
||||
|
||||
|
|
@ -24,24 +24,24 @@ pod 'Segmentio', '~> 2.1'
|
|||
|
||||
*CocoaPods v1.1.0 or later required*
|
||||
|
||||
####[Carthage](http://github.com/Carthage/Carthage)
|
||||
#### [Carthage](http://github.com/Carthage/Carthage)
|
||||
```ruby
|
||||
github "Yalantis/Segmentio" ~> 2.1
|
||||
```
|
||||
|
||||
##Usage
|
||||
####Import `Segmentio` module
|
||||
## Usage
|
||||
#### Import `Segmentio` module
|
||||
```swift
|
||||
import Segmentio
|
||||
```
|
||||
|
||||
####Init
|
||||
#### Init
|
||||
You can initialize a `Segmentio` instance from code:
|
||||
|
||||
```swift
|
||||
var segmentioView: Segmentio!
|
||||
|
||||
let segmentioViewRect = CGRect(x: 0, y: 0, width: UIScreen.mainScreen().bounds.width, height: 125)
|
||||
let segmentioViewRect = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 125)
|
||||
segmentioView = Segmentio(frame: segmentioViewRect)
|
||||
view.addSubview(segmentioView)
|
||||
```
|
||||
|
|
@ -54,9 +54,9 @@ add a `UIView` instance in your .storyboard or .xib, set `Segmentio` class and c
|
|||
@IBOutlet weak var segmentioView: Segmentio!
|
||||
```
|
||||
|
||||
####Setup `Segmentio`
|
||||
#### Setup `Segmentio`
|
||||
```swift
|
||||
segmentioView.setupContent(
|
||||
segmentioView.setup(
|
||||
content: [SegmentioItem],
|
||||
style: SegmentioStyle,
|
||||
options: SegmentioOptions?
|
||||
|
|
@ -66,7 +66,7 @@ segmentioView.setupContent(
|
|||
To start with default options you can just pass `nil` to the `options` parameter.
|
||||
|
||||
```swift
|
||||
segmentioView.setupContent(
|
||||
segmentioView.setup(
|
||||
content: [SegmentioItem],
|
||||
style: SegmentioStyle,
|
||||
options: nil
|
||||
|
|
@ -74,7 +74,7 @@ segmentioView.setupContent(
|
|||
```
|
||||
|
||||
|
||||
####Configuring items
|
||||
#### Configuring items
|
||||
In order to set items you need to create an array of `SegmentioItem` instances:
|
||||
|
||||
```swift
|
||||
|
|
@ -87,14 +87,14 @@ let tornadoItem = SegmentioItem(
|
|||
content.append(tornadoItem)
|
||||
```
|
||||
|
||||
####Handling selection
|
||||
#### Handling selection
|
||||
You can specify selected item manually:
|
||||
|
||||
```swift
|
||||
segmentioView.selectedSegmentIndex = 0
|
||||
segmentioView.selectedSegmentioIndex = 0
|
||||
```
|
||||
|
||||
####Handling callback
|
||||
#### Handling callback
|
||||
|
||||
```swift
|
||||
segmentioView.valueDidChange = { segmentio, segmentIndex in
|
||||
|
|
@ -102,22 +102,20 @@ segmentioView.valueDidChange = { segmentio, segmentIndex in
|
|||
}
|
||||
```
|
||||
|
||||
####Customization
|
||||
#### Customization
|
||||
`Segmentio` can be customized by passing an instance of `SegmentioOptions` struct:
|
||||
|
||||
```swift
|
||||
SegmentioOptions(
|
||||
backgroundColor: UIColor.whiteColor(),
|
||||
maxVisibleItems: 3,
|
||||
scrollEnabled: true,
|
||||
indicatorOptions: SegmentioIndicatorOptions,
|
||||
horizontalSeparatorOptions: SegmentioHorizontalSeparatorOptions,
|
||||
verticalSeparatorOptions: SegmentioVerticalSeparatorOptions,
|
||||
imageContentMode: UIViewContentMode.Center,
|
||||
labelTextNumberOfLines: 1,
|
||||
labelTextAlignment: NSTextAlignment.Center,
|
||||
segmentStates: SegmentioStates, // tuple of SegmentioState (defaultState, selectState, highlightedState)
|
||||
animationDuration: 0.1
|
||||
backgroundColor: .white,
|
||||
maxVisibleItems: 3,
|
||||
scrollEnabled: true,
|
||||
indicatorOptions: SegmentioIndicatorOptions,
|
||||
horizontalSeparatorOptions: SegmentioHorizontalSeparatorOptions,
|
||||
verticalSeparatorOptions: SegmentioVerticalSeparatorOptions,
|
||||
imageContentMode: .center,
|
||||
labelTextAlignment: .center,
|
||||
segmentStates: SegmentioStates
|
||||
)
|
||||
```
|
||||
|
||||
|
|
@ -125,10 +123,10 @@ Selection indicator can be customized by passing an instance of `SegmentioIndica
|
|||
|
||||
```swift
|
||||
SegmentioIndicatorOptions(
|
||||
type: .Bottom,
|
||||
ratio: 1,
|
||||
height: 5,
|
||||
color: UIColor.orangeColor()
|
||||
type: .bottom,
|
||||
ratio: 1,
|
||||
height: 5,
|
||||
color: .orange
|
||||
)
|
||||
```
|
||||
|
||||
|
|
@ -136,9 +134,9 @@ Horizontal borders can be customized by passing an instance of `SegmentioHorizon
|
|||
|
||||
```swift
|
||||
SegmentioHorizontalSeparatorOptions(
|
||||
type: SegmentioHorizontalSeparatorType.TopAndBottom, // Top, Bottom, TopAndBottom
|
||||
height: 1,
|
||||
color: UIColor.grayColor()
|
||||
type: SegmentioHorizontalSeparatorType.topAndBottom, // Top, Bottom, TopAndBottom
|
||||
height: 1,
|
||||
color: .gray
|
||||
)
|
||||
```
|
||||
|
||||
|
|
@ -146,8 +144,8 @@ Separators between segments can be customized by passing an instance of `Segmen
|
|||
|
||||
```swift
|
||||
SegmentioVerticalSeparatorOptions(
|
||||
ratio: 0.6 // from 0.1 to 1
|
||||
color: UIColor.grayColor()
|
||||
ratio: 0.6, // from 0.1 to 1
|
||||
color: .gray
|
||||
)
|
||||
```
|
||||
|
||||
|
|
@ -155,34 +153,34 @@ In order to set `SegmentioStates` you need to create a tuple of `SegmentioState`
|
|||
|
||||
```swift
|
||||
SegmentioStates(
|
||||
defaultState: segmentioState(
|
||||
backgroundColor: UIColor.clearColor(),
|
||||
titleFont: UIFont.systemFontOfSize(UIFont.smallSystemFontSize()),
|
||||
titleTextColor: UIColor.blackColor()
|
||||
),
|
||||
selectState: segmentioState(
|
||||
backgroundColor: UIColor.orangeColor(),
|
||||
titleFont: UIFont.systemFontOfSize(UIFont.smallSystemFontSize()),
|
||||
titleTextColor: UIColor.whiteColor()
|
||||
),
|
||||
highlightedState: segmentioState(
|
||||
backgroundColor: UIColor.lightGrayColor().colorWithAlphaComponent(0.6),
|
||||
titleFont: UIFont.boldSystemFontOfSize(UIFont.smallSystemFontSize()),
|
||||
titleTextColor: UIColor.blackColor()
|
||||
)
|
||||
defaultState: SegmentioState(
|
||||
backgroundColor: .clear,
|
||||
titleFont: UIFont.systemFont(ofSize: UIFont.smallSystemFontSize),
|
||||
titleTextColor: .black
|
||||
),
|
||||
selectedState: SegmentioState(
|
||||
backgroundColor: .orange,
|
||||
titleFont: UIFont.systemFont(ofSize: UIFont.smallSystemFontSize),
|
||||
titleTextColor: .white
|
||||
),
|
||||
highlightedState: SegmentioState(
|
||||
backgroundColor: UIColor.lightGray.withAlphaComponent(0.6),
|
||||
titleFont: UIFont.boldSystemFont(ofSize: UIFont.smallSystemFontSize),
|
||||
titleTextColor: .black
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
####Let us know!
|
||||
#### Let us know!
|
||||
We’d be really happy if you sent us links to your projects where you use our component. Just send an email to github@yalantis.com And do let us know if you have any questions or suggestion regarding the animation.
|
||||
|
||||
P.S. We’re going to publish more awesomeness wrapped in code and a tutorial on how to make UI for iOS (Android) better than better. Stay tuned!
|
||||
|
||||
##License
|
||||
## License
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright © 2016 Yalantis
|
||||
Copyright © 2017 Yalantis
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
Pod::Spec.new do |spec|
|
||||
spec.name = "Segmentio"
|
||||
spec.version = "2.1.1"
|
||||
spec.version = "2.1.2"
|
||||
|
||||
spec.homepage = "https://github.com/Yalantis/Segmentio"
|
||||
spec.summary = "Animated top/bottom segmented control written in Swift!"
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ class SegmentioCell: UICollectionViewCell {
|
|||
segmentTitleLabel?.font = isHighlighted ? highlightedState.titleFont : highlightedTitleFont
|
||||
}
|
||||
|
||||
backgroundColor = isHighlighted ? highlightedState.backgroundColor : defaultState.backgroundColor
|
||||
backgroundColor = isHighlighted ? highlightedState.backgroundColor : .clear
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -130,7 +130,7 @@ class SegmentioCell: UICollectionViewCell {
|
|||
configurateBadgeWithCount(content.badgeCount, color: content.badgeColor)
|
||||
}
|
||||
|
||||
func configure(selected: Bool) {
|
||||
func configure(selected: Bool, selectedImage: UIImage? = nil, image: UIImage? = nil) {
|
||||
cellSelected = selected
|
||||
|
||||
let selectedState = options.states.selectedState
|
||||
|
|
@ -140,6 +140,10 @@ class SegmentioCell: UICollectionViewCell {
|
|||
segmentTitleLabel?.textColor = selected ? selectedState.titleTextColor : defaultState.titleTextColor
|
||||
segmentTitleLabel?.font = selected ? selectedState.titleFont : defaultState.titleFont
|
||||
}
|
||||
|
||||
if (style != .onlyLabel) {
|
||||
segmentImageView?.image = selected ? selectedImage : image
|
||||
}
|
||||
}
|
||||
|
||||
func configurateBadgeWithCount(_ badgeCount: Int?, color: UIColor?) {
|
||||
|
|
@ -173,38 +177,43 @@ class SegmentioCell: UICollectionViewCell {
|
|||
// MARK: - Private functions
|
||||
|
||||
fileprivate func setupContainerConstraints() {
|
||||
guard let segmentTitleLabel = segmentTitleLabel else {
|
||||
return
|
||||
}
|
||||
guard let containerView = containerView else {
|
||||
guard let segmentTitleLabel = segmentTitleLabel, let containerView = containerView else {
|
||||
return
|
||||
}
|
||||
|
||||
let segmentTitleLabelHorizontalCenterConstraint =
|
||||
NSLayoutConstraint(
|
||||
item: segmentTitleLabel,
|
||||
attribute: .centerX,
|
||||
relatedBy: .equal,
|
||||
toItem: containerView,
|
||||
attribute: .centerX,
|
||||
multiplier: 1,
|
||||
constant: 0
|
||||
let segmentTitleLabelVerticalCenterConstraint = NSLayoutConstraint(
|
||||
item: segmentTitleLabel,
|
||||
attribute: .centerY,
|
||||
relatedBy: .equal,
|
||||
toItem: containerView,
|
||||
attribute: .centerY,
|
||||
multiplier: 1,
|
||||
constant: 0
|
||||
)
|
||||
let segmentTitleLabelTrailingConstraint = NSLayoutConstraint(
|
||||
item: segmentTitleLabel,
|
||||
attribute: .trailing,
|
||||
relatedBy: .equal,
|
||||
toItem: containerView,
|
||||
attribute: .trailingMargin,
|
||||
multiplier: 1.0,
|
||||
constant: 0
|
||||
)
|
||||
let segmentTitleLabelLeadingConstraint = NSLayoutConstraint(
|
||||
item: segmentTitleLabel,
|
||||
attribute: .leading,
|
||||
relatedBy: .equal,
|
||||
toItem: containerView,
|
||||
attribute: .leadingMargin,
|
||||
multiplier: 1.0,
|
||||
constant: 0
|
||||
)
|
||||
|
||||
let segmentTitleLabelVerticalCenterConstraint =
|
||||
NSLayoutConstraint(
|
||||
item: segmentTitleLabel,
|
||||
attribute: .centerY,
|
||||
relatedBy: .equal,
|
||||
toItem: containerView,
|
||||
attribute: .centerY,
|
||||
multiplier: 1,
|
||||
constant: 0
|
||||
)
|
||||
addConstraints([
|
||||
segmentTitleLabelHorizontalCenterConstraint,
|
||||
segmentTitleLabelVerticalCenterConstraint
|
||||
])
|
||||
segmentTitleLabelTrailingConstraint,
|
||||
segmentTitleLabelVerticalCenterConstraint,
|
||||
segmentTitleLabelLeadingConstraint
|
||||
])
|
||||
}
|
||||
|
||||
fileprivate func setupImageContainerConstraints() {
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ open class Segmentio: UIView {
|
|||
collectionView.bounces = true
|
||||
collectionView.isScrollEnabled = segmentioOptions.scrollEnabled
|
||||
collectionView.backgroundColor = .clear
|
||||
collectionView.accessibilityIdentifier = "segmentio_collection_view"
|
||||
|
||||
segmentioCollectionView = collectionView
|
||||
|
||||
|
|
@ -113,6 +114,8 @@ open class Segmentio: UIView {
|
|||
let separatorHeight = horizontalSeparatorOptions.height
|
||||
|
||||
switch horizontalSeparatorOptions.type {
|
||||
case .none:
|
||||
separatorsHeight = 0
|
||||
case .top:
|
||||
collectionViewFrameMinY = separatorHeight
|
||||
separatorsHeight = separatorHeight
|
||||
|
|
@ -252,7 +255,7 @@ open class Segmentio: UIView {
|
|||
bottomSeparatorView = UIView(frame: CGRect.zero)
|
||||
setupConstraintsForSeparatorView(
|
||||
separatorView: bottomSeparatorView,
|
||||
originY: frame.maxY - height
|
||||
originY: bounds.maxY - height
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -270,7 +273,7 @@ open class Segmentio: UIView {
|
|||
item: separatorView,
|
||||
attribute: .top,
|
||||
relatedBy: .equal,
|
||||
toItem: superview,
|
||||
toItem: self,
|
||||
attribute: .top,
|
||||
multiplier: 1,
|
||||
constant: originY
|
||||
|
|
@ -549,6 +552,8 @@ open class Segmentio: UIView {
|
|||
let isIndicatorTop = indicatorOptions.type == .top
|
||||
|
||||
switch horizontalSeparatorOptions.type {
|
||||
case .none:
|
||||
break
|
||||
case .top:
|
||||
indicatorPointY = isIndicatorTop ? indicatorPointY + separatorHeight : indicatorPointY
|
||||
case .bottom:
|
||||
|
|
@ -578,14 +583,20 @@ extension Segmentio: UICollectionViewDataSource {
|
|||
withReuseIdentifier: segmentioStyle.rawValue,
|
||||
for: indexPath) as! SegmentioCell
|
||||
|
||||
let content = segmentioItems[indexPath.row]
|
||||
|
||||
cell.configure(
|
||||
content: segmentioItems[indexPath.row],
|
||||
content: content,
|
||||
style: segmentioStyle,
|
||||
options: segmentioOptions,
|
||||
isLastCell: indexPath.row == segmentioItems.count - 1
|
||||
)
|
||||
|
||||
cell.configure(selected: (indexPath.row == selectedSegmentioIndex))
|
||||
cell.configure(
|
||||
selected: (indexPath.row == selectedSegmentioIndex),
|
||||
selectedImage: content.selectedImage,
|
||||
image: content.image
|
||||
)
|
||||
|
||||
return cell
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ public struct SegmentioItem {
|
|||
|
||||
public var title: String?
|
||||
public var image: UIImage?
|
||||
public var selectedImage: UIImage?
|
||||
public var badgeCount: Int?
|
||||
public var badgeColor: UIColor?
|
||||
public var intrinsicWidth: CGFloat {
|
||||
|
|
@ -23,9 +24,10 @@ public struct SegmentioItem {
|
|||
return label.intrinsicContentSize.width
|
||||
}
|
||||
|
||||
public init(title: String?, image: UIImage?) {
|
||||
public init(title: String?, image: UIImage?, selectedImage: UIImage? = nil) {
|
||||
self.title = title
|
||||
self.image = image
|
||||
self.selectedImage = selectedImage ?? image
|
||||
}
|
||||
|
||||
public mutating func addBadge(_ count: Int, color: UIColor) {
|
||||
|
|
@ -62,7 +64,7 @@ public struct SegmentioState {
|
|||
// MARK: - Horizontal separator
|
||||
|
||||
public enum SegmentioHorizontalSeparatorType {
|
||||
|
||||
case none
|
||||
case top
|
||||
case bottom
|
||||
case topAndBottom
|
||||
|
|
|
|||
Loading…
Reference in New Issue