[Add] SegmentioBuilder
[Update] ExampleViewController: moved setup segmentioView logic to SegmentioBuilder [Fix] Autolayout issue using Segmentio programtically [Update] SegmentioItem, SegmentioCell: minor updates
This commit is contained in:
parent
e85b4ccb95
commit
07f7d884fc
|
|
@ -24,6 +24,7 @@
|
|||
327AF5EA1D1ABEC100534355 /* HomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 327AF5CB1D1ABEC100534355 /* HomeViewController.swift */; };
|
||||
327AF5EB1D1ABEC100534355 /* SideMenuViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 327AF5CC1D1ABEC100534355 /* SideMenuViewController.swift */; };
|
||||
327AF6041D1AC0FE00534355 /* ColorPalette.swift in Sources */ = {isa = PBXBuildFile; fileRef = 327AF6031D1AC0FE00534355 /* ColorPalette.swift */; };
|
||||
32C3706C1DD9C4FA001A39CB /* SegmentioBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C3706B1DD9C4FA001A39CB /* SegmentioBuilder.swift */; };
|
||||
5B9491B14F42A77448746E9B /* Pods_Segmentio_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 74E8553D39ECFE4883F1D2CA /* Pods_Segmentio_Example.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
|
|
@ -49,6 +50,7 @@
|
|||
327AF5CB1D1ABEC100534355 /* HomeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeViewController.swift; sourceTree = "<group>"; };
|
||||
327AF5CC1D1ABEC100534355 /* SideMenuViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SideMenuViewController.swift; sourceTree = "<group>"; };
|
||||
327AF6031D1AC0FE00534355 /* ColorPalette.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorPalette.swift; sourceTree = "<group>"; };
|
||||
32C3706B1DD9C4FA001A39CB /* SegmentioBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SegmentioBuilder.swift; sourceTree = "<group>"; };
|
||||
32C3A9241D2BB3B5004C0FC9 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = "<group>"; };
|
||||
607FACD01AFB9204008FA782 /* Segmentio_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Segmentio_Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
|
|
@ -136,6 +138,14 @@
|
|||
path = ViewControllers;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
32C3706A1DD9C4EC001A39CB /* Builders */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
32C3706B1DD9C4FA001A39CB /* SegmentioBuilder.swift */,
|
||||
);
|
||||
path = Builders;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
45CA913E13914443DB2552B6 /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
|
@ -169,6 +179,7 @@
|
|||
607FACD21AFB9204008FA782 /* Example for Segmentio */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
32C3706A1DD9C4EC001A39CB /* Builders */,
|
||||
327AF5A71D1ABEC100534355 /* Application */,
|
||||
327AF5A91D1ABEC100534355 /* Extensions */,
|
||||
327AF5AD1D1ABEC100534355 /* Helpers */,
|
||||
|
|
@ -337,6 +348,7 @@
|
|||
327AF5CF1D1ABEC100534355 /* AppDelegate.swift in Sources */,
|
||||
327AF5EB1D1ABEC100534355 /* SideMenuViewController.swift in Sources */,
|
||||
327AF5E81D1ABEC100534355 /* EmbedContainerViewController.swift in Sources */,
|
||||
32C3706C1DD9C4FA001A39CB /* SegmentioBuilder.swift in Sources */,
|
||||
327AF5D41D1ABEC100534355 /* Disaster.swift in Sources */,
|
||||
327AF5D31D1ABEC100534355 /* AppearanceConfigurator.swift in Sources */,
|
||||
327AF5EA1D1ABEC100534355 /* HomeViewController.swift in Sources */,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,118 @@
|
|||
//
|
||||
// SegmentioBuilder.swift
|
||||
// Segmentio
|
||||
//
|
||||
// Created by Dmitriy Demchenko on 11/14/16.
|
||||
// Copyright © 2016 CocoaPods. All rights reserved.
|
||||
//
|
||||
|
||||
import Segmentio
|
||||
import UIKit
|
||||
|
||||
struct SegmentioBuilder {
|
||||
|
||||
static func setupBadgeCountForIndex(_ segmentioView: Segmentio, index: Int) {
|
||||
segmentioView.addBadge(
|
||||
at: index,
|
||||
count: 10,
|
||||
color: ColorPalette.coral
|
||||
)
|
||||
}
|
||||
|
||||
static func buildSegmentioView(segmentioView: Segmentio, segmentioStyle: SegmentioStyle) {
|
||||
segmentioView.setup(
|
||||
content: segmentioContent(),
|
||||
style: segmentioStyle,
|
||||
options: segmentioOptions(segmentioStyle: segmentioStyle)
|
||||
)
|
||||
}
|
||||
|
||||
private static func segmentioContent() -> [SegmentioItem] {
|
||||
return [
|
||||
SegmentioItem(title: "Tornado", image: UIImage(named: "tornado")),
|
||||
SegmentioItem(title: "Earthquakes", image: UIImage(named: "earthquakes")),
|
||||
SegmentioItem(title: "Extreme heat", image: UIImage(named: "heat")),
|
||||
SegmentioItem(title: "Eruption", image: UIImage(named: "eruption")),
|
||||
SegmentioItem(title: "Floods", image: UIImage(named: "floods")),
|
||||
SegmentioItem(title: "Wildfires", image: UIImage(named: "wildfires"))
|
||||
]
|
||||
}
|
||||
|
||||
private static func segmentioOptions(segmentioStyle: SegmentioStyle) -> SegmentioOptions {
|
||||
var imageContentMode = UIViewContentMode.center
|
||||
switch segmentioStyle {
|
||||
case .imageBeforeLabel, .imageAfterLabel:
|
||||
imageContentMode = .scaleAspectFit
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
return SegmentioOptions(
|
||||
backgroundColor: ColorPalette.white,
|
||||
maxVisibleItems: 3,
|
||||
scrollEnabled: true,
|
||||
indicatorOptions: segmentioIndicatorOptions(),
|
||||
horizontalSeparatorOptions: segmentioHorizontalSeparatorOptions(),
|
||||
verticalSeparatorOptions: segmentioVerticalSeparatorOptions(),
|
||||
imageContentMode: imageContentMode,
|
||||
labelTextAlignment: .center,
|
||||
labelTextNumberOfLines: 1,
|
||||
segmentStates: segmentioStates(),
|
||||
animationDuration: 0.3
|
||||
)
|
||||
}
|
||||
|
||||
private static func segmentioStates() -> SegmentioStates {
|
||||
let font = UIFont.exampleAvenirMedium(ofSize: 13)
|
||||
return SegmentioStates(
|
||||
defaultState: segmentioState(
|
||||
backgroundColor: .clear,
|
||||
titleFont: font,
|
||||
titleTextColor: ColorPalette.grayChateau
|
||||
),
|
||||
selectedState: segmentioState(
|
||||
backgroundColor: .cyan,
|
||||
titleFont: font,
|
||||
titleTextColor: ColorPalette.black
|
||||
),
|
||||
highlightedState: segmentioState(
|
||||
backgroundColor: ColorPalette.whiteSmoke,
|
||||
titleFont: font,
|
||||
titleTextColor: ColorPalette.grayChateau
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private static func segmentioState(backgroundColor: UIColor, titleFont: UIFont, titleTextColor: UIColor) -> SegmentioState {
|
||||
return SegmentioState(
|
||||
backgroundColor: backgroundColor,
|
||||
titleFont: titleFont,
|
||||
titleTextColor: titleTextColor
|
||||
)
|
||||
}
|
||||
|
||||
private static func segmentioIndicatorOptions() -> SegmentioIndicatorOptions {
|
||||
return SegmentioIndicatorOptions(
|
||||
type: .bottom,
|
||||
ratio: 1,
|
||||
height: 5,
|
||||
color: ColorPalette.coral
|
||||
)
|
||||
}
|
||||
|
||||
private static func segmentioHorizontalSeparatorOptions() -> SegmentioHorizontalSeparatorOptions {
|
||||
return SegmentioHorizontalSeparatorOptions(
|
||||
type: .topAndBottom,
|
||||
height: 1,
|
||||
color: ColorPalette.whiteSmoke
|
||||
)
|
||||
}
|
||||
|
||||
private static func segmentioVerticalSeparatorOptions() -> SegmentioVerticalSeparatorOptions {
|
||||
return SegmentioVerticalSeparatorOptions(
|
||||
ratio: 1,
|
||||
color: ColorPalette.whiteSmoke
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -33,8 +33,6 @@
|
|||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
|||
|
|
@ -46,132 +46,65 @@ class ExampleViewController: UIViewController {
|
|||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
setupSegmentioView()
|
||||
setupScrollView()
|
||||
setupBadgeCountForIndex(1)
|
||||
}
|
||||
|
||||
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
|
||||
super.viewWillTransition(to: size, with: coordinator)
|
||||
|
||||
coordinator.animate(alongsideTransition: { [weak self] _ in
|
||||
self?.segmentioView.interfaceOrientationDidChange()
|
||||
}, completion: nil)
|
||||
}
|
||||
|
||||
fileprivate func setupSegmentioView() {
|
||||
segmentioView.setup(
|
||||
content: segmentioContent(),
|
||||
style: segmentioStyle,
|
||||
options: segmentioOptions()
|
||||
SegmentioBuilder.buildSegmentioView(
|
||||
segmentioView: segmentioView,
|
||||
segmentioStyle: segmentioStyle
|
||||
)
|
||||
SegmentioBuilder.setupBadgeCountForIndex(segmentioView, index: 1)
|
||||
|
||||
segmentioView.selectedSegmentioIndex = selectedSegmentioIndex()
|
||||
|
||||
segmentioView.valueDidChange = { [weak self] _, segmentIndex in
|
||||
if let scrollViewWidth = self?.scrollView.frame.width {
|
||||
let contentOffsetX = scrollViewWidth * CGFloat(segmentIndex)
|
||||
self?.scrollView.setContentOffset(CGPoint(x: contentOffsetX, y: 0), animated: true)
|
||||
self?.scrollView.setContentOffset(
|
||||
CGPoint(x: contentOffsetX, y: 0),
|
||||
animated: true
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func setupBadgeCountForIndex(_ index: Int) {
|
||||
segmentioView.addBadge(at: index, count: 10, color: ColorPalette.coral)
|
||||
}
|
||||
|
||||
fileprivate func segmentioContent() -> [SegmentioItem] {
|
||||
return [
|
||||
SegmentioItem(title: "Tornado", image: UIImage(named: "tornado")),
|
||||
SegmentioItem(title: "Earthquakes", image: UIImage(named: "earthquakes")),
|
||||
SegmentioItem(title: "Extreme heat", image: UIImage(named: "heat")),
|
||||
SegmentioItem(title: "Eruption", image: UIImage(named: "eruption")),
|
||||
SegmentioItem(title: "Floods", image: UIImage(named: "floods")),
|
||||
SegmentioItem(title: "Wildfires", image: UIImage(named: "wildfires"))
|
||||
]
|
||||
}
|
||||
|
||||
fileprivate func segmentioOptions() -> SegmentioOptions {
|
||||
var imageContentMode = UIViewContentMode.center
|
||||
switch segmentioStyle {
|
||||
case .imageBeforeLabel, .imageAfterLabel:
|
||||
imageContentMode = .scaleAspectFit
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
return SegmentioOptions(
|
||||
backgroundColor: ColorPalette.white,
|
||||
maxVisibleItems: 3,
|
||||
scrollEnabled: true,
|
||||
indicatorOptions: segmentioIndicatorOptions(),
|
||||
horizontalSeparatorOptions: segmentioHorizontalSeparatorOptions(),
|
||||
verticalSeparatorOptions: segmentioVerticalSeparatorOptions(),
|
||||
imageContentMode: imageContentMode,
|
||||
labelTextAlignment: .center,
|
||||
labelTextNumberOfLines: 1,
|
||||
segmentStates: segmentioStates(),
|
||||
animationDuration: 0.3
|
||||
)
|
||||
}
|
||||
|
||||
fileprivate func segmentioStates() -> SegmentioStates {
|
||||
let font = UIFont.exampleAvenirMedium(ofSize: 13)
|
||||
return SegmentioStates(
|
||||
defaultState: segmentioState(
|
||||
backgroundColor: .clear,
|
||||
titleFont: font,
|
||||
titleTextColor: ColorPalette.grayChateau
|
||||
),
|
||||
selectedState: segmentioState(
|
||||
backgroundColor: .cyan,
|
||||
titleFont: font,
|
||||
titleTextColor: ColorPalette.black
|
||||
),
|
||||
highlightedState: segmentioState(
|
||||
backgroundColor: ColorPalette.whiteSmoke,
|
||||
titleFont: font,
|
||||
titleTextColor: ColorPalette.grayChateau
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fileprivate func segmentioState(backgroundColor: UIColor, titleFont: UIFont, titleTextColor: UIColor) -> SegmentioState {
|
||||
return SegmentioState(backgroundColor: backgroundColor, titleFont: titleFont, titleTextColor: titleTextColor)
|
||||
}
|
||||
|
||||
fileprivate func segmentioIndicatorOptions() -> SegmentioIndicatorOptions {
|
||||
return SegmentioIndicatorOptions(type: .bottom, ratio: 1, height: 5, color: ColorPalette.coral)
|
||||
}
|
||||
|
||||
fileprivate func segmentioHorizontalSeparatorOptions() -> SegmentioHorizontalSeparatorOptions {
|
||||
return SegmentioHorizontalSeparatorOptions(type: .topAndBottom, height: 1, color: ColorPalette.whiteSmoke)
|
||||
}
|
||||
|
||||
fileprivate func segmentioVerticalSeparatorOptions() -> SegmentioVerticalSeparatorOptions {
|
||||
return SegmentioVerticalSeparatorOptions(ratio: 1, color: ColorPalette.whiteSmoke)
|
||||
}
|
||||
|
||||
// Example viewControllers
|
||||
|
||||
fileprivate func preparedViewControllers() -> [ContentViewController] {
|
||||
let tornadoController = ContentViewController.create()
|
||||
tornadoController.disaster = Disaster(cardName: "Before tornado", hints: Hints.tornado)
|
||||
tornadoController.disaster = Disaster(
|
||||
cardName: "Before tornado",
|
||||
hints: Hints.tornado
|
||||
)
|
||||
|
||||
let earthquakesController = ContentViewController.create()
|
||||
earthquakesController.disaster = Disaster(cardName: "Before earthquakes", hints: Hints.earthquakes)
|
||||
earthquakesController.disaster = Disaster(
|
||||
cardName: "Before earthquakes",
|
||||
hints: Hints.earthquakes
|
||||
)
|
||||
|
||||
let extremeHeatController = ContentViewController.create()
|
||||
extremeHeatController.disaster = Disaster(cardName: "Before extreme heat", hints: Hints.extremeHeat)
|
||||
extremeHeatController.disaster = Disaster(
|
||||
cardName: "Before extreme heat",
|
||||
hints: Hints.extremeHeat
|
||||
)
|
||||
|
||||
let eruptionController = ContentViewController.create()
|
||||
eruptionController.disaster = Disaster(cardName: "Before eruption", hints: Hints.eruption)
|
||||
eruptionController.disaster = Disaster(
|
||||
cardName: "Before eruption",
|
||||
hints: Hints.eruption
|
||||
)
|
||||
|
||||
let floodsController = ContentViewController.create()
|
||||
floodsController.disaster = Disaster(cardName: "Before floods", hints: Hints.floods)
|
||||
floodsController.disaster = Disaster(
|
||||
cardName: "Before floods",
|
||||
hints: Hints.floods
|
||||
)
|
||||
|
||||
let wildfiresController = ContentViewController.create()
|
||||
wildfiresController.disaster = Disaster(cardName: "Before wildfires", hints: Hints.wildfires)
|
||||
wildfiresController.disaster = Disaster(
|
||||
cardName: "Before wildfires",
|
||||
hints: Hints.wildfires
|
||||
)
|
||||
|
||||
return [
|
||||
tornadoController,
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ class SegmentioCell: UICollectionViewCell {
|
|||
toItem: containerView,
|
||||
attribute: .centerX,
|
||||
multiplier: 1,
|
||||
constant: 0.0
|
||||
constant: 0
|
||||
)
|
||||
|
||||
let segmentTitleLabelVerticalCenterConstraint =
|
||||
|
|
@ -199,9 +199,12 @@ class SegmentioCell: UICollectionViewCell {
|
|||
toItem: containerView,
|
||||
attribute: .centerY,
|
||||
multiplier: 1,
|
||||
constant: 0.0
|
||||
constant: 0
|
||||
)
|
||||
addConstraints([segmentTitleLabelHorizontalCenterConstraint, segmentTitleLabelVerticalCenterConstraint])
|
||||
addConstraints([
|
||||
segmentTitleLabelHorizontalCenterConstraint,
|
||||
segmentTitleLabelVerticalCenterConstraint
|
||||
])
|
||||
}
|
||||
|
||||
fileprivate func setupImageContainerConstraints() {
|
||||
|
|
@ -220,7 +223,7 @@ class SegmentioCell: UICollectionViewCell {
|
|||
toItem: imageContainerView,
|
||||
attribute: .top,
|
||||
multiplier: 1,
|
||||
constant: 0.0
|
||||
constant: 0
|
||||
)
|
||||
|
||||
let segmentImageViewLeadingConstraint =
|
||||
|
|
@ -231,7 +234,7 @@ class SegmentioCell: UICollectionViewCell {
|
|||
toItem: imageContainerView,
|
||||
attribute: .leading,
|
||||
multiplier: 1,
|
||||
constant: 0.0
|
||||
constant: 0
|
||||
)
|
||||
|
||||
let segmentImageViewTrailingConstraint =
|
||||
|
|
@ -242,7 +245,7 @@ class SegmentioCell: UICollectionViewCell {
|
|||
toItem: imageContainerView,
|
||||
attribute: .trailing,
|
||||
multiplier: 1,
|
||||
constant: 0.0
|
||||
constant: 0
|
||||
)
|
||||
|
||||
let segmentImageViewBottomConstraint =
|
||||
|
|
@ -253,9 +256,14 @@ class SegmentioCell: UICollectionViewCell {
|
|||
toItem: imageContainerView,
|
||||
attribute: .bottom,
|
||||
multiplier: 1,
|
||||
constant: 0.0
|
||||
constant: 0
|
||||
)
|
||||
addConstraints([segmentImageViewBottomConstraint, segmentImageViewTrailingConstraint, segmentImageViewLeadingConstraint, segmentImageViewTopConstraint])
|
||||
addConstraints([
|
||||
segmentImageViewBottomConstraint,
|
||||
segmentImageViewTrailingConstraint,
|
||||
segmentImageViewLeadingConstraint,
|
||||
segmentImageViewTopConstraint
|
||||
])
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,11 @@ open class Segmentio: UIView {
|
|||
commonInit()
|
||||
}
|
||||
|
||||
open override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
reloadSegmentio()
|
||||
}
|
||||
|
||||
fileprivate func commonInit() {
|
||||
setupSegmentedCollectionView()
|
||||
}
|
||||
|
|
@ -187,12 +192,6 @@ open class Segmentio: UIView {
|
|||
segmentioCollectionView?.reloadData()
|
||||
}
|
||||
|
||||
open func interfaceOrientationDidChange() {
|
||||
segmentioCollectionView?.collectionViewLayout.invalidateLayout()
|
||||
scrollToItemAtContext()
|
||||
moveShapeLayerAtContext()
|
||||
}
|
||||
|
||||
// MARK: Collection view setup
|
||||
|
||||
fileprivate func setupCellWithStyle(_ style: SegmentioStyle) {
|
||||
|
|
@ -323,7 +322,6 @@ open class Segmentio: UIView {
|
|||
// MARK: - Actions:
|
||||
// MARK: Reload segmentio
|
||||
public func reloadSegmentio() {
|
||||
// segmentioCollectionView?.reloadData()
|
||||
segmentioCollectionView?.collectionViewLayout.invalidateLayout()
|
||||
scrollToItemAtContext()
|
||||
moveShapeLayerAtContext()
|
||||
|
|
@ -389,9 +387,10 @@ open class Segmentio: UIView {
|
|||
)
|
||||
}
|
||||
|
||||
if context.isFirstOrSecondVisibleCell == true {
|
||||
if context.isFirstOrSecondVisibleCell == true && selectedSegmentioIndex != -1 {
|
||||
let newIndex = selectedSegmentioIndex - (context.isFirstIndex ? 1 : 0)
|
||||
let newIndexPath = IndexPath(item: newIndex, section: numberOfSections - 1)
|
||||
|
||||
segmentioCollectionView?.scrollToItem(
|
||||
at: newIndexPath,
|
||||
at: UICollectionViewScrollPosition(),
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ public struct SegmentioVerticalSeparatorOptions {
|
|||
var ratio: CGFloat
|
||||
var color: UIColor
|
||||
|
||||
public init(ratio: CGFloat = 1.0, color: UIColor = .darkGray) {
|
||||
public init(ratio: CGFloat = 1, color: UIColor = .darkGray) {
|
||||
self.ratio = ratio
|
||||
self.color = color
|
||||
}
|
||||
|
|
@ -107,7 +107,7 @@ public struct SegmentioIndicatorOptions {
|
|||
var height: CGFloat
|
||||
var color: UIColor
|
||||
|
||||
public init(type: SegmentioIndicatorType = .bottom, ratio: CGFloat = 1.0, height: CGFloat = 2.0, color: UIColor = .orange) {
|
||||
public init(type: SegmentioIndicatorType = .bottom, ratio: CGFloat = 1, height: CGFloat = 2, color: UIColor = .orange) {
|
||||
self.type = type
|
||||
self.ratio = ratio
|
||||
self.height = height
|
||||
|
|
|
|||
Loading…
Reference in New Issue