Adds dynamic segment positioning type where cells size varies based on content
This commit is contained in:
parent
e46a86115d
commit
19a6e00996
|
|
@ -1,16 +1,16 @@
|
|||
PODS:
|
||||
- Segmentio (1.1.3)
|
||||
- Segmentio (2.1.1)
|
||||
|
||||
DEPENDENCIES:
|
||||
- Segmentio (from `../`)
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
Segmentio:
|
||||
:path: "../"
|
||||
:path: ../
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Segmentio: f784171237bcbb4854f338aef8162e312f4ac5b8
|
||||
Segmentio: fc7d724a2394d62367ac766b88b8e05d8edda012
|
||||
|
||||
PODFILE CHECKSUM: 761653fe0a6001fe4076ba25b04e279672ecc970
|
||||
|
||||
COCOAPODS: 1.1.0.rc.2
|
||||
COCOAPODS: 1.1.0.rc.3
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "Segmentio",
|
||||
"version": "1.1.3",
|
||||
"version": "2.1.1",
|
||||
"homepage": "https://github.com/Yalantis/Segmentio",
|
||||
"summary": "Animated top/bottom segmented control written in Swift!",
|
||||
"screenshots": "https://raw.githubusercontent.com/Yalantis/Segmentio/master/Assets/animation.gif",
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
},
|
||||
"source": {
|
||||
"git": "https://github.com/Yalantis/Segmentio.git",
|
||||
"tag": "1.1.3"
|
||||
"tag": "2.1.1"
|
||||
},
|
||||
"source_files": "Segmentio/Source/**/*.swift",
|
||||
"resources": "Segmentio/Source/Badge/Views/*.xib",
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
PODS:
|
||||
- Segmentio (1.1.3)
|
||||
- Segmentio (2.1.1)
|
||||
|
||||
DEPENDENCIES:
|
||||
- Segmentio (from `../`)
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
Segmentio:
|
||||
:path: "../"
|
||||
:path: ../
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Segmentio: f784171237bcbb4854f338aef8162e312f4ac5b8
|
||||
Segmentio: fc7d724a2394d62367ac766b88b8e05d8edda012
|
||||
|
||||
PODFILE CHECKSUM: 761653fe0a6001fe4076ba25b04e279672ecc970
|
||||
|
||||
COCOAPODS: 1.1.0.rc.2
|
||||
COCOAPODS: 1.1.0.rc.3
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ This application makes use of the following third party libraries:
|
|||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright © 2015 Yalantis
|
||||
Copyright © 2016 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
|
||||
|
|
@ -24,4 +24,5 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
Generated by CocoaPods - https://cocoapods.org
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<key>FooterText</key>
|
||||
<string>The MIT License (MIT)
|
||||
|
||||
Copyright © 2015 Yalantis
|
||||
Copyright © 2016 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
|
||||
|
|
@ -34,7 +34,8 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.</string>
|
||||
THE SOFTWARE.
|
||||
</string>
|
||||
<key>License</key>
|
||||
<string>MIT</string>
|
||||
<key>Title</key>
|
||||
|
|
|
|||
|
|
@ -23,12 +23,6 @@ case "${TARGETED_DEVICE_FAMILY}" in
|
|||
;;
|
||||
esac
|
||||
|
||||
realpath() {
|
||||
DIRECTORY="$(cd "${1%/*}" && pwd)"
|
||||
FILENAME="${1##*/}"
|
||||
echo "$DIRECTORY/$FILENAME"
|
||||
}
|
||||
|
||||
install_resource()
|
||||
{
|
||||
if [[ "$1" = /* ]] ; then
|
||||
|
|
@ -70,7 +64,7 @@ EOM
|
|||
xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm"
|
||||
;;
|
||||
*.xcassets)
|
||||
ABSOLUTE_XCASSET_FILE=$(realpath "$RESOURCE_PATH")
|
||||
ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH"
|
||||
XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
|
||||
;;
|
||||
*)
|
||||
|
|
@ -93,7 +87,7 @@ then
|
|||
# Find all other xcassets (this unfortunately includes those of path pods and other targets).
|
||||
OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d)
|
||||
while read line; do
|
||||
if [[ $line != "`realpath $PODS_ROOT`*" ]]; then
|
||||
if [[ $line != "${PODS_ROOT}*" ]]; then
|
||||
XCASSET_FILES+=("$line")
|
||||
fi
|
||||
done <<<"$OTHER_XCASSETS"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
#ifdef __OBJC__
|
||||
#import <UIKit/UIKit.h>
|
||||
#endif
|
||||
|
||||
|
||||
FOUNDATION_EXPORT double Pods_Segmentio_ExampleVersionNumber;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.1.3</string>
|
||||
<string>2.1.1</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.1.3</string>
|
||||
<string>2.1.1</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
#ifdef __OBJC__
|
||||
#import <UIKit/UIKit.h>
|
||||
#endif
|
||||
|
||||
|
||||
FOUNDATION_EXPORT double SegmentioVersionNumber;
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ struct SegmentioBuilder {
|
|||
|
||||
return SegmentioOptions(
|
||||
backgroundColor: ColorPalette.white,
|
||||
maxVisibleItems: 3,
|
||||
segmentPosition: .fixed(maxVisibleItems: 3),
|
||||
scrollEnabled: true,
|
||||
indicatorOptions: segmentioIndicatorOptions(),
|
||||
horizontalSeparatorOptions: segmentioHorizontalSeparatorOptions(),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,15 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "20x20",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "20x20",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
|
|
@ -36,6 +46,16 @@
|
|||
"filename" : "Icon-60@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "20x20",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "20x20",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import UIKit
|
|||
class SegmentioCell: UICollectionViewCell {
|
||||
|
||||
let padding: CGFloat = 8
|
||||
let segmentTitleLabelHeight: CGFloat = 22
|
||||
static let segmentTitleLabelHeight: CGFloat = 22
|
||||
|
||||
var verticalSeparatorView: UIView?
|
||||
var segmentTitleLabel: UILabel?
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ final class SegmentioCellWithImageAfterLabel: SegmentioCell {
|
|||
return
|
||||
}
|
||||
|
||||
let metrics = ["labelHeight": segmentTitleLabelHeight]
|
||||
let metrics = ["labelHeight": SegmentioCell.segmentTitleLabelHeight]
|
||||
let views = [
|
||||
"imageContainerView": imageContainerView,
|
||||
"containerView": containerView
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ class SegmentioCellWithImageBeforeLabel: SegmentioCell {
|
|||
return
|
||||
}
|
||||
|
||||
let metrics = ["labelHeight": segmentTitleLabelHeight]
|
||||
let metrics = ["labelHeight": SegmentioCell.segmentTitleLabelHeight]
|
||||
let views = [
|
||||
"imageContainerView": imageContainerView,
|
||||
"containerView": containerView
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ class SegmentioCellWithImageOverLabel: SegmentioCell {
|
|||
return
|
||||
}
|
||||
|
||||
let metrics = ["labelHeight": segmentTitleLabelHeight]
|
||||
let metrics = ["labelHeight": SegmentioCell.segmentTitleLabelHeight]
|
||||
let views = [
|
||||
"imageContainerView": imageContainerView,
|
||||
"containerView": containerView
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ class SegmentioCellWithImageUnderLabel: SegmentioCell {
|
|||
return
|
||||
}
|
||||
|
||||
let metrics = ["labelHeight": segmentTitleLabelHeight]
|
||||
let metrics = ["labelHeight": SegmentioCell.segmentTitleLabelHeight]
|
||||
let views = [
|
||||
"imageContainerView": imageContainerView,
|
||||
"containerView": containerView
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ open class Segmentio: UIView {
|
|||
fileprivate var segmentioOptions = SegmentioOptions()
|
||||
fileprivate var segmentioStyle = SegmentioStyle.imageOverLabel
|
||||
fileprivate var isPerformingScrollAnimation = false
|
||||
fileprivate var isCollectionViewScrolling = false
|
||||
|
||||
fileprivate var topSeparatorView: UIView?
|
||||
fileprivate var bottomSeparatorView: UIView?
|
||||
|
|
@ -324,6 +325,7 @@ open class Segmentio: UIView {
|
|||
public func reloadSegmentio() {
|
||||
segmentioCollectionView?.collectionViewLayout.invalidateLayout()
|
||||
segmentioCollectionView?.reloadData()
|
||||
guard selectedSegmentioIndex != -1 else { return }
|
||||
scrollToItemAtContext()
|
||||
moveShapeLayerAtContext()
|
||||
}
|
||||
|
|
@ -335,7 +337,7 @@ open class Segmentio: UIView {
|
|||
let item = itemInSuperview(ratio: options.ratio)
|
||||
let context = contextForItem(item)
|
||||
|
||||
let points = Points(context: context, item: item, atIndex: selectedSegmentioIndex, allItems: segmentioItems, pointY: indicatorPointY(), position: segmentioOptions.segmentPosition)
|
||||
let points = Points(context: context, item: item, atIndex: selectedSegmentioIndex, allItems: segmentioItems, pointY: indicatorPointY(), position: segmentioOptions.segmentPosition, style: segmentioStyle)
|
||||
|
||||
moveShapeLayer(
|
||||
indicatorLayer,
|
||||
|
|
@ -349,7 +351,7 @@ open class Segmentio: UIView {
|
|||
let item = itemInSuperview()
|
||||
let context = contextForItem(item)
|
||||
|
||||
let points = Points(context: context, item: item, atIndex: selectedSegmentioIndex, allItems: segmentioItems, pointY: bounds.midY, position: segmentioOptions.segmentPosition)
|
||||
let points = Points(context: context, item: item, atIndex: selectedSegmentioIndex, allItems: segmentioItems, pointY: bounds.midY, position: segmentioOptions.segmentPosition, style: segmentioStyle)
|
||||
|
||||
moveShapeLayer(
|
||||
selectedLayer,
|
||||
|
|
@ -366,30 +368,30 @@ open class Segmentio: UIView {
|
|||
guard let numberOfSections = segmentioCollectionView?.numberOfSections else {
|
||||
return
|
||||
}
|
||||
|
||||
guard selectedSegmentioIndex != -1 else { return }
|
||||
|
||||
let item = itemInSuperview()
|
||||
let context = contextForItem(item)
|
||||
|
||||
if context.isLastOrPrelastVisibleCell == true && selectedSegmentioIndex != -1 {
|
||||
let newIndex = selectedSegmentioIndex + (context.isLastCell ? 0 : 1)
|
||||
let newIndexPath = IndexPath(item: newIndex, section: numberOfSections - 1)
|
||||
segmentioCollectionView?.scrollToItem(
|
||||
at: newIndexPath,
|
||||
at: UICollectionViewScrollPosition(),
|
||||
animated: 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(),
|
||||
animated: true
|
||||
)
|
||||
|
||||
segmentioCollectionView?.scrollRectToVisible(centerRect(for: item), animated: true)
|
||||
}
|
||||
|
||||
fileprivate func centerRect(for item: ItemInSuperview) -> CGRect {
|
||||
let item = itemInSuperview()
|
||||
var centerRect = item.cellFrameInSuperview
|
||||
if (item.startX + segmentioCollectionView!.contentOffset.x) - (item.collectionViewWidth - centerRect.width) / 2 < 0 {
|
||||
centerRect.origin.x = 0
|
||||
var widthToAdd: CGFloat = (item.collectionViewWidth - centerRect.width)
|
||||
centerRect.size.width += widthToAdd
|
||||
} else if segmentioCollectionView!.contentSize.width - item.endX < (item.collectionViewWidth - centerRect.width) / 2 {
|
||||
centerRect.origin.x = segmentioCollectionView!.contentSize.width - item.collectionViewWidth
|
||||
centerRect.size.width = item.collectionViewWidth
|
||||
} else {
|
||||
centerRect.origin.x = item.startX - (item.collectionViewWidth - centerRect.width) / 2 + segmentioCollectionView!.contentOffset.x
|
||||
centerRect.size.width = item.collectionViewWidth
|
||||
}
|
||||
return centerRect
|
||||
}
|
||||
|
||||
// MARK: Move shape layer
|
||||
|
|
@ -455,7 +457,7 @@ open class Segmentio: UIView {
|
|||
var cellRect = CGRect.zero
|
||||
var shapeLayerWidth: CGFloat = 0
|
||||
|
||||
if let collectionView = segmentioCollectionView {
|
||||
if let collectionView = segmentioCollectionView, selectedSegmentioIndex != -1 {
|
||||
collectionViewWidth = collectionView.frame.width
|
||||
cellWidth = segmentWidth(for: IndexPath(row: selectedSegmentioIndex, section: 0))
|
||||
var x: CGFloat = 0
|
||||
|
|
@ -506,14 +508,23 @@ open class Segmentio: UIView {
|
|||
}
|
||||
var dynamicWidth: CGFloat = 0
|
||||
for item in segmentioItems {
|
||||
dynamicWidth += item.intrinsicWidth
|
||||
dynamicWidth += Segmentio.intrinsicWidth(for: item, style: segmentioStyle)
|
||||
}
|
||||
width = dynamicWidth > collectionViewWidth ? segmentioItems[indexPath.row].intrinsicWidth : segmentioItems[indexPath.row].intrinsicWidth + ((collectionViewWidth - dynamicWidth) / CGFloat(segmentioItems.count))
|
||||
let itemWidth = Segmentio.intrinsicWidth(for: segmentioItems[indexPath.row], style: segmentioStyle)
|
||||
width = dynamicWidth > collectionViewWidth ? itemWidth : itemWidth + ((collectionViewWidth - dynamicWidth) / CGFloat(segmentioItems.count))
|
||||
}
|
||||
}
|
||||
return width
|
||||
}
|
||||
|
||||
|
||||
fileprivate static func intrinsicWidth(for item: SegmentioItem, style: SegmentioStyle) -> CGFloat {
|
||||
var itemWidth: CGFloat = item.intrinsicWidth
|
||||
if style == .imageAfterLabel || style == .imageBeforeLabel {
|
||||
itemWidth += SegmentioCell.segmentTitleLabelHeight
|
||||
}
|
||||
return itemWidth
|
||||
}
|
||||
|
||||
// MARK: - Indicator point Y
|
||||
|
||||
fileprivate func indicatorPointY() -> CGFloat {
|
||||
|
|
@ -634,12 +645,16 @@ extension Segmentio: UIScrollViewDelegate {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
|
||||
isCollectionViewScrolling = false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension Segmentio.Points {
|
||||
|
||||
init(context: Segmentio.Context, item: Segmentio.ItemInSuperview, atIndex index: Int, allItems: [SegmentioItem], pointY: CGFloat, position: SegmentioPosition) {
|
||||
init(context: Segmentio.Context, item: Segmentio.ItemInSuperview, atIndex index: Int, allItems: [SegmentioItem], pointY: CGFloat, position: SegmentioPosition, style: SegmentioStyle) {
|
||||
let cellWidth = item.cellFrameInSuperview.width
|
||||
|
||||
var startX = item.startX
|
||||
|
|
@ -677,7 +692,7 @@ extension Segmentio.Points {
|
|||
// We have to calculate the final position of the item
|
||||
var dynamicWidth: CGFloat = 0
|
||||
for item in allItems {
|
||||
dynamicWidth += item.intrinsicWidth
|
||||
dynamicWidth += Segmentio.intrinsicWidth(for: item, style: style)
|
||||
}
|
||||
if item.collectionViewWidth < dynamicWidth {
|
||||
startX = 0
|
||||
|
|
@ -687,9 +702,9 @@ extension Segmentio.Points {
|
|||
var i = 0
|
||||
for item in allItems {
|
||||
if i < index {
|
||||
spaceBefore += item.intrinsicWidth
|
||||
spaceBefore += Segmentio.intrinsicWidth(for: item, style: style)
|
||||
} else if i > index {
|
||||
spaceAfter += item.intrinsicWidth
|
||||
spaceAfter += Segmentio.intrinsicWidth(for: item, style: style)
|
||||
}
|
||||
i += 1
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue